@@ -380,8 +380,11 @@ kmem_buckets *kmem_buckets_create(const char *name, slab_flags_t flags,
380
380
unsigned int usersize ,
381
381
void (* ctor )(void * ))
382
382
{
383
+ unsigned long mask = 0 ;
384
+ unsigned int idx ;
383
385
kmem_buckets * b ;
384
- int idx ;
386
+
387
+ BUILD_BUG_ON (ARRAY_SIZE (kmalloc_caches [KMALLOC_NORMAL ]) > BITS_PER_LONG );
385
388
386
389
/*
387
390
* 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,
403
406
for (idx = 0 ; idx < ARRAY_SIZE (kmalloc_caches [KMALLOC_NORMAL ]); idx ++ ) {
404
407
char * short_size , * cache_name ;
405
408
unsigned int cache_useroffset , cache_usersize ;
406
- unsigned int size ;
409
+ unsigned int size , aligned_idx ;
407
410
408
411
if (!kmalloc_caches [KMALLOC_NORMAL ][idx ])
409
412
continue ;
@@ -416,29 +419,35 @@ kmem_buckets *kmem_buckets_create(const char *name, slab_flags_t flags,
416
419
if (WARN_ON (!short_size ))
417
420
goto fail ;
418
421
419
- cache_name = kasprintf (GFP_KERNEL , "%s-%s" , name , short_size + 1 );
420
- if (WARN_ON (!cache_name ))
421
- goto fail ;
422
-
423
422
if (useroffset >= size ) {
424
423
cache_useroffset = 0 ;
425
424
cache_usersize = 0 ;
426
425
} else {
427
426
cache_useroffset = useroffset ;
428
427
cache_usersize = min (size - cache_useroffset , usersize );
429
428
}
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 ,
431
436
0 , flags , cache_useroffset ,
432
437
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 ];
436
445
}
437
446
438
447
return b ;
439
448
440
449
fail :
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 ]))
442
451
kmem_cache_destroy ((* b )[idx ]);
443
452
kmem_cache_free (kmem_buckets_cache , b );
444
453
0 commit comments