Skip to content

Commit 1c84724

Browse files
committed
Merge tag 'slab-fixes-for-6.6-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab
Pull slab fixes from Vlastimil Babka: - stable fix to prevent list corruption when destroying caches with leftover objects (Rafael Aquini) - fix for a gotcha in kmalloc_size_roundup() when calling it with too high size, discovered when recently a networking call site had to be fixed for a different issue (David Laight) * tag 'slab-fixes-for-6.6-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab: slab: kmalloc_size_roundup() must not return 0 for non-zero size mm/slab_common: fix slab_caches list corruption after kmem_cache_destroy()
2 parents 6edc84b + 8446a4d commit 1c84724

File tree

1 file changed

+18
-18
lines changed

1 file changed

+18
-18
lines changed

mm/slab_common.c

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ void slab_kmem_cache_release(struct kmem_cache *s)
479479

480480
void kmem_cache_destroy(struct kmem_cache *s)
481481
{
482-
int refcnt;
482+
int err = -EBUSY;
483483
bool rcu_set;
484484

485485
if (unlikely(!s) || !kasan_check_byte(s))
@@ -490,17 +490,17 @@ void kmem_cache_destroy(struct kmem_cache *s)
490490

491491
rcu_set = s->flags & SLAB_TYPESAFE_BY_RCU;
492492

493-
refcnt = --s->refcount;
494-
if (refcnt)
493+
s->refcount--;
494+
if (s->refcount)
495495
goto out_unlock;
496496

497-
WARN(shutdown_cache(s),
498-
"%s %s: Slab cache still has objects when called from %pS",
497+
err = shutdown_cache(s);
498+
WARN(err, "%s %s: Slab cache still has objects when called from %pS",
499499
__func__, s->name, (void *)_RET_IP_);
500500
out_unlock:
501501
mutex_unlock(&slab_mutex);
502502
cpus_read_unlock();
503-
if (!refcnt && !rcu_set)
503+
if (!err && !rcu_set)
504504
kmem_cache_release(s);
505505
}
506506
EXPORT_SYMBOL(kmem_cache_destroy);
@@ -745,24 +745,24 @@ struct kmem_cache *kmalloc_slab(size_t size, gfp_t flags, unsigned long caller)
745745

746746
size_t kmalloc_size_roundup(size_t size)
747747
{
748-
struct kmem_cache *c;
748+
if (size && size <= KMALLOC_MAX_CACHE_SIZE) {
749+
/*
750+
* The flags don't matter since size_index is common to all.
751+
* Neither does the caller for just getting ->object_size.
752+
*/
753+
return kmalloc_slab(size, GFP_KERNEL, 0)->object_size;
754+
}
749755

750-
/* Short-circuit the 0 size case. */
751-
if (unlikely(size == 0))
752-
return 0;
753-
/* Short-circuit saturated "too-large" case. */
754-
if (unlikely(size == SIZE_MAX))
755-
return SIZE_MAX;
756756
/* Above the smaller buckets, size is a multiple of page size. */
757-
if (size > KMALLOC_MAX_CACHE_SIZE)
757+
if (size && size <= KMALLOC_MAX_SIZE)
758758
return PAGE_SIZE << get_order(size);
759759

760760
/*
761-
* The flags don't matter since size_index is common to all.
762-
* Neither does the caller for just getting ->object_size.
761+
* Return 'size' for 0 - kmalloc() returns ZERO_SIZE_PTR
762+
* and very large size - kmalloc() may fail.
763763
*/
764-
c = kmalloc_slab(size, GFP_KERNEL, 0);
765-
return c ? c->object_size : 0;
764+
return size;
765+
766766
}
767767
EXPORT_SYMBOL(kmalloc_size_roundup);
768768

0 commit comments

Comments
 (0)