It prints page addresses in slub.
Useful for search of leaked objects (say, I found leaked dentry with this after 
CT stop).

Signed-off-by: Stanislav Kinsburskiy <skinsbur...@virtuozzo.com>
---
 mm/slub.c |   35 ++++++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/mm/slub.c b/mm/slub.c
index 96a7aba..91a4de1 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -4559,7 +4559,8 @@ enum slab_stat_type {
        SL_PARTIAL,             /* Only partially allocated slabs */
        SL_CPU,                 /* Only slabs used for cpu caches */
        SL_OBJECTS,             /* Determine allocated objects not slabs */
-       SL_TOTAL                /* Determine object capacity not slabs */
+       SL_TOTAL,               /* Determine object capacity not slabs */
+       SL_PAGES
 };
 
 #define SO_ALL         (1 << SL_ALL)
@@ -4567,6 +4568,20 @@ enum slab_stat_type {
 #define SO_CPU         (1 << SL_CPU)
 #define SO_OBJECTS     (1 << SL_OBJECTS)
 #define SO_TOTAL       (1 << SL_TOTAL)
+#define SO_PAGES       (1 << SL_PAGES)
+
+static unsigned long print_pages(struct kmem_cache_node *n, char *buf)
+{
+       unsigned long flags;
+       unsigned long x = 0;
+       struct page *page;
+
+       spin_lock_irqsave(&n->list_lock, flags);
+       list_for_each_entry(page, &n->partial, lru)
+               x += sprintf(buf + x, "%p\n", page_address(page));
+       spin_unlock_irqrestore(&n->list_lock, flags);
+       return x;
+}
 
 static ssize_t show_slab_objects(struct kmem_cache *s,
                            char *buf, unsigned long flags)
@@ -4582,6 +4597,17 @@ static ssize_t show_slab_objects(struct kmem_cache *s,
                return -ENOMEM;
        per_cpu = nodes + nr_node_ids;
 
+       if (flags & SO_PAGES) {
+               x = 0;
+               for_each_node_state(node, N_NORMAL_MEMORY) {
+                       struct kmem_cache_node *n = get_node(s, node);
+
+                       x += print_pages(n, buf + x);
+               }
+               kfree(nodes);
+               return x;
+       }
+
        if (flags & SO_CPU) {
                int cpu;
 
@@ -4831,6 +4857,12 @@ static ssize_t objects_partial_show(struct kmem_cache 
*s, char *buf)
 }
 SLAB_ATTR_RO(objects_partial);
 
+static ssize_t pages_show(struct kmem_cache *s, char *buf)
+{
+       return show_slab_objects(s, buf, SO_PAGES);
+}
+SLAB_ATTR_RO(pages);
+
 static ssize_t slabs_cpu_partial_show(struct kmem_cache *s, char *buf)
 {
        int objects = 0;
@@ -5257,6 +5289,7 @@ static struct attribute *slab_attrs[] = {
        &failslab_attr.attr,
 #endif
 
+       &pages_attr.attr,
        NULL
 };
 

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to