diff options
author | Brian Behlendorf <[email protected]> | 2012-12-10 11:01:08 -0800 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2012-12-12 09:56:54 -0800 |
commit | 296a8e596dac344cf3af5e7f2dff5be12c979d80 (patch) | |
tree | ab570d57ac45da745cb133921391fe8b76d438d1 | |
parent | a5a98e72605c071f94b9fdc4bf1811f8ed8d7f32 (diff) |
kmem-cache: spl_kmem_cache_create() may always sleep
When this code was originally written I went overboard and allowed
for the possibility of creating a cache in an atomic context. In
practice there are no callers which ever do this. This makes sense
since a cache is by design a long lived data structure.
To prevent abuse of this function going forward I'm removing the
code which is supported to handle an atomic context. All allocators
have been updated to use KM_SLEEP and the might_sleep() debug macro
has been added to immediately detect atomic callers.
Signed-off-by: Brian Behlendorf <[email protected]>
-rw-r--r-- | module/spl/spl-kmem.c | 19 |
1 files changed, 8 insertions, 11 deletions
diff --git a/module/spl/spl-kmem.c b/module/spl/spl-kmem.c index b171d446a..f78f820aa 100644 --- a/module/spl/spl-kmem.c +++ b/module/spl/spl-kmem.c @@ -1482,7 +1482,7 @@ spl_kmem_cache_create(char *name, size_t size, size_t align, void *priv, void *vmp, int flags) { spl_kmem_cache_t *skc; - int rc, kmem_flags = KM_SLEEP; + int rc; SENTRY; ASSERTF(!(flags & KMC_NOMAGAZINE), "Bad KMC_NOMAGAZINE (%x)\n", flags); @@ -1490,25 +1490,22 @@ spl_kmem_cache_create(char *name, size_t size, size_t align, ASSERTF(!(flags & KMC_QCACHE), "Bad KMC_QCACHE (%x)\n", flags); ASSERT(vmp == NULL); - /* We may be called when there is a non-zero preempt_count or - * interrupts are disabled is which case we must not sleep. - */ - if (current_thread_info()->preempt_count || irqs_disabled()) - kmem_flags = KM_NOSLEEP; + might_sleep(); - /* Allocate memory for a new cache an initialize it. Unfortunately, + /* + * Allocate memory for a new cache an initialize it. Unfortunately, * this usually ends up being a large allocation of ~32k because * we need to allocate enough memory for the worst case number of * cpus in the magazine, skc_mag[NR_CPUS]. Because of this we - * explicitly pass KM_NODEBUG to suppress the kmem warning */ - skc = (spl_kmem_cache_t *)kmem_zalloc(sizeof(*skc), - kmem_flags | KM_NODEBUG); + * explicitly pass KM_NODEBUG to suppress the kmem warning + */ + skc = kmem_zalloc(sizeof(*skc), KM_SLEEP| KM_NODEBUG); if (skc == NULL) SRETURN(NULL); skc->skc_magic = SKC_MAGIC; skc->skc_name_size = strlen(name) + 1; - skc->skc_name = (char *)kmem_alloc(skc->skc_name_size, kmem_flags); + skc->skc_name = (char *)kmem_alloc(skc->skc_name_size, KM_SLEEP); if (skc->skc_name == NULL) { kmem_free(skc, sizeof(*skc)); SRETURN(NULL); |