Skip to content
This repository has been archived by the owner on Feb 26, 2020. It is now read-only.

Commit

Permalink
Disable vmalloc() direct reclaim
Browse files Browse the repository at this point in the history
As part of vmalloc() a __pte_alloc_kernel() allocation may occur.  This
internal allocation does not honor the gfp flags passed to vmalloc().
This means even when vmalloc(GFP_NOFS) is called it is possible that a
synchronous reclaim will occur.  This reclaim can trigger file IO which
can result in a deadlock.  This issue can be avoided by explicitly
setting PF_MEMALLOC on the process to subvert synchronous reclaim when
vmalloc() is called with !__GFP_FS.

An example stack of the deadlock can be found here (1), along with the
upstream kernel bug (2), and the original bug discussion on the
linux-mm mailing list (3).  This code can be properly autoconf'ed
when the upstream bug is fixed.

1) http://github.com/behlendorf/zfs/issues/labels/Vmalloc#issue/133
2) http://bugzilla.kernel.org/show_bug.cgi?id=30702
3) http://marc.info/?l=linux-mm&m=128942194520631&w=4
  • Loading branch information
behlendorf committed Mar 20, 2011
1 parent cb255ae commit 2092cf6
Showing 1 changed file with 22 additions and 2 deletions.
24 changes: 22 additions & 2 deletions module/spl/spl-kmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -842,11 +842,31 @@ kv_alloc(spl_kmem_cache_t *skc, int size, int flags)

ASSERT(ISP2(size));

if (skc->skc_flags & KMC_KMEM)
if (skc->skc_flags & KMC_KMEM) {
ptr = (void *)__get_free_pages(flags, get_order(size));
else
} else {
/*
* As part of vmalloc() an __pte_alloc_kernel() allocation
* may occur. This internal allocation does not honor the
* gfp flags passed to vmalloc(). This means even when
* vmalloc(GFP_NOFS) is called it is possible synchronous
* reclaim will occur. This reclaim can trigger file IO
* which can result in a deadlock. This issue can be avoided
* by explicitly setting PF_MEMALLOC on the process to
* subvert synchronous reclaim. The following bug has
* been filed at kernel.org to track the issue.
*
* https://bugzilla.kernel.org/show_bug.cgi?id=30702
*/
if (!(flags & __GFP_FS))
current->flags |= PF_MEMALLOC;

ptr = __vmalloc(size, flags | __GFP_HIGHMEM, PAGE_KERNEL);

if (!(flags & __GFP_FS))
current->flags &= ~PF_MEMALLOC;
}

/* Resulting allocated memory will be page aligned */
ASSERT(IS_P2ALIGNED(ptr, PAGE_SIZE));

Expand Down

0 comments on commit 2092cf6

Please sign in to comment.