diff options
author | Chunwei Chen <[email protected]> | 2015-12-17 18:31:58 -0800 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2015-12-18 13:24:52 -0800 |
commit | b4ad50ac5f16de9220452f0da493e67c060d701b (patch) | |
tree | 2242714bb50ea85f87792f859d20bbfefcbc9f7c /module/spl | |
parent | 200366f23f1a16874d78a07936c5a33f2d488022 (diff) |
Use spl_fstrans_mark instead of memalloc_noio_save
For earlier versions of the kernel with memalloc_noio_save, it only turns
off __GFP_IO but leaves __GFP_FS untouched during direct reclaim. This
would cause threads to direct reclaim into ZFS and cause deadlock.
Instead, we should stick to using spl_fstrans_mark. Since we would
explicitly turn off both __GFP_IO and __GFP_FS before allocation, it
will work on every version of the kernel.
This impacts kernel versions 3.9-3.17, see upstream kernel commit
torvalds/linux@934f307 for reference.
Signed-off-by: Chunwei Chen <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Signed-off-by: Tim Chase <[email protected]>
Closes #515
Issue zfsonlinux/zfs#4111
Diffstat (limited to 'module/spl')
-rw-r--r-- | module/spl/spl-kmem-cache.c | 9 | ||||
-rw-r--r-- | module/spl/spl-kmem.c | 4 | ||||
-rw-r--r-- | module/spl/spl-taskq.c | 4 | ||||
-rw-r--r-- | module/spl/spl-vmem.c | 25 |
4 files changed, 5 insertions, 37 deletions
diff --git a/module/spl/spl-kmem-cache.c b/module/spl/spl-kmem-cache.c index 846d24300..e3edca5a0 100644 --- a/module/spl/spl-kmem-cache.c +++ b/module/spl/spl-kmem-cache.c @@ -201,7 +201,7 @@ kv_alloc(spl_kmem_cache_t *skc, int size, int flags) ASSERT(ISP2(size)); ptr = (void *)__get_free_pages(lflags, get_order(size)); } else { - ptr = spl_vmalloc(size, lflags | __GFP_HIGHMEM, PAGE_KERNEL); + ptr = __vmalloc(size, lflags | __GFP_HIGHMEM, PAGE_KERNEL); } /* Resulting allocated memory will be page aligned */ @@ -1156,15 +1156,10 @@ spl_cache_grow_work(void *data) spl_kmem_cache_t *skc = ska->ska_cache; spl_kmem_slab_t *sks; -#if defined(PF_MEMALLOC_NOIO) - unsigned noio_flag = memalloc_noio_save(); - sks = spl_slab_alloc(skc, ska->ska_flags); - memalloc_noio_restore(noio_flag); -#else fstrans_cookie_t cookie = spl_fstrans_mark(); sks = spl_slab_alloc(skc, ska->ska_flags); spl_fstrans_unmark(cookie); -#endif + spin_lock(&skc->skc_lock); if (sks) { skc->skc_slab_total++; diff --git a/module/spl/spl-kmem.c b/module/spl/spl-kmem.c index 92263f8f4..0931fdfcf 100644 --- a/module/spl/spl-kmem.c +++ b/module/spl/spl-kmem.c @@ -185,7 +185,7 @@ spl_kmem_alloc_impl(size_t size, int flags, int node) */ if ((size > spl_kmem_alloc_max) || use_vmem) { if (flags & KM_VMEM) { - ptr = spl_vmalloc(size, lflags, PAGE_KERNEL); + ptr = __vmalloc(size, lflags, PAGE_KERNEL); } else { return (NULL); } @@ -198,7 +198,7 @@ spl_kmem_alloc_impl(size_t size, int flags, int node) /* * For vmem_alloc() and vmem_zalloc() callers retry immediately - * using spl_vmalloc() which is unlikely to fail. + * using __vmalloc() which is unlikely to fail. */ if ((flags & KM_VMEM) && (use_vmem == 0)) { use_vmem = 1; diff --git a/module/spl/spl-taskq.c b/module/spl/spl-taskq.c index db5d8fba1..5f2b725c9 100644 --- a/module/spl/spl-taskq.c +++ b/module/spl/spl-taskq.c @@ -849,9 +849,7 @@ taskq_thread(void *args) tq = tqt->tqt_tq; current->flags |= PF_NOFREEZE; -#if defined(PF_MEMALLOC_NOIO) - (void) memalloc_noio_save(); -#endif + (void) spl_fstrans_mark(); sigfillset(&blocked); sigprocmask(SIG_BLOCK, &blocked, NULL); diff --git a/module/spl/spl-vmem.c b/module/spl/spl-vmem.c index bca27f263..e177988a7 100644 --- a/module/spl/spl-vmem.c +++ b/module/spl/spl-vmem.c @@ -97,31 +97,6 @@ spl_vmem_free(const void *buf, size_t size) } EXPORT_SYMBOL(spl_vmem_free); -/* - * Public vmalloc() interface designed to be safe to be called during I/O. - */ -void * -spl_vmalloc(unsigned long size, gfp_t lflags, pgprot_t prot) -{ -#if defined(PF_MEMALLOC_NOIO) - void *ptr; - unsigned noio_flag = 0; - - if (spl_fstrans_check()) - noio_flag = memalloc_noio_save(); - - ptr = __vmalloc(size, lflags, prot); - - if (spl_fstrans_check()) - memalloc_noio_restore(noio_flag); - - return (ptr); -#else - return (__vmalloc(size, lflags, prot)); -#endif -} -EXPORT_SYMBOL(spl_vmalloc); - int spl_vmem_init(void) { |