From: Oleg Drokin Date: Mon, 12 Oct 2020 20:10:15 +0000 (-0400) Subject: LU-13182 llite: Avoid eternel retry loops with MAP_POPULATE X-Git-Tag: 2.13.57~91 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=bb50c62c6f4cdd7a31145ab81e7c166e0760ed11;ds=sidebyside LU-13182 llite: Avoid eternel retry loops with MAP_POPULATE Kernels 5.4+ have an infinite retry loop from MAP_POPULATE mmap option. Use the FAULT_FLAG_RETRY_NOWAIT to instruct filemap_fault to not drop the mmap_sem so if the call fails, we could use the slow path and break the loop from forming. (Idea by Neil Brown) Test-Parameters: testlist=sanity-hsm env=ONLY=1 clientdistro=ubuntu2004 Change-Id: I320ab9ca447282aea15ef2030ef8671c4260d895 Signed-off-by: Oleg Drokin Reviewed-on: https://review.whamcloud.com/40221 Reviewed-by: Neil Brown Tested-by: jenkins Reviewed-by: James Simmons Tested-by: Maloo --- diff --git a/lustre/llite/llite_mmap.c b/lustre/llite/llite_mmap.c index f3fd0a2..242f4f4 100644 --- a/lustre/llite/llite_mmap.c +++ b/lustre/llite/llite_mmap.c @@ -280,16 +280,22 @@ static vm_fault_t ll_fault0(struct vm_area_struct *vma, struct vm_fault *vmf) if (ll_sbi_has_fast_read(ll_i2sbi(file_inode(vma->vm_file)))) { /* do fast fault */ + bool has_retry = vmf->flags & FAULT_FLAG_RETRY_NOWAIT; + + /* To avoid loops, instruct downstream to not drop mmap_sem */ + vmf->flags |= FAULT_FLAG_RETRY_NOWAIT; ll_cl_add(vma->vm_file, env, NULL, LCC_MMAP); fault_ret = ll_filemap_fault(vma, vmf); ll_cl_remove(vma->vm_file, env); + if (!has_retry) + vmf->flags &= ~FAULT_FLAG_RETRY_NOWAIT; /* - If there is no error, then the page was found in cache and * uptodate; * - If VM_FAULT_RETRY is set, the page existed but failed to - * lock. It will return to kernel and retry; + * lock. We will try slow path to avoid loops. * - Otherwise, it should try normal fault under DLM lock. */ - if ((fault_ret & VM_FAULT_RETRY) || + if (!(fault_ret & VM_FAULT_RETRY) && !(fault_ret & VM_FAULT_ERROR)) GOTO(out, result = 0);