The call slab_pre_alloc_hook() interacts with kmemgc and is not allowed to be called several times inside the bulk alloc for loop, due to the call to memcg_kmem_get_cache(). This would result in hitting the VM_BUG_ON in __memcg_kmem_get_cache. To match the number of "put" calls, the call to memcg_kmem_put_cache() is moved out of slab_post_alloc_hook(). Reported-by: Vladimir Davydov <vdavydov@xxxxxxxxxxxxx> Signed-off-by: Jesper Dangaard Brouer <brouer@xxxxxxxxxx> --- mm/slub.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/mm/slub.c b/mm/slub.c index 9be12ffae9fc..8e9e9b2ee6f3 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -1298,7 +1298,6 @@ static inline void slab_post_alloc_hook(struct kmem_cache *s, flags &= gfp_allowed_mask; kmemcheck_slab_alloc(s, flags, object, slab_ksize(s)); kmemleak_alloc_recursive(object, s->object_size, 1, s->flags, flags); - memcg_kmem_put_cache(s); kasan_slab_alloc(s, object); } @@ -2557,6 +2556,7 @@ redo: memset(object, 0, s->object_size); slab_post_alloc_hook(s, gfpflags, object); + memcg_kmem_put_cache(s); return object; } @@ -2906,6 +2906,11 @@ bool kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size, struct kmem_cache_cpu *c; int i; + /* memcg and kmem_cache debug support */ + s = slab_pre_alloc_hook(s, flags); + if (unlikely(!s)) + return false; + /* * Drain objects in the per cpu slab, while disabling local * IRQs, which protects against PREEMPT and interrupts @@ -2931,11 +2936,6 @@ bool kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size, continue; /* goto for-loop */ } - /* kmem_cache debug support */ - s = slab_pre_alloc_hook(s, flags); - if (unlikely(!s)) - goto error; - c->freelist = get_freepointer(s, object); p[i] = object; @@ -2953,9 +2953,11 @@ bool kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size, memset(p[j], 0, s->object_size); } + memcg_kmem_put_cache(s); return true; error: + memcg_kmem_put_cache(s); __kmem_cache_free_bulk(s, i, p); local_irq_enable(); return false; -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>