2121#include "slab.h"
2222
2323static DECLARE_FAULT_ATTR (fail_mempool_alloc );
24+ static DECLARE_FAULT_ATTR (fail_mempool_alloc_bulk );
2425
2526static int __init mempool_faul_inject_init (void )
2627{
27- return PTR_ERR_OR_ZERO (fault_create_debugfs_attr ("fail_mempool_alloc" ,
28+ int error ;
29+
30+ error = PTR_ERR_OR_ZERO (fault_create_debugfs_attr ("fail_mempool_alloc" ,
2831 NULL , & fail_mempool_alloc ));
32+ if (error )
33+ return error ;
34+
35+ /* booting will fail on error return here, don't bother to cleanup */
36+ return PTR_ERR_OR_ZERO (
37+ fault_create_debugfs_attr ("fail_mempool_alloc_bulk" , NULL ,
38+ & fail_mempool_alloc_bulk ));
2939}
3040late_initcall (mempool_faul_inject_init );
3141
@@ -380,15 +390,22 @@ int mempool_resize(mempool_t *pool, int new_min_nr)
380390}
381391EXPORT_SYMBOL (mempool_resize );
382392
383- static void * mempool_alloc_from_pool (struct mempool * pool , gfp_t gfp_mask )
393+ static unsigned int mempool_alloc_from_pool (struct mempool * pool , void * * elems ,
394+ unsigned int count , unsigned int allocated ,
395+ gfp_t gfp_mask )
384396{
385397 unsigned long flags ;
386- void * element ;
398+ unsigned int i ;
387399
388400 spin_lock_irqsave (& pool -> lock , flags );
389- if (unlikely (! pool -> curr_nr ))
401+ if (unlikely (pool -> curr_nr < count - allocated ))
390402 goto fail ;
391- element = remove_element (pool );
403+ for (i = 0 ; i < count ; i ++ ) {
404+ if (!elems [i ]) {
405+ elems [i ] = remove_element (pool );
406+ allocated ++ ;
407+ }
408+ }
392409 spin_unlock_irqrestore (& pool -> lock , flags );
393410
394411 /* Paired with rmb in mempool_free(), read comment there. */
@@ -398,8 +415,9 @@ static void *mempool_alloc_from_pool(struct mempool *pool, gfp_t gfp_mask)
398415 * Update the allocation stack trace as this is more useful for
399416 * debugging.
400417 */
401- kmemleak_update_trace (element );
402- return element ;
418+ for (i = 0 ; i < count ; i ++ )
419+ kmemleak_update_trace (elems [i ]);
420+ return allocated ;
403421
404422fail :
405423 if (gfp_mask & __GFP_DIRECT_RECLAIM ) {
@@ -421,7 +439,7 @@ static void *mempool_alloc_from_pool(struct mempool *pool, gfp_t gfp_mask)
421439 spin_unlock_irqrestore (& pool -> lock , flags );
422440 }
423441
424- return NULL ;
442+ return allocated ;
425443}
426444
427445/*
@@ -437,6 +455,65 @@ static inline gfp_t mempool_adjust_gfp(gfp_t *gfp_mask)
437455 return * gfp_mask & ~(__GFP_DIRECT_RECLAIM | __GFP_IO );
438456}
439457
458+ /**
459+ * mempool_alloc_bulk - allocate multiple elements from a memory pool
460+ * @pool: pointer to the memory pool
461+ * @elems: partially or fully populated elements array
462+ * @count: number of entries in @elem that need to be allocated
463+ * @allocated: number of entries in @elem already allocated
464+ *
465+ * Allocate elements for each slot in @elem that is non-%NULL. This is done by
466+ * first calling into the alloc_fn supplied at pool initialization time, and
467+ * dipping into the reserved pool when alloc_fn fails to allocate an element.
468+ *
469+ * On return all @count elements in @elems will be populated.
470+ *
471+ * Return: Always 0. If it wasn't for %$#^$ alloc tags, it would return void.
472+ */
473+ int mempool_alloc_bulk_noprof (struct mempool * pool , void * * elems ,
474+ unsigned int count , unsigned int allocated )
475+ {
476+ gfp_t gfp_mask = GFP_KERNEL ;
477+ gfp_t gfp_temp = mempool_adjust_gfp (& gfp_mask );
478+ unsigned int i = 0 ;
479+
480+ VM_WARN_ON_ONCE (count > pool -> min_nr );
481+ might_alloc (gfp_mask );
482+
483+ /*
484+ * If an error is injected, fail all elements in a bulk allocation so
485+ * that we stress the multiple elements missing path.
486+ */
487+ if (should_fail_ex (& fail_mempool_alloc_bulk , 1 , FAULT_NOWARN )) {
488+ pr_info ("forcing mempool usage for %pS\n" ,
489+ (void * )_RET_IP_ );
490+ goto use_pool ;
491+ }
492+
493+ repeat_alloc :
494+ /*
495+ * Try to allocate the elements using the allocation callback first as
496+ * that might succeed even when the caller's bulk allocation did not.
497+ */
498+ for (i = 0 ; i < count ; i ++ ) {
499+ if (elems [i ])
500+ continue ;
501+ elems [i ] = pool -> alloc (gfp_temp , pool -> pool_data );
502+ if (unlikely (!elems [i ]))
503+ goto use_pool ;
504+ allocated ++ ;
505+ }
506+
507+ return 0 ;
508+
509+ use_pool :
510+ allocated = mempool_alloc_from_pool (pool , elems , count , allocated ,
511+ gfp_temp );
512+ gfp_temp = gfp_mask ;
513+ goto repeat_alloc ;
514+ }
515+ EXPORT_SYMBOL_GPL (mempool_alloc_bulk_noprof );
516+
440517/**
441518 * mempool_alloc - allocate an element from a memory pool
442519 * @pool: pointer to the memory pool
@@ -478,8 +555,7 @@ void *mempool_alloc_noprof(mempool_t *pool, gfp_t gfp_mask)
478555 * sleep in mempool_alloc_from_pool. Retry the allocation
479556 * with all flags set in that case.
480557 */
481- element = mempool_alloc_from_pool (pool , gfp_temp );
482- if (!element ) {
558+ if (!mempool_alloc_from_pool (pool , & element , 1 , 0 , gfp_temp )) {
483559 if (gfp_temp != gfp_mask ) {
484560 gfp_temp = gfp_mask ;
485561 goto repeat_alloc ;
@@ -508,26 +584,33 @@ EXPORT_SYMBOL(mempool_alloc_noprof);
508584 */
509585void * mempool_alloc_preallocated (mempool_t * pool )
510586{
511- return mempool_alloc_from_pool (pool , GFP_NOWAIT );
587+ void * element = NULL ;
588+
589+ mempool_alloc_from_pool (pool , & element , 1 , 0 , GFP_NOWAIT );
590+ return element ;
512591}
513592EXPORT_SYMBOL (mempool_alloc_preallocated );
514593
515594/**
516- * mempool_free - return an element to a mempool
517- * @element: pointer to element
595+ * mempool_free_bulk - return elements to a mempool
518596 * @pool: pointer to the memory pool
597+ * @elems: elements to return
598+ * @count: number of elements to return
519599 *
520- * Returns @element to @pool if it needs replenishing, else frees it using
521- * the free_fn callback in @pool.
600+ * Returns a number of elements from the start of @elem to @pool if @pool needs
601+ * replenishing and sets their slots in @elem to NULL. Other elements are left
602+ * in @elem.
522603 *
523- * This function only sleeps if the free_fn callback sleeps.
604+ * Return: number of elements transferred to @pool. Elements are always
605+ * transferred from the beginning of @elem, so the return value can be used as
606+ * an offset into @elem for the freeing the remaining elements in the caller.
524607 */
525- void mempool_free (void * element , mempool_t * pool )
608+ unsigned int mempool_free_bulk (struct mempool * pool , void * * elems ,
609+ unsigned int count )
526610{
527611 unsigned long flags ;
528-
529- if (unlikely (element == NULL ))
530- return ;
612+ unsigned int freed = 0 ;
613+ bool added = false;
531614
532615 /*
533616 * Paired with the wmb in mempool_alloc(). The preceding read is
@@ -561,42 +644,52 @@ void mempool_free(void *element, mempool_t *pool)
561644 * Waiters happen iff curr_nr is 0 and the above guarantee also
562645 * ensures that there will be frees which return elements to the
563646 * pool waking up the waiters.
564- */
565- if (unlikely (READ_ONCE (pool -> curr_nr ) < pool -> min_nr )) {
566- spin_lock_irqsave (& pool -> lock , flags );
567- if (likely (pool -> curr_nr < pool -> min_nr )) {
568- add_element (pool , element );
569- spin_unlock_irqrestore (& pool -> lock , flags );
570- if (wq_has_sleeper (& pool -> wait ))
571- wake_up (& pool -> wait );
572- return ;
573- }
574- spin_unlock_irqrestore (& pool -> lock , flags );
575- }
576-
577- /*
578- * Handle the min_nr = 0 edge case:
579647 *
580648 * For zero-minimum pools, curr_nr < min_nr (0 < 0) never succeeds,
581649 * so waiters sleeping on pool->wait would never be woken by the
582650 * wake-up path of previous test. This explicit check ensures the
583651 * allocation of element when both min_nr and curr_nr are 0, and
584652 * any active waiters are properly awakened.
585653 */
586- if (unlikely (pool -> min_nr == 0 &&
654+ if (unlikely (READ_ONCE (pool -> curr_nr ) < pool -> min_nr )) {
655+ spin_lock_irqsave (& pool -> lock , flags );
656+ while (pool -> curr_nr < pool -> min_nr && freed < count ) {
657+ add_element (pool , elems [freed ++ ]);
658+ added = true;
659+ }
660+ spin_unlock_irqrestore (& pool -> lock , flags );
661+ } else if (unlikely (pool -> min_nr == 0 &&
587662 READ_ONCE (pool -> curr_nr ) == 0 )) {
663+ /* Handle the min_nr = 0 edge case: */
588664 spin_lock_irqsave (& pool -> lock , flags );
589665 if (likely (pool -> curr_nr == 0 )) {
590- add_element (pool , element );
591- spin_unlock_irqrestore (& pool -> lock , flags );
592- if (wq_has_sleeper (& pool -> wait ))
593- wake_up (& pool -> wait );
594- return ;
666+ add_element (pool , elems [freed ++ ]);
667+ added = true;
595668 }
596669 spin_unlock_irqrestore (& pool -> lock , flags );
597670 }
598671
599- pool -> free (element , pool -> pool_data );
672+ if (unlikely (added ) && wq_has_sleeper (& pool -> wait ))
673+ wake_up (& pool -> wait );
674+
675+ return freed ;
676+ }
677+ EXPORT_SYMBOL_GPL (mempool_free_bulk );
678+
679+ /**
680+ * mempool_free - return an element to the pool.
681+ * @element: element to return
682+ * @pool: pointer to the memory pool
683+ *
684+ * Returns @element to @pool if it needs replenishing, else frees it using
685+ * the free_fn callback in @pool.
686+ *
687+ * This function only sleeps if the free_fn callback sleeps.
688+ */
689+ void mempool_free (void * element , struct mempool * pool )
690+ {
691+ if (likely (element ) && !mempool_free_bulk (pool , & element , 1 ))
692+ pool -> free (element , pool -> pool_data );
600693}
601694EXPORT_SYMBOL (mempool_free );
602695
0 commit comments