FAILED: patch "[PATCH] NFS: Use GFP_NOIO for two allocations in writeback" failed to apply to 4.4-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
Quoted 1 line
From
ae97aa524ef495b6276fd26f5d5449fb22975d7cMon Sep 17 00:00:00 2001
From: Benjamin Coddington <[email protected]>
Date: Wed, 19 Apr 2017 10:11:33 -0400
Subject: [PATCH] NFS: Use GFP_NOIO for two allocations in writeback
Prevent a deadlock that can occur if we wait on allocations that try to write back our pages.
Signed-off-by Benjamin Coddington <[email protected]>
Fixes 00bfa30abe869 ("NFS: Create a common pgio_alloc and pgio_release...")
Cc [email protected] # 3.16+
Signed-off-by Trond Myklebust <[email protected]>
fs/nfs/pagelist.c +11 -4
@@ -29,13 +29,14 @@static struct kmem_cache *nfs_page_cachep;static const struct rpc_call_ops nfs_pgio_common_ops; -static bool nfs_pgarray_set (struct nfs_page_array *p,unsigned int pagecount) +static bool nfs_pgarray_set (struct nfs_page_array *p,unsigned int pagecount, +gfp_t gfp_flags) { p->npages = pagecount;if (pagecount <=ARRAY_SIZE (p->page_array)) p->pagevec = p->page_array;else { - p->pagevec =kcalloc (pagecount,sizeof (struct page *),GFP_KERNEL ); + p->pagevec =kcalloc (pagecount,sizeof (struct page *), gfp_flags);if (!p->pagevec) p->npages =0 ; }
@@ -681,6 +682,7 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc, {struct nfs_pgio_mirror *new;int i; +gfp_t gfp_flags =GFP_KERNEL ; desc->pg_moreio =0 ; desc->pg_inode = inode;
@@ -700,8 +702,10 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc,if (pg_ops->pg_get_mirror_count) {/* until we have a request, we don't have an lseg and no * idea how many mirrors there will be */ +if (desc->pg_rw_ops->rw_mode ==FMODE_WRITE ) + gfp_flags =GFP_NOIO ; new =kcalloc (NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX , -sizeof (struct nfs_pgio_mirror ),GFP_KERNEL ); +sizeof (struct nfs_pgio_mirror ), gfp_flags); desc->pg_mirrors_dynamic = new; desc->pg_mirrors = new;
@@ -755,9 +759,12 @@ int nfs_generic_pgio(struct nfs_pageio_descriptor *desc,struct list_head *head = &mirror->pg_list;struct nfs_commit_info cinfo;unsigned int pagecount, pageused; +gfp_t gfp_flags =GFP_KERNEL ; pagecount =nfs_page_array_len (mirror->pg_base, mirror->pg_count); -if (!nfs_pgarray_set (&hdr->page_array, pagecount)) { +if (desc->pg_rw_ops->rw_mode ==FMODE_WRITE ) + gfp_flags =GFP_NOIO ; +if (!nfs_pgarray_set (&hdr->page_array, pagecount, gfp_flags)) {nfs_pgio_error (hdr); desc->pg_error = -ENOMEM ;return desc->pg_error;