diff mbox series

[RFC] SLUB: list_slab_objects() looks like a miss-merge

Message ID 20200618094623.ef7wrsyrnrsfm7as@linutronix.de (mailing list archive)
State New, archived
Headers show
Series [RFC] SLUB: list_slab_objects() looks like a miss-merge | expand

Commit Message

Sebastian Andrzej Siewior June 18, 2020, 9:46 a.m. UTC
Hi,

I stumbled over the following:

| static void free_partial(struct kmem_cache *s, struct kmem_cache_node *n)
| {
…
|         unsigned long *map = NULL;
| 
| #ifdef CONFIG_SLUB_DEBUG
|         map = bitmap_alloc(oo_objects(s->max), GFP_KERNEL);
| #endif
…
|                 } else {
|                         list_slab_objects(s, page,
|                           "Objects remaining in %s on __kmem_cache_shutdown()",
|                           map);
|                 }
|         }
…
| #ifdef CONFIG_SLUB_DEBUG
|         bitmap_free(map);
| #endif
…
| }


so map gets allocated, passed to list_slab_objects() and then freed at
end. Haven't notices where `map' is set but maybe it is just a buffer
used in list_slab_objects().
And then there is this:

| static void list_slab_objects(struct kmem_cache *s, struct page *page,
|                               const char *text, unsigned long *map)
| {
| #ifdef CONFIG_SLUB_DEBUG
|         void *addr = page_address(page);
|         void *p;
| 
|         if (!map)
|                 return;

No map, return. Okay.

|         slab_err(s, page, text, s->name);
|         slab_lock(page);
| 
|         map = get_map(s, page);

and here `map' gets overwritten, correct? But it gets initialized. And it also
acquires `object_map_lock'.

|         for_each_object(p, s, addr, page->objects) {
| 
|                 if (!test_bit(slab_index(p, s, addr), map)) {
|                         pr_err("INFO: Object 0x%p @offset=%tu\n", p, p - addr);
|                         print_tracking(s, p);
|                 }
|         }

and here I would expect to unlock `object_map_lock'.

|         slab_unlock(page);
| #endif
| }   

Is this a miss-merge of some kind? I would revert commit
   aa456c7aebb14 ("slub: remove kmalloc under list_lock from list_slab_objects() V2")

by doing this:



Is there something I'm missing? This is completely untested of course.

Sebastian

Comments

Christoph Lameter (Ampere) June 18, 2020, 3:03 p.m. UTC | #1
On Thu, 18 Jun 2020, Sebastian Andrzej Siewior wrote:

> Is this a miss-merge of some kind? I would revert commit
>    aa456c7aebb14 ("slub: remove kmalloc under list_lock from list_slab_objects() V2")

Seems that two fixes to the same problem were merged?
Yu Zhao June 18, 2020, 9:02 p.m. UTC | #2
On Thu, Jun 18, 2020 at 03:03:25PM +0000, Christopher Lameter wrote:
> On Thu, 18 Jun 2020, Sebastian Andrzej Siewior wrote:
> 
> > Is this a miss-merge of some kind? I would revert commit
> >    aa456c7aebb14 ("slub: remove kmalloc under list_lock from list_slab_objects() V2")
> 
> Seems that two fixes to the same problem were merged?

Sorry, I assumed the previous fix had been dropped when this one was
taken. I'm fine with reverting the previous fix if this one is deemed
more appropriate.
diff mbox series

Patch

diff --git a/kernel/locking/rwsem.h b/kernel/locking/rwsem.h
deleted file mode 100644
index e69de29bb2d1d..0000000000000
diff --git a/mm/slub.c b/mm/slub.c
index b8f798b50d44d..72195cafbb503 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3766,15 +3766,13 @@  static int kmem_cache_open(struct kmem_cache *s, slab_flags_t flags)
 }
 
 static void list_slab_objects(struct kmem_cache *s, struct page *page,
-			      const char *text, unsigned long *map)
+			      const char *text)
 {
 #ifdef CONFIG_SLUB_DEBUG
 	void *addr = page_address(page);
+	unsigned long *map;
 	void *p;
 
-	if (!map)
-		return;
-
 	slab_err(s, page, text, s->name);
 	slab_lock(page);
 
@@ -3786,6 +3784,7 @@  static void list_slab_objects(struct kmem_cache *s, struct page *page,
 			print_tracking(s, p);
 		}
 	}
+	put_map(map);
 	slab_unlock(page);
 #endif
 }
@@ -3799,11 +3798,6 @@  static void free_partial(struct kmem_cache *s, struct kmem_cache_node *n)
 {
 	LIST_HEAD(discard);
 	struct page *page, *h;
-	unsigned long *map = NULL;
-
-#ifdef CONFIG_SLUB_DEBUG
-	map = bitmap_alloc(oo_objects(s->max), GFP_KERNEL);
-#endif
 
 	BUG_ON(irqs_disabled());
 	spin_lock_irq(&n->list_lock);
@@ -3813,16 +3807,11 @@  static void free_partial(struct kmem_cache *s, struct kmem_cache_node *n)
 			list_add(&page->slab_list, &discard);
 		} else {
 			list_slab_objects(s, page,
-			  "Objects remaining in %s on __kmem_cache_shutdown()",
-			  map);
+			  "Objects remaining in %s on __kmem_cache_shutdown()");
 		}
 	}
 	spin_unlock_irq(&n->list_lock);
 
-#ifdef CONFIG_SLUB_DEBUG
-	bitmap_free(map);
-#endif
-
 	list_for_each_entry_safe(page, h, &discard, slab_list)
 		discard_slab(s, page);
 }