aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/slab.c72
-rw-r--r--mm/slab.h8
-rw-r--r--mm/slab_common.c70
-rw-r--r--mm/slub.c51
4 files changed, 96 insertions, 105 deletions
diff --git a/mm/slab.c b/mm/slab.c
index 33d3363658df..a6e045c13b8d 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -4277,7 +4277,7 @@ out:
4277 4277
4278#ifdef CONFIG_SLABINFO 4278#ifdef CONFIG_SLABINFO
4279 4279
4280static void print_slabinfo_header(struct seq_file *m) 4280void print_slabinfo_header(struct seq_file *m)
4281{ 4281{
4282 /* 4282 /*
4283 * Output format version, so at least we can change it 4283 * Output format version, so at least we can change it
@@ -4300,28 +4300,7 @@ static void print_slabinfo_header(struct seq_file *m)
4300 seq_putc(m, '\n'); 4300 seq_putc(m, '\n');
4301} 4301}
4302 4302
4303static void *s_start(struct seq_file *m, loff_t *pos) 4303int slabinfo_show(struct seq_file *m, void *p)
4304{
4305 loff_t n = *pos;
4306
4307 mutex_lock(&slab_mutex);
4308 if (!n)
4309 print_slabinfo_header(m);
4310
4311 return seq_list_start(&slab_caches, *pos);
4312}
4313
4314static void *s_next(struct seq_file *m, void *p, loff_t *pos)
4315{
4316 return seq_list_next(p, &slab_caches, pos);
4317}
4318
4319static void s_stop(struct seq_file *m, void *p)
4320{
4321 mutex_unlock(&slab_mutex);
4322}
4323
4324static int s_show(struct seq_file *m, void *p)
4325{ 4304{
4326 struct kmem_cache *cachep = list_entry(p, struct kmem_cache, list); 4305 struct kmem_cache *cachep = list_entry(p, struct kmem_cache, list);
4327 struct slab *slabp; 4306 struct slab *slabp;
@@ -4418,27 +4397,6 @@ static int s_show(struct seq_file *m, void *p)
4418 return 0; 4397 return 0;
4419} 4398}
4420 4399
4421/*
4422 * slabinfo_op - iterator that generates /proc/slabinfo
4423 *
4424 * Output layout:
4425 * cache-name
4426 * num-active-objs
4427 * total-objs
4428 * object size
4429 * num-active-slabs
4430 * total-slabs
4431 * num-pages-per-slab
4432 * + further values on SMP and with statistics enabled
4433 */
4434
4435static const struct seq_operations slabinfo_op = {
4436 .start = s_start,
4437 .next = s_next,
4438 .stop = s_stop,
4439 .show = s_show,
4440};
4441
4442#define MAX_SLABINFO_WRITE 128 4400#define MAX_SLABINFO_WRITE 128
4443/** 4401/**
4444 * slabinfo_write - Tuning for the slab allocator 4402 * slabinfo_write - Tuning for the slab allocator
@@ -4447,7 +4405,7 @@ static const struct seq_operations slabinfo_op = {
4447 * @count: data length 4405 * @count: data length
4448 * @ppos: unused 4406 * @ppos: unused
4449 */ 4407 */
4450static ssize_t slabinfo_write(struct file *file, const char __user *buffer, 4408ssize_t slabinfo_write(struct file *file, const char __user *buffer,
4451 size_t count, loff_t *ppos) 4409 size_t count, loff_t *ppos)
4452{ 4410{
4453 char kbuf[MAX_SLABINFO_WRITE + 1], *tmp; 4411 char kbuf[MAX_SLABINFO_WRITE + 1], *tmp;
@@ -4490,19 +4448,6 @@ static ssize_t slabinfo_write(struct file *file, const char __user *buffer,
4490 return res; 4448 return res;
4491} 4449}
4492 4450
4493static int slabinfo_open(struct inode *inode, struct file *file)
4494{
4495 return seq_open(file, &slabinfo_op);
4496}
4497
4498static const struct file_operations proc_slabinfo_operations = {
4499 .open = slabinfo_open,
4500 .read = seq_read,
4501 .write = slabinfo_write,
4502 .llseek = seq_lseek,
4503 .release = seq_release,
4504};
4505
4506#ifdef CONFIG_DEBUG_SLAB_LEAK 4451#ifdef CONFIG_DEBUG_SLAB_LEAK
4507 4452
4508static void *leaks_start(struct seq_file *m, loff_t *pos) 4453static void *leaks_start(struct seq_file *m, loff_t *pos)
@@ -4631,6 +4576,16 @@ static int leaks_show(struct seq_file *m, void *p)
4631 return 0; 4576 return 0;
4632} 4577}
4633 4578
4579static void *s_next(struct seq_file *m, void *p, loff_t *pos)
4580{
4581 return seq_list_next(p, &slab_caches, pos);
4582}
4583
4584static void s_stop(struct seq_file *m, void *p)
4585{
4586 mutex_unlock(&slab_mutex);
4587}
4588
4634static const struct seq_operations slabstats_op = { 4589static const struct seq_operations slabstats_op = {
4635 .start = leaks_start, 4590 .start = leaks_start,
4636 .next = s_next, 4591 .next = s_next,
@@ -4665,7 +4620,6 @@ static const struct file_operations proc_slabstats_operations = {
4665 4620
4666static int __init slab_proc_init(void) 4621static int __init slab_proc_init(void)
4667{ 4622{
4668 proc_create("slabinfo",S_IWUSR|S_IRUSR,NULL,&proc_slabinfo_operations);
4669#ifdef CONFIG_DEBUG_SLAB_LEAK 4623#ifdef CONFIG_DEBUG_SLAB_LEAK
4670 proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations); 4624 proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations);
4671#endif 4625#endif
diff --git a/mm/slab.h b/mm/slab.h
index 7deeb449a301..dc78101962a1 100644
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -47,4 +47,12 @@ static inline struct kmem_cache *__kmem_cache_alias(const char *name, size_t siz
47 47
48int __kmem_cache_shutdown(struct kmem_cache *); 48int __kmem_cache_shutdown(struct kmem_cache *);
49 49
50struct seq_file;
51struct file;
52void print_slabinfo_header(struct seq_file *m);
53
54int slabinfo_show(struct seq_file *m, void *p);
55
56ssize_t slabinfo_write(struct file *file, const char __user *buffer,
57 size_t count, loff_t *ppos);
50#endif 58#endif
diff --git a/mm/slab_common.c b/mm/slab_common.c
index 069a24e64403..2e4b4c6d89e2 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -13,6 +13,8 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/cpu.h> 14#include <linux/cpu.h>
15#include <linux/uaccess.h> 15#include <linux/uaccess.h>
16#include <linux/seq_file.h>
17#include <linux/proc_fs.h>
16#include <asm/cacheflush.h> 18#include <asm/cacheflush.h>
17#include <asm/tlbflush.h> 19#include <asm/tlbflush.h>
18#include <asm/page.h> 20#include <asm/page.h>
@@ -192,3 +194,71 @@ int slab_is_available(void)
192{ 194{
193 return slab_state >= UP; 195 return slab_state >= UP;
194} 196}
197
198#ifdef CONFIG_SLABINFO
199static void *s_start(struct seq_file *m, loff_t *pos)
200{
201 loff_t n = *pos;
202
203 mutex_lock(&slab_mutex);
204 if (!n)
205 print_slabinfo_header(m);
206
207 return seq_list_start(&slab_caches, *pos);
208}
209
210static void *s_next(struct seq_file *m, void *p, loff_t *pos)
211{
212 return seq_list_next(p, &slab_caches, pos);
213}
214
215static void s_stop(struct seq_file *m, void *p)
216{
217 mutex_unlock(&slab_mutex);
218}
219
220static int s_show(struct seq_file *m, void *p)
221{
222 return slabinfo_show(m, p);
223}
224
225/*
226 * slabinfo_op - iterator that generates /proc/slabinfo
227 *
228 * Output layout:
229 * cache-name
230 * num-active-objs
231 * total-objs
232 * object size
233 * num-active-slabs
234 * total-slabs
235 * num-pages-per-slab
236 * + further values on SMP and with statistics enabled
237 */
238static const struct seq_operations slabinfo_op = {
239 .start = s_start,
240 .next = s_next,
241 .stop = s_stop,
242 .show = s_show,
243};
244
245static int slabinfo_open(struct inode *inode, struct file *file)
246{
247 return seq_open(file, &slabinfo_op);
248}
249
250static const struct file_operations proc_slabinfo_operations = {
251 .open = slabinfo_open,
252 .read = seq_read,
253 .write = slabinfo_write,
254 .llseek = seq_lseek,
255 .release = seq_release,
256};
257
258static int __init slab_proc_init(void)
259{
260 proc_create("slabinfo", S_IRUSR, NULL, &proc_slabinfo_operations);
261 return 0;
262}
263module_init(slab_proc_init);
264#endif /* CONFIG_SLABINFO */
diff --git a/mm/slub.c b/mm/slub.c
index a0d698467f70..77a0c8a9fc75 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -5405,7 +5405,7 @@ __initcall(slab_sysfs_init);
5405 * The /proc/slabinfo ABI 5405 * The /proc/slabinfo ABI
5406 */ 5406 */
5407#ifdef CONFIG_SLABINFO 5407#ifdef CONFIG_SLABINFO
5408static void print_slabinfo_header(struct seq_file *m) 5408void print_slabinfo_header(struct seq_file *m)
5409{ 5409{
5410 seq_puts(m, "slabinfo - version: 2.1\n"); 5410 seq_puts(m, "slabinfo - version: 2.1\n");
5411 seq_puts(m, "# name <active_objs> <num_objs> <object_size> " 5411 seq_puts(m, "# name <active_objs> <num_objs> <object_size> "
@@ -5415,28 +5415,7 @@ static void print_slabinfo_header(struct seq_file *m)
5415 seq_putc(m, '\n'); 5415 seq_putc(m, '\n');
5416} 5416}
5417 5417
5418static void *s_start(struct seq_file *m, loff_t *pos) 5418int slabinfo_show(struct seq_file *m, void *p)
5419{
5420 loff_t n = *pos;
5421
5422 mutex_lock(&slab_mutex);
5423 if (!n)
5424 print_slabinfo_header(m);
5425
5426 return seq_list_start(&slab_caches, *pos);
5427}
5428
5429static void *s_next(struct seq_file *m, void *p, loff_t *pos)
5430{
5431 return seq_list_next(p, &slab_caches, pos);
5432}
5433
5434static void s_stop(struct seq_file *m, void *p)
5435{
5436 mutex_unlock(&slab_mutex);
5437}
5438
5439static int s_show(struct seq_file *m, void *p)
5440{ 5419{
5441 unsigned long nr_partials = 0; 5420 unsigned long nr_partials = 0;
5442 unsigned long nr_slabs = 0; 5421 unsigned long nr_slabs = 0;
@@ -5472,29 +5451,9 @@ static int s_show(struct seq_file *m, void *p)
5472 return 0; 5451 return 0;
5473} 5452}
5474 5453
5475static const struct seq_operations slabinfo_op = { 5454ssize_t slabinfo_write(struct file *file, const char __user *buffer,
5476 .start = s_start, 5455 size_t count, loff_t *ppos)
5477 .next = s_next,
5478 .stop = s_stop,
5479 .show = s_show,
5480};
5481
5482static int slabinfo_open(struct inode *inode, struct file *file)
5483{
5484 return seq_open(file, &slabinfo_op);
5485}
5486
5487static const struct file_operations proc_slabinfo_operations = {
5488 .open = slabinfo_open,
5489 .read = seq_read,
5490 .llseek = seq_lseek,
5491 .release = seq_release,
5492};
5493
5494static int __init slab_proc_init(void)
5495{ 5456{
5496 proc_create("slabinfo", S_IRUSR, NULL, &proc_slabinfo_operations); 5457 return -EIO;
5497 return 0;
5498} 5458}
5499module_init(slab_proc_init);
5500#endif /* CONFIG_SLABINFO */ 5459#endif /* CONFIG_SLABINFO */