@@ -380,8 +380,11 @@ kmem_buckets *kmem_buckets_create(const char *name, slab_flags_t flags,
380380 unsigned int usersize ,
381381 void (* ctor )(void * ))
382382{
383+ unsigned long mask = 0 ;
384+ unsigned int idx ;
383385 kmem_buckets * b ;
384- int idx ;
386+
387+ BUILD_BUG_ON (ARRAY_SIZE (kmalloc_caches [KMALLOC_NORMAL ]) > BITS_PER_LONG );
385388
386389 /*
387390 * 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,
403406 for (idx = 0 ; idx < ARRAY_SIZE (kmalloc_caches [KMALLOC_NORMAL ]); idx ++ ) {
404407 char * short_size , * cache_name ;
405408 unsigned int cache_useroffset , cache_usersize ;
406- unsigned int size ;
409+ unsigned int size , aligned_idx ;
407410
408411 if (!kmalloc_caches [KMALLOC_NORMAL ][idx ])
409412 continue ;
@@ -416,29 +419,35 @@ kmem_buckets *kmem_buckets_create(const char *name, slab_flags_t flags,
416419 if (WARN_ON (!short_size ))
417420 goto fail ;
418421
419- cache_name = kasprintf (GFP_KERNEL , "%s-%s" , name , short_size + 1 );
420- if (WARN_ON (!cache_name ))
421- goto fail ;
422-
423422 if (useroffset >= size ) {
424423 cache_useroffset = 0 ;
425424 cache_usersize = 0 ;
426425 } else {
427426 cache_useroffset = useroffset ;
428427 cache_usersize = min (size - cache_useroffset , usersize );
429428 }
430- (* b )[idx ] = kmem_cache_create_usercopy (cache_name , size ,
429+
430+ aligned_idx = __kmalloc_index (size , false);
431+ if (!(* b )[aligned_idx ]) {
432+ cache_name = kasprintf (GFP_KERNEL , "%s-%s" , name , short_size + 1 );
433+ if (WARN_ON (!cache_name ))
434+ goto fail ;
435+ (* b )[aligned_idx ] = kmem_cache_create_usercopy (cache_name , size ,
431436 0 , flags , cache_useroffset ,
432437 cache_usersize , ctor );
433- kfree (cache_name );
434- if (WARN_ON (!(* b )[idx ]))
435- goto fail ;
438+ kfree (cache_name );
439+ if (WARN_ON (!(* b )[aligned_idx ]))
440+ goto fail ;
441+ set_bit (aligned_idx , & mask );
442+ }
443+ if (idx != aligned_idx )
444+ (* b )[idx ] = (* b )[aligned_idx ];
436445 }
437446
438447 return b ;
439448
440449fail :
441- for (idx = 0 ; idx < ARRAY_SIZE (kmalloc_caches [KMALLOC_NORMAL ]); idx ++ )
450+ for_each_set_bit (idx , & mask , ARRAY_SIZE (kmalloc_caches [KMALLOC_NORMAL ]))
442451 kmem_cache_destroy ((* b )[idx ]);
443452 kmem_cache_free (kmem_buckets_cache , b );
444453
0 commit comments