mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2025-01-12 19:20:28 +03:00
Disable vmalloc() direct reclaim
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
This commit is contained in:
parent
cb255ae572
commit
2092cf68d8
@ -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));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user