From e06f121442bc2973ad5bfa94c6be921c19381eea Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Tue, 18 Jun 2013 10:15:33 -0700 Subject: [PATCH] Register correct handlers in nvlist_alloc() The non-blocking allocation handlers in nvlist_alloc() would be mistakenly assigned if any flags other than KM_SLEEP were passed. This meant that nvlists allocated with KM_PUSHPUSH or other KM_* debug flags were effectively always using atomic allocations. While these failures were unlikely it could lead to assertions because KM_PUSHPAGE allocation in particular are guaranteed to succeed or block. They must never fail. Since this code is already wrapped in a _KERNEL define the cleanest fix is to check the __GFP_HIGH bit. When set the caller is signaling it is safe for the allocation to block, when it's clear atomic allocations must be used. Signed-off-by: Brian Behlendorf Issue zfsonlinux/spl#249 --- module/nvpair/nvpair.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/nvpair/nvpair.c b/module/nvpair/nvpair.c index 5c6898446793..7c8a5d99f6f0 100644 --- a/module/nvpair/nvpair.c +++ b/module/nvpair/nvpair.c @@ -271,7 +271,7 @@ nvlist_alloc(nvlist_t **nvlp, uint_t nvflag, int kmflag) { #if defined(_KERNEL) && !defined(_BOOT) return (nvlist_xalloc(nvlp, nvflag, - (kmflag == KM_SLEEP ? nv_alloc_sleep : nv_alloc_nosleep))); + (kmflag & __GFP_WAIT ? nv_alloc_sleep : nv_alloc_nosleep))); #else return (nvlist_xalloc(nvlp, nvflag, nv_alloc_nosleep)); #endif