diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2008-04-30 03:54:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-30 11:29:50 -0400 |
commit | 76f1418b485da2707531178e517bbb5cf06b3c76 (patch) | |
tree | 138a012d965ebc284163f42e0ff5786c6de1cda5 /mm/backing-dev.c | |
parent | a42dde04152750426cc620fd277e80fffae2f65a (diff) |
mm: bdi: move statistics to debugfs
Move BDI statistics to debugfs:
/sys/kernel/debug/bdi/<bdi>/stats
Use postcore_initcall() to initialize the sysfs class and debugfs,
because debugfs is initialized in core_initcall().
Update descriptions in ABI documentation.
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/backing-dev.c')
-rw-r--r-- | mm/backing-dev.c | 98 |
1 files changed, 78 insertions, 20 deletions
diff --git a/mm/backing-dev.c b/mm/backing-dev.c index 08361b6aad50..7c4f9e097095 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c | |||
@@ -10,6 +10,80 @@ | |||
10 | 10 | ||
11 | static struct class *bdi_class; | 11 | static struct class *bdi_class; |
12 | 12 | ||
13 | #ifdef CONFIG_DEBUG_FS | ||
14 | #include <linux/debugfs.h> | ||
15 | #include <linux/seq_file.h> | ||
16 | |||
17 | static struct dentry *bdi_debug_root; | ||
18 | |||
19 | static void bdi_debug_init(void) | ||
20 | { | ||
21 | bdi_debug_root = debugfs_create_dir("bdi", NULL); | ||
22 | } | ||
23 | |||
24 | static int bdi_debug_stats_show(struct seq_file *m, void *v) | ||
25 | { | ||
26 | struct backing_dev_info *bdi = m->private; | ||
27 | long background_thresh; | ||
28 | long dirty_thresh; | ||
29 | long bdi_thresh; | ||
30 | |||
31 | get_dirty_limits(&background_thresh, &dirty_thresh, &bdi_thresh, bdi); | ||
32 | |||
33 | #define K(x) ((x) << (PAGE_SHIFT - 10)) | ||
34 | seq_printf(m, | ||
35 | "BdiWriteback: %8lu kB\n" | ||
36 | "BdiReclaimable: %8lu kB\n" | ||
37 | "BdiDirtyThresh: %8lu kB\n" | ||
38 | "DirtyThresh: %8lu kB\n" | ||
39 | "BackgroundThresh: %8lu kB\n", | ||
40 | (unsigned long) K(bdi_stat(bdi, BDI_WRITEBACK)), | ||
41 | (unsigned long) K(bdi_stat(bdi, BDI_RECLAIMABLE)), | ||
42 | K(bdi_thresh), | ||
43 | K(dirty_thresh), | ||
44 | K(background_thresh)); | ||
45 | #undef K | ||
46 | |||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | static int bdi_debug_stats_open(struct inode *inode, struct file *file) | ||
51 | { | ||
52 | return single_open(file, bdi_debug_stats_show, inode->i_private); | ||
53 | } | ||
54 | |||
55 | static const struct file_operations bdi_debug_stats_fops = { | ||
56 | .open = bdi_debug_stats_open, | ||
57 | .read = seq_read, | ||
58 | .llseek = seq_lseek, | ||
59 | .release = single_release, | ||
60 | }; | ||
61 | |||
62 | static void bdi_debug_register(struct backing_dev_info *bdi, const char *name) | ||
63 | { | ||
64 | bdi->debug_dir = debugfs_create_dir(name, bdi_debug_root); | ||
65 | bdi->debug_stats = debugfs_create_file("stats", 0444, bdi->debug_dir, | ||
66 | bdi, &bdi_debug_stats_fops); | ||
67 | } | ||
68 | |||
69 | static void bdi_debug_unregister(struct backing_dev_info *bdi) | ||
70 | { | ||
71 | debugfs_remove(bdi->debug_stats); | ||
72 | debugfs_remove(bdi->debug_dir); | ||
73 | } | ||
74 | #else | ||
75 | static inline void bdi_debug_init(void) | ||
76 | { | ||
77 | } | ||
78 | static inline void bdi_debug_register(struct backing_dev_info *bdi, | ||
79 | const char *name) | ||
80 | { | ||
81 | } | ||
82 | static inline void bdi_debug_unregister(struct backing_dev_info *bdi) | ||
83 | { | ||
84 | } | ||
85 | #endif | ||
86 | |||
13 | static ssize_t read_ahead_kb_store(struct device *dev, | 87 | static ssize_t read_ahead_kb_store(struct device *dev, |
14 | struct device_attribute *attr, | 88 | struct device_attribute *attr, |
15 | const char *buf, size_t count) | 89 | const char *buf, size_t count) |
@@ -40,21 +114,6 @@ static ssize_t name##_show(struct device *dev, \ | |||
40 | 114 | ||
41 | BDI_SHOW(read_ahead_kb, K(bdi->ra_pages)) | 115 | BDI_SHOW(read_ahead_kb, K(bdi->ra_pages)) |
42 | 116 | ||
43 | BDI_SHOW(reclaimable_kb, K(bdi_stat(bdi, BDI_RECLAIMABLE))) | ||
44 | BDI_SHOW(writeback_kb, K(bdi_stat(bdi, BDI_WRITEBACK))) | ||
45 | |||
46 | static inline unsigned long get_dirty(struct backing_dev_info *bdi, int i) | ||
47 | { | ||
48 | unsigned long thresh[3]; | ||
49 | |||
50 | get_dirty_limits(&thresh[0], &thresh[1], &thresh[2], bdi); | ||
51 | |||
52 | return thresh[i]; | ||
53 | } | ||
54 | |||
55 | BDI_SHOW(dirty_kb, K(get_dirty(bdi, 1))) | ||
56 | BDI_SHOW(bdi_dirty_kb, K(get_dirty(bdi, 2))) | ||
57 | |||
58 | static ssize_t min_ratio_store(struct device *dev, | 117 | static ssize_t min_ratio_store(struct device *dev, |
59 | struct device_attribute *attr, const char *buf, size_t count) | 118 | struct device_attribute *attr, const char *buf, size_t count) |
60 | { | 119 | { |
@@ -95,10 +154,6 @@ BDI_SHOW(max_ratio, bdi->max_ratio) | |||
95 | 154 | ||
96 | static struct device_attribute bdi_dev_attrs[] = { | 155 | static struct device_attribute bdi_dev_attrs[] = { |
97 | __ATTR_RW(read_ahead_kb), | 156 | __ATTR_RW(read_ahead_kb), |
98 | __ATTR_RO(reclaimable_kb), | ||
99 | __ATTR_RO(writeback_kb), | ||
100 | __ATTR_RO(dirty_kb), | ||
101 | __ATTR_RO(bdi_dirty_kb), | ||
102 | __ATTR_RW(min_ratio), | 157 | __ATTR_RW(min_ratio), |
103 | __ATTR_RW(max_ratio), | 158 | __ATTR_RW(max_ratio), |
104 | __ATTR_NULL, | 159 | __ATTR_NULL, |
@@ -108,10 +163,11 @@ static __init int bdi_class_init(void) | |||
108 | { | 163 | { |
109 | bdi_class = class_create(THIS_MODULE, "bdi"); | 164 | bdi_class = class_create(THIS_MODULE, "bdi"); |
110 | bdi_class->dev_attrs = bdi_dev_attrs; | 165 | bdi_class->dev_attrs = bdi_dev_attrs; |
166 | bdi_debug_init(); | ||
111 | return 0; | 167 | return 0; |
112 | } | 168 | } |
113 | 169 | ||
114 | core_initcall(bdi_class_init); | 170 | postcore_initcall(bdi_class_init); |
115 | 171 | ||
116 | int bdi_register(struct backing_dev_info *bdi, struct device *parent, | 172 | int bdi_register(struct backing_dev_info *bdi, struct device *parent, |
117 | const char *fmt, ...) | 173 | const char *fmt, ...) |
@@ -136,6 +192,7 @@ int bdi_register(struct backing_dev_info *bdi, struct device *parent, | |||
136 | 192 | ||
137 | bdi->dev = dev; | 193 | bdi->dev = dev; |
138 | dev_set_drvdata(bdi->dev, bdi); | 194 | dev_set_drvdata(bdi->dev, bdi); |
195 | bdi_debug_register(bdi, name); | ||
139 | 196 | ||
140 | exit: | 197 | exit: |
141 | kfree(name); | 198 | kfree(name); |
@@ -152,6 +209,7 @@ EXPORT_SYMBOL(bdi_register_dev); | |||
152 | void bdi_unregister(struct backing_dev_info *bdi) | 209 | void bdi_unregister(struct backing_dev_info *bdi) |
153 | { | 210 | { |
154 | if (bdi->dev) { | 211 | if (bdi->dev) { |
212 | bdi_debug_unregister(bdi); | ||
155 | device_unregister(bdi->dev); | 213 | device_unregister(bdi->dev); |
156 | bdi->dev = NULL; | 214 | bdi->dev = NULL; |
157 | } | 215 | } |