slab: print slabinfo header in seq show
authorVladimir Davydov <vdavydov@parallels.com>
Wed, 10 Dec 2014 23:42:16 +0000 (15:42 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 11 Dec 2014 01:41:04 +0000 (17:41 -0800)
Currently we print the slabinfo header in the seq start method, which
makes it unusable for showing leaks, so we have leaks_show, which does
practically the same as s_show except it doesn't show the header.

However, we can print the header in the seq show method - we only need
to check if the current element is the first on the list.  This will
allow us to use the same set of seq iterators for both leaks and
slabinfo reporting, which is nice.

Signed-off-by: Vladimir Davydov <vdavydov@parallels.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
mm/slab.c
mm/slab.h
mm/slab_common.c

index eae2d21cc14f60454eba9c683a49091cd2aded64..a2152a2573dd28b07daf557f09614a75e5104b49 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -4043,12 +4043,6 @@ ssize_t slabinfo_write(struct file *file, const char __user *buffer,
 
 #ifdef CONFIG_DEBUG_SLAB_LEAK
 
-static void *leaks_start(struct seq_file *m, loff_t *pos)
-{
-       mutex_lock(&slab_mutex);
-       return seq_list_start(&slab_caches, *pos);
-}
-
 static inline int add_caller(unsigned long *n, unsigned long v)
 {
        unsigned long *p;
@@ -4170,7 +4164,7 @@ static int leaks_show(struct seq_file *m, void *p)
 }
 
 static const struct seq_operations slabstats_op = {
-       .start = leaks_start,
+       .start = slab_start,
        .next = slab_next,
        .stop = slab_stop,
        .show = leaks_show,
index ab019e63e3c204d13b36c3957957e4310587d18b..53a55c70c4096fe98f0a15e01ff6ed8c4d2c5901 100644 (file)
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -357,6 +357,7 @@ static inline struct kmem_cache_node *get_node(struct kmem_cache *s, int node)
 
 #endif
 
+void *slab_start(struct seq_file *m, loff_t *pos);
 void *slab_next(struct seq_file *m, void *p, loff_t *pos);
 void slab_stop(struct seq_file *m, void *p);
 
index dcdab81bd240bafe3bec02cb32bf3390763a90e9..06aeaf091f213af43ce9f73d8beffbd754a3bf51 100644 (file)
@@ -834,14 +834,9 @@ void print_slabinfo_header(struct seq_file *m)
        seq_putc(m, '\n');
 }
 
-static void *s_start(struct seq_file *m, loff_t *pos)
+void *slab_start(struct seq_file *m, loff_t *pos)
 {
-       loff_t n = *pos;
-
        mutex_lock(&slab_mutex);
-       if (!n)
-               print_slabinfo_header(m);
-
        return seq_list_start(&slab_caches, *pos);
 }
 
@@ -903,10 +898,12 @@ int cache_show(struct kmem_cache *s, struct seq_file *m)
        return 0;
 }
 
-static int s_show(struct seq_file *m, void *p)
+static int slab_show(struct seq_file *m, void *p)
 {
        struct kmem_cache *s = list_entry(p, struct kmem_cache, list);
 
+       if (p == slab_caches.next)
+               print_slabinfo_header(m);
        if (!is_root_cache(s))
                return 0;
        return cache_show(s, m);
@@ -926,10 +923,10 @@ static int s_show(struct seq_file *m, void *p)
  * + further values on SMP and with statistics enabled
  */
 static const struct seq_operations slabinfo_op = {
-       .start = s_start,
+       .start = slab_start,
        .next = slab_next,
        .stop = slab_stop,
-       .show = s_show,
+       .show = slab_show,
 };
 
 static int slabinfo_open(struct inode *inode, struct file *file)