Skip to content

File tree

6 files changed

+128
-2
lines changed

6 files changed

+128
-2
lines changed

fs/netfs/Kconfig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,18 @@ config NETFS_SUPPORT
66
This option enables support for network filesystems, including
77
helpers for high-level buffered I/O, abstracting out read
88
segmentation, local caching and transparent huge page support.
9+
10+
config NETFS_STATS
11+
bool "Gather statistical information on local caching"
12+
depends on NETFS_SUPPORT && PROC_FS
13+
help
14+
This option causes statistical information to be gathered on local
15+
caching and exported through file:
16+
17+
/proc/fs/fscache/stats
18+
19+
The gathering of statistics adds a certain amount of overhead to
20+
execution as there are a quite a few stats gathered, and on a
21+
multi-CPU system these may be on cachelines that keep bouncing
22+
between CPUs. On the other hand, the stats are very useful for
23+
debugging purposes. Saying 'Y' here is recommended.

fs/netfs/Makefile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# SPDX-License-Identifier: GPL-2.0
22

3-
netfs-y := \
4-
read_helper.o
3+
netfs-y := read_helper.o stats.o
54

65
obj-$(CONFIG_NETFS_SUPPORT) := netfs.o

fs/netfs/internal.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,42 @@
1616
*/
1717
extern unsigned int netfs_debug;
1818

19+
/*
20+
* stats.c
21+
*/
22+
#ifdef CONFIG_NETFS_STATS
23+
extern atomic_t netfs_n_rh_readahead;
24+
extern atomic_t netfs_n_rh_readpage;
25+
extern atomic_t netfs_n_rh_rreq;
26+
extern atomic_t netfs_n_rh_sreq;
27+
extern atomic_t netfs_n_rh_download;
28+
extern atomic_t netfs_n_rh_download_done;
29+
extern atomic_t netfs_n_rh_download_failed;
30+
extern atomic_t netfs_n_rh_download_instead;
31+
extern atomic_t netfs_n_rh_read;
32+
extern atomic_t netfs_n_rh_read_done;
33+
extern atomic_t netfs_n_rh_read_failed;
34+
extern atomic_t netfs_n_rh_zero;
35+
extern atomic_t netfs_n_rh_short_read;
36+
extern atomic_t netfs_n_rh_write;
37+
extern atomic_t netfs_n_rh_write_done;
38+
extern atomic_t netfs_n_rh_write_failed;
39+
40+
41+
static inline void netfs_stat(atomic_t *stat)
42+
{
43+
atomic_inc(stat);
44+
}
45+
46+
static inline void netfs_stat_d(atomic_t *stat)
47+
{
48+
atomic_dec(stat);
49+
}
50+
51+
#else
1952
#define netfs_stat(x) do {} while(0)
2053
#define netfs_stat_d(x) do {} while(0)
54+
#endif
2155

2256
/*****************************************************************************/
2357
/*

fs/netfs/read_helper.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ static struct netfs_read_request *netfs_alloc_read_request(
5656
refcount_set(&rreq->usage, 1);
5757
__set_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags);
5858
ops->init_rreq(rreq, file);
59+
netfs_stat(&netfs_n_rh_rreq);
5960
}
6061

6162
return rreq;
@@ -88,6 +89,7 @@ static void netfs_free_read_request(struct work_struct *work)
8889
rreq->netfs_ops->cleanup(rreq->mapping, rreq->netfs_priv);
8990
trace_netfs_rreq(rreq, netfs_rreq_trace_free);
9091
kfree(rreq);
92+
netfs_stat_d(&netfs_n_rh_rreq);
9193
}
9294

9395
static void netfs_put_read_request(struct netfs_read_request *rreq, bool was_async)
@@ -117,6 +119,7 @@ static struct netfs_read_subrequest *netfs_alloc_subrequest(
117119
refcount_set(&subreq->usage, 2);
118120
subreq->rreq = rreq;
119121
netfs_get_read_request(rreq);
122+
netfs_stat(&netfs_n_rh_sreq);
120123
}
121124

122125
return subreq;
@@ -134,6 +137,7 @@ static void __netfs_put_subrequest(struct netfs_read_subrequest *subreq,
134137

135138
trace_netfs_sreq(subreq, netfs_sreq_trace_free);
136139
kfree(subreq);
140+
netfs_stat_d(&netfs_n_rh_sreq);
137141
netfs_put_read_request(rreq, was_async);
138142
}
139143

@@ -156,6 +160,7 @@ static void netfs_clear_unread(struct netfs_read_subrequest *subreq)
156160
static void netfs_fill_with_zeroes(struct netfs_read_request *rreq,
157161
struct netfs_read_subrequest *subreq)
158162
{
163+
netfs_stat(&netfs_n_rh_zero);
159164
__set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags);
160165
netfs_subreq_terminated(subreq, 0, false);
161166
}
@@ -179,6 +184,7 @@ static void netfs_fill_with_zeroes(struct netfs_read_request *rreq,
179184
static void netfs_read_from_server(struct netfs_read_request *rreq,
180185
struct netfs_read_subrequest *subreq)
181186
{
187+
netfs_stat(&netfs_n_rh_download);
182188
rreq->netfs_ops->issue_op(subreq);
183189
}
184190

@@ -288,6 +294,7 @@ static void netfs_rreq_short_read(struct netfs_read_request *rreq,
288294
__clear_bit(NETFS_SREQ_SHORT_READ, &subreq->flags);
289295
__set_bit(NETFS_SREQ_SEEK_DATA_READ, &subreq->flags);
290296

297+
netfs_stat(&netfs_n_rh_short_read);
291298
trace_netfs_sreq(subreq, netfs_sreq_trace_resubmit_short);
292299

293300
netfs_get_read_subrequest(subreq);
@@ -319,6 +326,7 @@ static bool netfs_rreq_perform_resubmissions(struct netfs_read_request *rreq)
319326
break;
320327
subreq->source = NETFS_DOWNLOAD_FROM_SERVER;
321328
subreq->error = 0;
329+
netfs_stat(&netfs_n_rh_download_instead);
322330
trace_netfs_sreq(subreq, netfs_sreq_trace_download_instead);
323331
netfs_get_read_subrequest(subreq);
324332
atomic_inc(&rreq->nr_rd_ops);
@@ -414,6 +422,17 @@ void netfs_subreq_terminated(struct netfs_read_subrequest *subreq,
414422
subreq->debug_index, subreq->start, subreq->flags,
415423
transferred_or_error);
416424

425+
switch (subreq->source) {
426+
case NETFS_READ_FROM_CACHE:
427+
netfs_stat(&netfs_n_rh_read_done);
428+
break;
429+
case NETFS_DOWNLOAD_FROM_SERVER:
430+
netfs_stat(&netfs_n_rh_download_done);
431+
break;
432+
default:
433+
break;
434+
}
435+
417436
if (IS_ERR_VALUE(transferred_or_error)) {
418437
subreq->error = transferred_or_error;
419438
goto failed;
@@ -470,8 +489,10 @@ void netfs_subreq_terminated(struct netfs_read_subrequest *subreq,
470489

471490
failed:
472491
if (subreq->source == NETFS_READ_FROM_CACHE) {
492+
netfs_stat(&netfs_n_rh_read_failed);
473493
set_bit(NETFS_RREQ_INCOMPLETE_IO, &rreq->flags);
474494
} else {
495+
netfs_stat(&netfs_n_rh_download_failed);
475496
set_bit(NETFS_RREQ_FAILED, &rreq->flags);
476497
rreq->error = subreq->error;
477498
}
@@ -653,6 +674,7 @@ void netfs_readahead(struct readahead_control *ractl,
653674
rreq->start = readahead_pos(ractl);
654675
rreq->len = readahead_length(ractl);
655676

677+
netfs_stat(&netfs_n_rh_readahead);
656678
trace_netfs_read(rreq, readahead_pos(ractl), readahead_length(ractl),
657679
netfs_read_trace_readahead);
658680

@@ -722,6 +744,7 @@ int netfs_readpage(struct file *file,
722744
rreq->start = page_index(page) * PAGE_SIZE;
723745
rreq->len = thp_size(page);
724746

747+
netfs_stat(&netfs_n_rh_readpage);
725748
trace_netfs_read(rreq, rreq->start, rreq->len, netfs_read_trace_readpage);
726749

727750
netfs_get_read_request(rreq);

fs/netfs/stats.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
/* Netfs support statistics
3+
*
4+
* Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
5+
* Written by David Howells ([email protected])
6+
*/
7+
8+
#include <linux/export.h>
9+
#include <linux/seq_file.h>
10+
#include <linux/netfs.h>
11+
#include "internal.h"
12+
13+
atomic_t netfs_n_rh_readahead;
14+
atomic_t netfs_n_rh_readpage;
15+
atomic_t netfs_n_rh_rreq;
16+
atomic_t netfs_n_rh_sreq;
17+
atomic_t netfs_n_rh_download;
18+
atomic_t netfs_n_rh_download_done;
19+
atomic_t netfs_n_rh_download_failed;
20+
atomic_t netfs_n_rh_download_instead;
21+
atomic_t netfs_n_rh_read;
22+
atomic_t netfs_n_rh_read_done;
23+
atomic_t netfs_n_rh_read_failed;
24+
atomic_t netfs_n_rh_zero;
25+
atomic_t netfs_n_rh_short_read;
26+
atomic_t netfs_n_rh_write;
27+
atomic_t netfs_n_rh_write_done;
28+
atomic_t netfs_n_rh_write_failed;
29+
30+
void netfs_stats_show(struct seq_file *m)
31+
{
32+
seq_printf(m, "RdHelp : RA=%u RP=%u rr=%u sr=%u\n",
33+
atomic_read(&netfs_n_rh_readahead),
34+
atomic_read(&netfs_n_rh_readpage),
35+
atomic_read(&netfs_n_rh_rreq),
36+
atomic_read(&netfs_n_rh_sreq));
37+
seq_printf(m, "RdHelp : ZR=%u sh=%u\n",
38+
atomic_read(&netfs_n_rh_zero),
39+
atomic_read(&netfs_n_rh_short_read));
40+
seq_printf(m, "RdHelp : DL=%u ds=%u df=%u di=%u\n",
41+
atomic_read(&netfs_n_rh_download),
42+
atomic_read(&netfs_n_rh_download_done),
43+
atomic_read(&netfs_n_rh_download_failed),
44+
atomic_read(&netfs_n_rh_download_instead));
45+
seq_printf(m, "RdHelp : RD=%u rs=%u rf=%u\n",
46+
atomic_read(&netfs_n_rh_read),
47+
atomic_read(&netfs_n_rh_read_done),
48+
atomic_read(&netfs_n_rh_read_failed));
49+
seq_printf(m, "RdHelp : WR=%u ws=%u wf=%u\n",
50+
atomic_read(&netfs_n_rh_write),
51+
atomic_read(&netfs_n_rh_write_done),
52+
atomic_read(&netfs_n_rh_write_failed));
53+
}
54+
EXPORT_SYMBOL(netfs_stats_show);

include/linux/netfs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,5 +166,6 @@ extern int netfs_readpage(struct file *,
166166
void *);
167167

168168
extern void netfs_subreq_terminated(struct netfs_read_subrequest *, ssize_t, bool);
169+
extern void netfs_stats_show(struct seq_file *);
169170

170171
#endif /* _LINUX_NETFS_H */

0 commit comments

Comments
 (0)