From 837e426c1f302e580a18a213fd216322f480caf8 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 7 Jun 2023 10:43:43 -0700 Subject: [PATCH] Linux: Never sleep in kmem_cache_alloc(..., KM_NOSLEEP) (#14926) 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 Reviewed-by: Adam Moss Reviewed-by: Brian Atkinson Reviewed-by: Richard Yao Reviewed-by: Tony Hutter --- module/os/linux/spl/spl-kmem-cache.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/module/os/linux/spl/spl-kmem-cache.c b/module/os/linux/spl/spl-kmem-cache.c index d586afa9be..c7fc3c854e 100644 --- a/module/os/linux/spl/spl-kmem-cache.c +++ b/module/os/linux/spl/spl-kmem-cache.c @@ -1020,9 +1020,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.