diff options
author | David Howells <dhowells@redhat.com> | 2009-04-03 11:42:37 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2009-04-03 11:42:37 -0400 |
commit | 7394daa8c61dfda4baa687f133748fa0b599b017 (patch) | |
tree | 32d2c55ed60596918ec62ce6ecca186337bf4660 /fs | |
parent | 06b3db1b9bccdc8c2c743122a89745279e5ecc46 (diff) |
FS-Cache: Add use of /proc and presentation of statistics
Make FS-Cache create its /proc interface and present various statistical
information through it. Also provide the functions for updating this
information.
These features are enabled by:
CONFIG_FSCACHE_PROC
CONFIG_FSCACHE_STATS
CONFIG_FSCACHE_HISTOGRAM
The /proc directory for FS-Cache is also exported so that caching modules can
add their own statistics there too.
The FS-Cache module is loadable at this point, and the statistics files can be
examined by userspace:
cat /proc/fs/fscache/stats
cat /proc/fs/fscache/histogram
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Steve Dickson <steved@redhat.com>
Acked-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Acked-by: Al Viro <viro@zeniv.linux.org.uk>
Tested-by: Daire Byrne <Daire.Byrne@framestore.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/fscache/Kconfig | 34 | ||||
-rw-r--r-- | fs/fscache/Makefile | 4 | ||||
-rw-r--r-- | fs/fscache/histogram.c | 109 | ||||
-rw-r--r-- | fs/fscache/internal.h | 127 | ||||
-rw-r--r-- | fs/fscache/main.c | 7 | ||||
-rw-r--r-- | fs/fscache/proc.c | 68 | ||||
-rw-r--r-- | fs/fscache/stats.c | 212 |
7 files changed, 561 insertions, 0 deletions
diff --git a/fs/fscache/Kconfig b/fs/fscache/Kconfig index 7c7bccd5eee4..9bbb8ce7bea0 100644 --- a/fs/fscache/Kconfig +++ b/fs/fscache/Kconfig | |||
@@ -11,6 +11,40 @@ config FSCACHE | |||
11 | 11 | ||
12 | See Documentation/filesystems/caching/fscache.txt for more information. | 12 | See Documentation/filesystems/caching/fscache.txt for more information. |
13 | 13 | ||
14 | config FSCACHE_STATS | ||
15 | bool "Gather statistical information on local caching" | ||
16 | depends on FSCACHE && PROC_FS | ||
17 | help | ||
18 | This option causes statistical information to be gathered on local | ||
19 | caching and exported through file: | ||
20 | |||
21 | /proc/fs/fscache/stats | ||
22 | |||
23 | The gathering of statistics adds a certain amount of overhead to | ||
24 | execution as there are a quite a few stats gathered, and on a | ||
25 | multi-CPU system these may be on cachelines that keep bouncing | ||
26 | between CPUs. On the other hand, the stats are very useful for | ||
27 | debugging purposes. Saying 'Y' here is recommended. | ||
28 | |||
29 | See Documentation/filesystems/caching/fscache.txt for more information. | ||
30 | |||
31 | config FSCACHE_HISTOGRAM | ||
32 | bool "Gather latency information on local caching" | ||
33 | depends on FSCACHE && PROC_FS | ||
34 | help | ||
35 | This option causes latency information to be gathered on local | ||
36 | caching and exported through file: | ||
37 | |||
38 | /proc/fs/fscache/histogram | ||
39 | |||
40 | The generation of this histogram adds a certain amount of overhead to | ||
41 | execution as there are a number of points at which data is gathered, | ||
42 | and on a multi-CPU system these may be on cachelines that keep | ||
43 | bouncing between CPUs. On the other hand, the histogram may be | ||
44 | useful for debugging purposes. Saying 'N' here is recommended. | ||
45 | |||
46 | See Documentation/filesystems/caching/fscache.txt for more information. | ||
47 | |||
14 | config FSCACHE_DEBUG | 48 | config FSCACHE_DEBUG |
15 | bool "Debug FS-Cache" | 49 | bool "Debug FS-Cache" |
16 | depends on FSCACHE | 50 | depends on FSCACHE |
diff --git a/fs/fscache/Makefile b/fs/fscache/Makefile index f8038b83e0ef..1384823a160c 100644 --- a/fs/fscache/Makefile +++ b/fs/fscache/Makefile | |||
@@ -5,4 +5,8 @@ | |||
5 | fscache-y := \ | 5 | fscache-y := \ |
6 | main.o | 6 | main.o |
7 | 7 | ||
8 | fscache-$(CONFIG_PROC_FS) += proc.o | ||
9 | fscache-$(CONFIG_FSCACHE_STATS) += stats.o | ||
10 | fscache-$(CONFIG_FSCACHE_HISTOGRAM) += histogram.o | ||
11 | |||
8 | obj-$(CONFIG_FSCACHE) := fscache.o | 12 | obj-$(CONFIG_FSCACHE) := fscache.o |
diff --git a/fs/fscache/histogram.c b/fs/fscache/histogram.c new file mode 100644 index 000000000000..bad496748a59 --- /dev/null +++ b/fs/fscache/histogram.c | |||
@@ -0,0 +1,109 @@ | |||
1 | /* FS-Cache latency histogram | ||
2 | * | ||
3 | * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #define FSCACHE_DEBUG_LEVEL THREAD | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/proc_fs.h> | ||
15 | #include <linux/seq_file.h> | ||
16 | #include "internal.h" | ||
17 | |||
18 | atomic_t fscache_obj_instantiate_histogram[HZ]; | ||
19 | atomic_t fscache_objs_histogram[HZ]; | ||
20 | atomic_t fscache_ops_histogram[HZ]; | ||
21 | atomic_t fscache_retrieval_delay_histogram[HZ]; | ||
22 | atomic_t fscache_retrieval_histogram[HZ]; | ||
23 | |||
24 | /* | ||
25 | * display the time-taken histogram | ||
26 | */ | ||
27 | static int fscache_histogram_show(struct seq_file *m, void *v) | ||
28 | { | ||
29 | unsigned long index; | ||
30 | unsigned n[5], t; | ||
31 | |||
32 | switch ((unsigned long) v) { | ||
33 | case 1: | ||
34 | seq_puts(m, "JIFS SECS OBJ INST OP RUNS OBJ RUNS " | ||
35 | " RETRV DLY RETRIEVLS\n"); | ||
36 | return 0; | ||
37 | case 2: | ||
38 | seq_puts(m, "===== ===== ========= ========= =========" | ||
39 | " ========= =========\n"); | ||
40 | return 0; | ||
41 | default: | ||
42 | index = (unsigned long) v - 3; | ||
43 | n[0] = atomic_read(&fscache_obj_instantiate_histogram[index]); | ||
44 | n[1] = atomic_read(&fscache_ops_histogram[index]); | ||
45 | n[2] = atomic_read(&fscache_objs_histogram[index]); | ||
46 | n[3] = atomic_read(&fscache_retrieval_delay_histogram[index]); | ||
47 | n[4] = atomic_read(&fscache_retrieval_histogram[index]); | ||
48 | if (!(n[0] | n[1] | n[2] | n[3] | n[4])) | ||
49 | return 0; | ||
50 | |||
51 | t = (index * 1000) / HZ; | ||
52 | |||
53 | seq_printf(m, "%4lu 0.%03u %9u %9u %9u %9u %9u\n", | ||
54 | index, t, n[0], n[1], n[2], n[3], n[4]); | ||
55 | return 0; | ||
56 | } | ||
57 | } | ||
58 | |||
59 | /* | ||
60 | * set up the iterator to start reading from the first line | ||
61 | */ | ||
62 | static void *fscache_histogram_start(struct seq_file *m, loff_t *_pos) | ||
63 | { | ||
64 | if ((unsigned long long)*_pos >= HZ + 2) | ||
65 | return NULL; | ||
66 | if (*_pos == 0) | ||
67 | *_pos = 1; | ||
68 | return (void *)(unsigned long) *_pos; | ||
69 | } | ||
70 | |||
71 | /* | ||
72 | * move to the next line | ||
73 | */ | ||
74 | static void *fscache_histogram_next(struct seq_file *m, void *v, loff_t *pos) | ||
75 | { | ||
76 | (*pos)++; | ||
77 | return (unsigned long long)*pos > HZ + 2 ? | ||
78 | NULL : (void *)(unsigned long) *pos; | ||
79 | } | ||
80 | |||
81 | /* | ||
82 | * clean up after reading | ||
83 | */ | ||
84 | static void fscache_histogram_stop(struct seq_file *m, void *v) | ||
85 | { | ||
86 | } | ||
87 | |||
88 | static const struct seq_operations fscache_histogram_ops = { | ||
89 | .start = fscache_histogram_start, | ||
90 | .stop = fscache_histogram_stop, | ||
91 | .next = fscache_histogram_next, | ||
92 | .show = fscache_histogram_show, | ||
93 | }; | ||
94 | |||
95 | /* | ||
96 | * open "/proc/fs/fscache/histogram" to provide latency data | ||
97 | */ | ||
98 | static int fscache_histogram_open(struct inode *inode, struct file *file) | ||
99 | { | ||
100 | return seq_open(file, &fscache_histogram_ops); | ||
101 | } | ||
102 | |||
103 | const struct file_operations fscache_histogram_fops = { | ||
104 | .owner = THIS_MODULE, | ||
105 | .open = fscache_histogram_open, | ||
106 | .read = seq_read, | ||
107 | .llseek = seq_lseek, | ||
108 | .release = seq_release, | ||
109 | }; | ||
diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h index 95dc92da7152..16f9f1f46e4d 100644 --- a/fs/fscache/internal.h +++ b/fs/fscache/internal.h | |||
@@ -28,6 +28,30 @@ | |||
28 | #define FSCACHE_MAX_THREADS 32 | 28 | #define FSCACHE_MAX_THREADS 32 |
29 | 29 | ||
30 | /* | 30 | /* |
31 | * fsc-histogram.c | ||
32 | */ | ||
33 | #ifdef CONFIG_FSCACHE_HISTOGRAM | ||
34 | extern atomic_t fscache_obj_instantiate_histogram[HZ]; | ||
35 | extern atomic_t fscache_objs_histogram[HZ]; | ||
36 | extern atomic_t fscache_ops_histogram[HZ]; | ||
37 | extern atomic_t fscache_retrieval_delay_histogram[HZ]; | ||
38 | extern atomic_t fscache_retrieval_histogram[HZ]; | ||
39 | |||
40 | static inline void fscache_hist(atomic_t histogram[], unsigned long start_jif) | ||
41 | { | ||
42 | unsigned long jif = jiffies - start_jif; | ||
43 | if (jif >= HZ) | ||
44 | jif = HZ - 1; | ||
45 | atomic_inc(&histogram[jif]); | ||
46 | } | ||
47 | |||
48 | extern const struct file_operations fscache_histogram_fops; | ||
49 | |||
50 | #else | ||
51 | #define fscache_hist(hist, start_jif) do {} while (0) | ||
52 | #endif | ||
53 | |||
54 | /* | ||
31 | * fsc-main.c | 55 | * fsc-main.c |
32 | */ | 56 | */ |
33 | extern unsigned fscache_defer_lookup; | 57 | extern unsigned fscache_defer_lookup; |
@@ -35,6 +59,109 @@ extern unsigned fscache_defer_create; | |||
35 | extern unsigned fscache_debug; | 59 | extern unsigned fscache_debug; |
36 | extern struct kobject *fscache_root; | 60 | extern struct kobject *fscache_root; |
37 | 61 | ||
62 | /* | ||
63 | * fsc-proc.c | ||
64 | */ | ||
65 | #ifdef CONFIG_PROC_FS | ||
66 | extern int __init fscache_proc_init(void); | ||
67 | extern void fscache_proc_cleanup(void); | ||
68 | #else | ||
69 | #define fscache_proc_init() (0) | ||
70 | #define fscache_proc_cleanup() do {} while (0) | ||
71 | #endif | ||
72 | |||
73 | /* | ||
74 | * fsc-stats.c | ||
75 | */ | ||
76 | #ifdef CONFIG_FSCACHE_STATS | ||
77 | extern atomic_t fscache_n_ops_processed[FSCACHE_MAX_THREADS]; | ||
78 | extern atomic_t fscache_n_objs_processed[FSCACHE_MAX_THREADS]; | ||
79 | |||
80 | extern atomic_t fscache_n_op_pend; | ||
81 | extern atomic_t fscache_n_op_run; | ||
82 | extern atomic_t fscache_n_op_enqueue; | ||
83 | extern atomic_t fscache_n_op_deferred_release; | ||
84 | extern atomic_t fscache_n_op_release; | ||
85 | extern atomic_t fscache_n_op_gc; | ||
86 | |||
87 | extern atomic_t fscache_n_attr_changed; | ||
88 | extern atomic_t fscache_n_attr_changed_ok; | ||
89 | extern atomic_t fscache_n_attr_changed_nobufs; | ||
90 | extern atomic_t fscache_n_attr_changed_nomem; | ||
91 | extern atomic_t fscache_n_attr_changed_calls; | ||
92 | |||
93 | extern atomic_t fscache_n_allocs; | ||
94 | extern atomic_t fscache_n_allocs_ok; | ||
95 | extern atomic_t fscache_n_allocs_wait; | ||
96 | extern atomic_t fscache_n_allocs_nobufs; | ||
97 | extern atomic_t fscache_n_alloc_ops; | ||
98 | extern atomic_t fscache_n_alloc_op_waits; | ||
99 | |||
100 | extern atomic_t fscache_n_retrievals; | ||
101 | extern atomic_t fscache_n_retrievals_ok; | ||
102 | extern atomic_t fscache_n_retrievals_wait; | ||
103 | extern atomic_t fscache_n_retrievals_nodata; | ||
104 | extern atomic_t fscache_n_retrievals_nobufs; | ||
105 | extern atomic_t fscache_n_retrievals_intr; | ||
106 | extern atomic_t fscache_n_retrievals_nomem; | ||
107 | extern atomic_t fscache_n_retrieval_ops; | ||
108 | extern atomic_t fscache_n_retrieval_op_waits; | ||
109 | |||
110 | extern atomic_t fscache_n_stores; | ||
111 | extern atomic_t fscache_n_stores_ok; | ||
112 | extern atomic_t fscache_n_stores_again; | ||
113 | extern atomic_t fscache_n_stores_nobufs; | ||
114 | extern atomic_t fscache_n_stores_oom; | ||
115 | extern atomic_t fscache_n_store_ops; | ||
116 | extern atomic_t fscache_n_store_calls; | ||
117 | |||
118 | extern atomic_t fscache_n_marks; | ||
119 | extern atomic_t fscache_n_uncaches; | ||
120 | |||
121 | extern atomic_t fscache_n_acquires; | ||
122 | extern atomic_t fscache_n_acquires_null; | ||
123 | extern atomic_t fscache_n_acquires_no_cache; | ||
124 | extern atomic_t fscache_n_acquires_ok; | ||
125 | extern atomic_t fscache_n_acquires_nobufs; | ||
126 | extern atomic_t fscache_n_acquires_oom; | ||
127 | |||
128 | extern atomic_t fscache_n_updates; | ||
129 | extern atomic_t fscache_n_updates_null; | ||
130 | extern atomic_t fscache_n_updates_run; | ||
131 | |||
132 | extern atomic_t fscache_n_relinquishes; | ||
133 | extern atomic_t fscache_n_relinquishes_null; | ||
134 | extern atomic_t fscache_n_relinquishes_waitcrt; | ||
135 | |||
136 | extern atomic_t fscache_n_cookie_index; | ||
137 | extern atomic_t fscache_n_cookie_data; | ||
138 | extern atomic_t fscache_n_cookie_special; | ||
139 | |||
140 | extern atomic_t fscache_n_object_alloc; | ||
141 | extern atomic_t fscache_n_object_no_alloc; | ||
142 | extern atomic_t fscache_n_object_lookups; | ||
143 | extern atomic_t fscache_n_object_lookups_negative; | ||
144 | extern atomic_t fscache_n_object_lookups_positive; | ||
145 | extern atomic_t fscache_n_object_created; | ||
146 | extern atomic_t fscache_n_object_avail; | ||
147 | extern atomic_t fscache_n_object_dead; | ||
148 | |||
149 | extern atomic_t fscache_n_checkaux_none; | ||
150 | extern atomic_t fscache_n_checkaux_okay; | ||
151 | extern atomic_t fscache_n_checkaux_update; | ||
152 | extern atomic_t fscache_n_checkaux_obsolete; | ||
153 | |||
154 | static inline void fscache_stat(atomic_t *stat) | ||
155 | { | ||
156 | atomic_inc(stat); | ||
157 | } | ||
158 | |||
159 | extern const struct file_operations fscache_stats_fops; | ||
160 | #else | ||
161 | |||
162 | #define fscache_stat(stat) do {} while (0) | ||
163 | #endif | ||
164 | |||
38 | /*****************************************************************************/ | 165 | /*****************************************************************************/ |
39 | /* | 166 | /* |
40 | * debug tracing | 167 | * debug tracing |
diff --git a/fs/fscache/main.c b/fs/fscache/main.c index 76f7c69079c0..7c734b7fb18e 100644 --- a/fs/fscache/main.c +++ b/fs/fscache/main.c | |||
@@ -52,9 +52,15 @@ static int __init fscache_init(void) | |||
52 | if (ret < 0) | 52 | if (ret < 0) |
53 | goto error_slow_work; | 53 | goto error_slow_work; |
54 | 54 | ||
55 | ret = fscache_proc_init(); | ||
56 | if (ret < 0) | ||
57 | goto error_proc; | ||
58 | |||
55 | printk(KERN_NOTICE "FS-Cache: Loaded\n"); | 59 | printk(KERN_NOTICE "FS-Cache: Loaded\n"); |
56 | return 0; | 60 | return 0; |
57 | 61 | ||
62 | error_proc: | ||
63 | slow_work_unregister_user(); | ||
58 | error_slow_work: | 64 | error_slow_work: |
59 | return ret; | 65 | return ret; |
60 | } | 66 | } |
@@ -68,6 +74,7 @@ static void __exit fscache_exit(void) | |||
68 | { | 74 | { |
69 | _enter(""); | 75 | _enter(""); |
70 | 76 | ||
77 | fscache_proc_cleanup(); | ||
71 | slow_work_unregister_user(); | 78 | slow_work_unregister_user(); |
72 | printk(KERN_NOTICE "FS-Cache: Unloaded\n"); | 79 | printk(KERN_NOTICE "FS-Cache: Unloaded\n"); |
73 | } | 80 | } |
diff --git a/fs/fscache/proc.c b/fs/fscache/proc.c new file mode 100644 index 000000000000..beeab44bc31a --- /dev/null +++ b/fs/fscache/proc.c | |||
@@ -0,0 +1,68 @@ | |||
1 | /* FS-Cache statistics viewing interface | ||
2 | * | ||
3 | * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #define FSCACHE_DEBUG_LEVEL OPERATION | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/proc_fs.h> | ||
15 | #include <linux/seq_file.h> | ||
16 | #include "internal.h" | ||
17 | |||
18 | /* | ||
19 | * initialise the /proc/fs/fscache/ directory | ||
20 | */ | ||
21 | int __init fscache_proc_init(void) | ||
22 | { | ||
23 | _enter(""); | ||
24 | |||
25 | if (!proc_mkdir("fs/fscache", NULL)) | ||
26 | goto error_dir; | ||
27 | |||
28 | #ifdef CONFIG_FSCACHE_STATS | ||
29 | if (!proc_create("fs/fscache/stats", S_IFREG | 0444, NULL, | ||
30 | &fscache_stats_fops)) | ||
31 | goto error_stats; | ||
32 | #endif | ||
33 | |||
34 | #ifdef CONFIG_FSCACHE_HISTOGRAM | ||
35 | if (!proc_create("fs/fscache/histogram", S_IFREG | 0444, NULL, | ||
36 | &fscache_histogram_fops)) | ||
37 | goto error_histogram; | ||
38 | #endif | ||
39 | |||
40 | _leave(" = 0"); | ||
41 | return 0; | ||
42 | |||
43 | #ifdef CONFIG_FSCACHE_HISTOGRAM | ||
44 | error_histogram: | ||
45 | #endif | ||
46 | #ifdef CONFIG_FSCACHE_STATS | ||
47 | remove_proc_entry("fs/fscache/stats", NULL); | ||
48 | error_stats: | ||
49 | #endif | ||
50 | remove_proc_entry("fs/fscache", NULL); | ||
51 | error_dir: | ||
52 | _leave(" = -ENOMEM"); | ||
53 | return -ENOMEM; | ||
54 | } | ||
55 | |||
56 | /* | ||
57 | * clean up the /proc/fs/fscache/ directory | ||
58 | */ | ||
59 | void fscache_proc_cleanup(void) | ||
60 | { | ||
61 | #ifdef CONFIG_FSCACHE_HISTOGRAM | ||
62 | remove_proc_entry("fs/fscache/histogram", NULL); | ||
63 | #endif | ||
64 | #ifdef CONFIG_FSCACHE_STATS | ||
65 | remove_proc_entry("fs/fscache/stats", NULL); | ||
66 | #endif | ||
67 | remove_proc_entry("fs/fscache", NULL); | ||
68 | } | ||
diff --git a/fs/fscache/stats.c b/fs/fscache/stats.c new file mode 100644 index 000000000000..65deb99e756b --- /dev/null +++ b/fs/fscache/stats.c | |||
@@ -0,0 +1,212 @@ | |||
1 | /* FS-Cache statistics | ||
2 | * | ||
3 | * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #define FSCACHE_DEBUG_LEVEL THREAD | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/proc_fs.h> | ||
15 | #include <linux/seq_file.h> | ||
16 | #include "internal.h" | ||
17 | |||
18 | /* | ||
19 | * operation counters | ||
20 | */ | ||
21 | atomic_t fscache_n_op_pend; | ||
22 | atomic_t fscache_n_op_run; | ||
23 | atomic_t fscache_n_op_enqueue; | ||
24 | atomic_t fscache_n_op_requeue; | ||
25 | atomic_t fscache_n_op_deferred_release; | ||
26 | atomic_t fscache_n_op_release; | ||
27 | atomic_t fscache_n_op_gc; | ||
28 | |||
29 | atomic_t fscache_n_attr_changed; | ||
30 | atomic_t fscache_n_attr_changed_ok; | ||
31 | atomic_t fscache_n_attr_changed_nobufs; | ||
32 | atomic_t fscache_n_attr_changed_nomem; | ||
33 | atomic_t fscache_n_attr_changed_calls; | ||
34 | |||
35 | atomic_t fscache_n_allocs; | ||
36 | atomic_t fscache_n_allocs_ok; | ||
37 | atomic_t fscache_n_allocs_wait; | ||
38 | atomic_t fscache_n_allocs_nobufs; | ||
39 | atomic_t fscache_n_alloc_ops; | ||
40 | atomic_t fscache_n_alloc_op_waits; | ||
41 | |||
42 | atomic_t fscache_n_retrievals; | ||
43 | atomic_t fscache_n_retrievals_ok; | ||
44 | atomic_t fscache_n_retrievals_wait; | ||
45 | atomic_t fscache_n_retrievals_nodata; | ||
46 | atomic_t fscache_n_retrievals_nobufs; | ||
47 | atomic_t fscache_n_retrievals_intr; | ||
48 | atomic_t fscache_n_retrievals_nomem; | ||
49 | atomic_t fscache_n_retrieval_ops; | ||
50 | atomic_t fscache_n_retrieval_op_waits; | ||
51 | |||
52 | atomic_t fscache_n_stores; | ||
53 | atomic_t fscache_n_stores_ok; | ||
54 | atomic_t fscache_n_stores_again; | ||
55 | atomic_t fscache_n_stores_nobufs; | ||
56 | atomic_t fscache_n_stores_oom; | ||
57 | atomic_t fscache_n_store_ops; | ||
58 | atomic_t fscache_n_store_calls; | ||
59 | |||
60 | atomic_t fscache_n_marks; | ||
61 | atomic_t fscache_n_uncaches; | ||
62 | |||
63 | atomic_t fscache_n_acquires; | ||
64 | atomic_t fscache_n_acquires_null; | ||
65 | atomic_t fscache_n_acquires_no_cache; | ||
66 | atomic_t fscache_n_acquires_ok; | ||
67 | atomic_t fscache_n_acquires_nobufs; | ||
68 | atomic_t fscache_n_acquires_oom; | ||
69 | |||
70 | atomic_t fscache_n_updates; | ||
71 | atomic_t fscache_n_updates_null; | ||
72 | atomic_t fscache_n_updates_run; | ||
73 | |||
74 | atomic_t fscache_n_relinquishes; | ||
75 | atomic_t fscache_n_relinquishes_null; | ||
76 | atomic_t fscache_n_relinquishes_waitcrt; | ||
77 | |||
78 | atomic_t fscache_n_cookie_index; | ||
79 | atomic_t fscache_n_cookie_data; | ||
80 | atomic_t fscache_n_cookie_special; | ||
81 | |||
82 | atomic_t fscache_n_object_alloc; | ||
83 | atomic_t fscache_n_object_no_alloc; | ||
84 | atomic_t fscache_n_object_lookups; | ||
85 | atomic_t fscache_n_object_lookups_negative; | ||
86 | atomic_t fscache_n_object_lookups_positive; | ||
87 | atomic_t fscache_n_object_created; | ||
88 | atomic_t fscache_n_object_avail; | ||
89 | atomic_t fscache_n_object_dead; | ||
90 | |||
91 | atomic_t fscache_n_checkaux_none; | ||
92 | atomic_t fscache_n_checkaux_okay; | ||
93 | atomic_t fscache_n_checkaux_update; | ||
94 | atomic_t fscache_n_checkaux_obsolete; | ||
95 | |||
96 | /* | ||
97 | * display the general statistics | ||
98 | */ | ||
99 | static int fscache_stats_show(struct seq_file *m, void *v) | ||
100 | { | ||
101 | seq_puts(m, "FS-Cache statistics\n"); | ||
102 | |||
103 | seq_printf(m, "Cookies: idx=%u dat=%u spc=%u\n", | ||
104 | atomic_read(&fscache_n_cookie_index), | ||
105 | atomic_read(&fscache_n_cookie_data), | ||
106 | atomic_read(&fscache_n_cookie_special)); | ||
107 | |||
108 | seq_printf(m, "Objects: alc=%u nal=%u avl=%u ded=%u\n", | ||
109 | atomic_read(&fscache_n_object_alloc), | ||
110 | atomic_read(&fscache_n_object_no_alloc), | ||
111 | atomic_read(&fscache_n_object_avail), | ||
112 | atomic_read(&fscache_n_object_dead)); | ||
113 | seq_printf(m, "ChkAux : non=%u ok=%u upd=%u obs=%u\n", | ||
114 | atomic_read(&fscache_n_checkaux_none), | ||
115 | atomic_read(&fscache_n_checkaux_okay), | ||
116 | atomic_read(&fscache_n_checkaux_update), | ||
117 | atomic_read(&fscache_n_checkaux_obsolete)); | ||
118 | |||
119 | seq_printf(m, "Pages : mrk=%u unc=%u\n", | ||
120 | atomic_read(&fscache_n_marks), | ||
121 | atomic_read(&fscache_n_uncaches)); | ||
122 | |||
123 | seq_printf(m, "Acquire: n=%u nul=%u noc=%u ok=%u nbf=%u" | ||
124 | " oom=%u\n", | ||
125 | atomic_read(&fscache_n_acquires), | ||
126 | atomic_read(&fscache_n_acquires_null), | ||
127 | atomic_read(&fscache_n_acquires_no_cache), | ||
128 | atomic_read(&fscache_n_acquires_ok), | ||
129 | atomic_read(&fscache_n_acquires_nobufs), | ||
130 | atomic_read(&fscache_n_acquires_oom)); | ||
131 | |||
132 | seq_printf(m, "Lookups: n=%u neg=%u pos=%u crt=%u\n", | ||
133 | atomic_read(&fscache_n_object_lookups), | ||
134 | atomic_read(&fscache_n_object_lookups_negative), | ||
135 | atomic_read(&fscache_n_object_lookups_positive), | ||
136 | atomic_read(&fscache_n_object_created)); | ||
137 | |||
138 | seq_printf(m, "Updates: n=%u nul=%u run=%u\n", | ||
139 | atomic_read(&fscache_n_updates), | ||
140 | atomic_read(&fscache_n_updates_null), | ||
141 | atomic_read(&fscache_n_updates_run)); | ||
142 | |||
143 | seq_printf(m, "Relinqs: n=%u nul=%u wcr=%u\n", | ||
144 | atomic_read(&fscache_n_relinquishes), | ||
145 | atomic_read(&fscache_n_relinquishes_null), | ||
146 | atomic_read(&fscache_n_relinquishes_waitcrt)); | ||
147 | |||
148 | seq_printf(m, "AttrChg: n=%u ok=%u nbf=%u oom=%u run=%u\n", | ||
149 | atomic_read(&fscache_n_attr_changed), | ||
150 | atomic_read(&fscache_n_attr_changed_ok), | ||
151 | atomic_read(&fscache_n_attr_changed_nobufs), | ||
152 | atomic_read(&fscache_n_attr_changed_nomem), | ||
153 | atomic_read(&fscache_n_attr_changed_calls)); | ||
154 | |||
155 | seq_printf(m, "Allocs : n=%u ok=%u wt=%u nbf=%u\n", | ||
156 | atomic_read(&fscache_n_allocs), | ||
157 | atomic_read(&fscache_n_allocs_ok), | ||
158 | atomic_read(&fscache_n_allocs_wait), | ||
159 | atomic_read(&fscache_n_allocs_nobufs)); | ||
160 | seq_printf(m, "Allocs : ops=%u owt=%u\n", | ||
161 | atomic_read(&fscache_n_alloc_ops), | ||
162 | atomic_read(&fscache_n_alloc_op_waits)); | ||
163 | |||
164 | seq_printf(m, "Retrvls: n=%u ok=%u wt=%u nod=%u nbf=%u" | ||
165 | " int=%u oom=%u\n", | ||
166 | atomic_read(&fscache_n_retrievals), | ||
167 | atomic_read(&fscache_n_retrievals_ok), | ||
168 | atomic_read(&fscache_n_retrievals_wait), | ||
169 | atomic_read(&fscache_n_retrievals_nodata), | ||
170 | atomic_read(&fscache_n_retrievals_nobufs), | ||
171 | atomic_read(&fscache_n_retrievals_intr), | ||
172 | atomic_read(&fscache_n_retrievals_nomem)); | ||
173 | seq_printf(m, "Retrvls: ops=%u owt=%u\n", | ||
174 | atomic_read(&fscache_n_retrieval_ops), | ||
175 | atomic_read(&fscache_n_retrieval_op_waits)); | ||
176 | |||
177 | seq_printf(m, "Stores : n=%u ok=%u agn=%u nbf=%u oom=%u\n", | ||
178 | atomic_read(&fscache_n_stores), | ||
179 | atomic_read(&fscache_n_stores_ok), | ||
180 | atomic_read(&fscache_n_stores_again), | ||
181 | atomic_read(&fscache_n_stores_nobufs), | ||
182 | atomic_read(&fscache_n_stores_oom)); | ||
183 | seq_printf(m, "Stores : ops=%u run=%u\n", | ||
184 | atomic_read(&fscache_n_store_ops), | ||
185 | atomic_read(&fscache_n_store_calls)); | ||
186 | |||
187 | seq_printf(m, "Ops : pend=%u run=%u enq=%u\n", | ||
188 | atomic_read(&fscache_n_op_pend), | ||
189 | atomic_read(&fscache_n_op_run), | ||
190 | atomic_read(&fscache_n_op_enqueue)); | ||
191 | seq_printf(m, "Ops : dfr=%u rel=%u gc=%u\n", | ||
192 | atomic_read(&fscache_n_op_deferred_release), | ||
193 | atomic_read(&fscache_n_op_release), | ||
194 | atomic_read(&fscache_n_op_gc)); | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | /* | ||
199 | * open "/proc/fs/fscache/stats" allowing provision of a statistical summary | ||
200 | */ | ||
201 | static int fscache_stats_open(struct inode *inode, struct file *file) | ||
202 | { | ||
203 | return single_open(file, fscache_stats_show, NULL); | ||
204 | } | ||
205 | |||
206 | const struct file_operations fscache_stats_fops = { | ||
207 | .owner = THIS_MODULE, | ||
208 | .open = fscache_stats_open, | ||
209 | .read = seq_read, | ||
210 | .llseek = seq_lseek, | ||
211 | .release = seq_release, | ||
212 | }; | ||