slab fix for 6.12-rc7

-----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCAAdFiEEe7vIQRWZI0iWSE3xu+CwddJFiJoFAmcuE+8ACgkQu+CwddJF
 iJoAmAf+JhB/c4xgZ6ztCPNRHAeMTBomr578qFqE1uU7HW4rZaWiVAuIYRghpVgj
 xXXRU1sITBrMJzakRr3kYDIjchv08yDOd/Bx3nkgRUHAozhNh2DVGR7XVF9qKNDU
 0Xof4+hNXSAqHsBTgJm3rYq42qdjVrJ0oA83EfwHFRUxVwrc6pARBrbNHprxfx1q
 /HbGI/FWqF/O2KEO45XuXHc/G4ZxLu/DlsHEcP7jHKG/TU2u3+wIUzGkIe1zgHH8
 pD5ARsRA9QG2zQ3Z12guh4zyLVjc+REg29/ko8J5cLLs79KHV7I9nSHW5+bw0425
 zAgOmo3P2NwQSnmNo0fdTWlNPniIsg==
 =+Co+
 -----END PGP SIGNATURE-----

Merge tag 'slab-for-6.12-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab

Pull slab fix from Vlastimil Babka:

 - Fix for duplicate caches in some arm64 configurations with
   CONFIG_SLAB_BUCKETS (Koichiro Den)

* tag 'slab-for-6.12-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab:
  mm/slab: fix warning caused by duplicate kmem_cache creation in kmem_buckets_create
This commit is contained in:
Linus Torvalds 2024-11-08 07:35:16 -10:00
commit f1dce1f093

View File

@ -380,8 +380,11 @@ kmem_buckets *kmem_buckets_create(const char *name, slab_flags_t flags,
unsigned int usersize,
void (*ctor)(void *))
{
unsigned long mask = 0;
unsigned int idx;
kmem_buckets *b;
int idx;
BUILD_BUG_ON(ARRAY_SIZE(kmalloc_caches[KMALLOC_NORMAL]) > BITS_PER_LONG);
/*
* When the separate buckets API is not built in, just return
@ -403,7 +406,7 @@ kmem_buckets *kmem_buckets_create(const char *name, slab_flags_t flags,
for (idx = 0; idx < ARRAY_SIZE(kmalloc_caches[KMALLOC_NORMAL]); idx++) {
char *short_size, *cache_name;
unsigned int cache_useroffset, cache_usersize;
unsigned int size;
unsigned int size, aligned_idx;
if (!kmalloc_caches[KMALLOC_NORMAL][idx])
continue;
@ -416,10 +419,6 @@ kmem_buckets *kmem_buckets_create(const char *name, slab_flags_t flags,
if (WARN_ON(!short_size))
goto fail;
cache_name = kasprintf(GFP_KERNEL, "%s-%s", name, short_size + 1);
if (WARN_ON(!cache_name))
goto fail;
if (useroffset >= size) {
cache_useroffset = 0;
cache_usersize = 0;
@ -427,18 +426,28 @@ kmem_buckets *kmem_buckets_create(const char *name, slab_flags_t flags,
cache_useroffset = useroffset;
cache_usersize = min(size - cache_useroffset, usersize);
}
(*b)[idx] = kmem_cache_create_usercopy(cache_name, size,
aligned_idx = __kmalloc_index(size, false);
if (!(*b)[aligned_idx]) {
cache_name = kasprintf(GFP_KERNEL, "%s-%s", name, short_size + 1);
if (WARN_ON(!cache_name))
goto fail;
(*b)[aligned_idx] = kmem_cache_create_usercopy(cache_name, size,
0, flags, cache_useroffset,
cache_usersize, ctor);
kfree(cache_name);
if (WARN_ON(!(*b)[idx]))
goto fail;
kfree(cache_name);
if (WARN_ON(!(*b)[aligned_idx]))
goto fail;
set_bit(aligned_idx, &mask);
}
if (idx != aligned_idx)
(*b)[idx] = (*b)[aligned_idx];
}
return b;
fail:
for (idx = 0; idx < ARRAY_SIZE(kmalloc_caches[KMALLOC_NORMAL]); idx++)
for_each_set_bit(idx, &mask, ARRAY_SIZE(kmalloc_caches[KMALLOC_NORMAL]))
kmem_cache_destroy((*b)[idx]);
kmem_cache_free(kmem_buckets_cache, b);