Skip to content

Commit

Permalink
Linux: Never sleep in kmem_cache_alloc(..., KM_NOSLEEP) (openzfs#14926)
Browse files Browse the repository at this point in the history
When a kmem cache is exhausted and needs to be expanded a new
slab is allocated.  KM_SLEEP callers can block and wait for the
allocation, but KM_NOSLEEP callers were incorrectly allowed to
block as well.

Resolve this by attempting an emergency allocation as a best
effort.  This may fail but that's fine since any KM_NOSLEEP
consumer is required to handle an allocation failure.

Signed-off-by: Brian Behlendorf <[email protected]>
Reviewed-by: Adam Moss <[email protected]>
Reviewed-by: Brian Atkinson <[email protected]>
Reviewed-by: Richard Yao <[email protected]>
Reviewed-by: Tony Hutter <[email protected]>
  • Loading branch information
behlendorf authored Jun 7, 2023
1 parent bcd5321 commit 93f8abe
Showing 1 changed file with 11 additions and 1 deletion.
12 changes: 11 additions & 1 deletion module/os/linux/spl/spl-kmem-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -1015,9 +1015,19 @@ spl_cache_grow(spl_kmem_cache_t *skc, int flags, void **obj)
ASSERT0(flags & ~KM_PUBLIC_MASK);
ASSERT(skc->skc_magic == SKC_MAGIC);
ASSERT((skc->skc_flags & KMC_SLAB) == 0);
might_sleep();

*obj = NULL;

/*
* Since we can't sleep attempt an emergency allocation to satisfy
* the request. The only alterative is to fail the allocation but
* it's preferable try. The use of KM_NOSLEEP is expected to be rare.
*/
if (flags & KM_NOSLEEP)
return (spl_emergency_alloc(skc, flags, obj));

might_sleep();

/*
* Before allocating a new slab wait for any reaping to complete and
* then return so the local magazine can be rechecked for new objects.
Expand Down

0 comments on commit 93f8abe

Please sign in to comment.