diff options
-rw-r--r-- | include/sys/nvpair.h | 1 | ||||
-rw-r--r-- | module/nvpair/nvpair.c | 21 | ||||
-rw-r--r-- | module/nvpair/nvpair_alloc_spl.c | 20 |
3 files changed, 38 insertions, 4 deletions
diff --git a/include/sys/nvpair.h b/include/sys/nvpair.h index cc399fd16..c502568a6 100644 --- a/include/sys/nvpair.h +++ b/include/sys/nvpair.h @@ -144,6 +144,7 @@ extern nv_alloc_t *nv_alloc_nosleep; #if defined(_KERNEL) && !defined(_BOOT) extern nv_alloc_t *nv_alloc_sleep; +extern nv_alloc_t *nv_alloc_pushpage; #endif int nv_alloc_init(nv_alloc_t *, const nv_alloc_ops_t *, /* args */ ...); diff --git a/module/nvpair/nvpair.c b/module/nvpair/nvpair.c index 5c6898446..36f4e4dc1 100644 --- a/module/nvpair/nvpair.c +++ b/module/nvpair/nvpair.c @@ -269,12 +269,25 @@ nvlist_nvflag(nvlist_t *nvl) int nvlist_alloc(nvlist_t **nvlp, uint_t nvflag, int kmflag) { + nv_alloc_t *nva = nv_alloc_nosleep; + #if defined(_KERNEL) && !defined(_BOOT) - return (nvlist_xalloc(nvlp, nvflag, - (kmflag == KM_SLEEP ? nv_alloc_sleep : nv_alloc_nosleep))); -#else - return (nvlist_xalloc(nvlp, nvflag, nv_alloc_nosleep)); + switch (kmflag) { + case KM_SLEEP: + nva = nv_alloc_sleep; + break; + case KM_PUSHPAGE: + nva = nv_alloc_pushpage; + break; + case KM_NOSLEEP: + nva = nv_alloc_nosleep; + break; + default: + return (EINVAL); + } #endif + + return (nvlist_xalloc(nvlp, nvflag, nva)); } int diff --git a/module/nvpair/nvpair_alloc_spl.c b/module/nvpair/nvpair_alloc_spl.c index 63d57a19a..be6e8f0a5 100644 --- a/module/nvpair/nvpair_alloc_spl.c +++ b/module/nvpair/nvpair_alloc_spl.c @@ -34,6 +34,12 @@ nv_alloc_sleep_spl(nv_alloc_t *nva, size_t size) } static void * +nv_alloc_pushpage_spl(nv_alloc_t *nva, size_t size) +{ + return (kmem_alloc(size, KM_PUSHPAGE | KM_NODEBUG)); +} + +static void * nv_alloc_nosleep_spl(nv_alloc_t *nva, size_t size) { return (kmem_alloc(size, KM_NOSLEEP)); @@ -53,6 +59,14 @@ const nv_alloc_ops_t spl_sleep_ops_def = { NULL /* nv_ao_reset() */ }; +const nv_alloc_ops_t spl_pushpage_ops_def = { + NULL, /* nv_ao_init() */ + NULL, /* nv_ao_fini() */ + nv_alloc_pushpage_spl, /* nv_ao_alloc() */ + nv_free_spl, /* nv_ao_free() */ + NULL /* nv_ao_reset() */ +}; + const nv_alloc_ops_t spl_nosleep_ops_def = { NULL, /* nv_ao_init() */ NULL, /* nv_ao_fini() */ @@ -66,10 +80,16 @@ nv_alloc_t nv_alloc_sleep_def = { NULL }; +nv_alloc_t nv_alloc_pushpage_def = { + &spl_pushpage_ops_def, + NULL +}; + nv_alloc_t nv_alloc_nosleep_def = { &spl_nosleep_ops_def, NULL }; nv_alloc_t *nv_alloc_sleep = &nv_alloc_sleep_def; +nv_alloc_t *nv_alloc_pushpage = &nv_alloc_pushpage_def; nv_alloc_t *nv_alloc_nosleep = &nv_alloc_nosleep_def; |