Whamcloud - gitweb
LU-14713 llite: tighten condition for fault not drop mmap_sem
authorBobi Jam <bobijam@whamcloud.com>
Wed, 26 Jan 2022 19:05:55 +0000 (14:05 -0500)
committerAndreas Dilger <adilger@whamcloud.com>
Tue, 1 Feb 2022 08:26:14 +0000 (08:26 +0000)
As __lock_page_or_retry() indicates, filemap_fault() will return
VM_FAULT_RETRY without releasing mmap_sem iff flags contains
FAULT_FLAG_ALLOW_RETRY and FAULT_FLAG_RETRY_NOWAIT.

So ll_fault0() should pass in FAULT_FLAG_ALLOW_RETRY |
FAULT_FLAG_RETRY_NOWAIT in ll_filemap_fault() so that when it
returns VM_FAULT_RETRY, we can pass on trying normal fault
under DLM lock as mmap_sem is still being held.

While in Linux 5.1 (6b4c9f4469819) FAULT_FLAG_RETRY_NOWAIT is enough
to not drop mmap_sem when failed to lock the page.

Lustre-change: https://review.whamcloud.com/44715
Lustre-commit: 81aec05103558f57adb10fd319847304cdf44aa7

Fixes: 87865e4ae9 ("LU-13182 llite: Avoid eternel retry loops with MAP_POPULATE")
Signed-off-by: Bobi Jam <bobijam@whamcloud.com>
Change-Id: I9420c587301722b597155558657577349a8141e4
Reviewed-on: https://review.whamcloud.com/46322
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: Bobi Jam <bobijam@hotmail.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
lustre/llite/llite_mmap.c

index d263346..c16404c 100644 (file)
@@ -279,15 +279,23 @@ static vm_fault_t ll_fault0(struct vm_area_struct *vma, struct vm_fault *vmf)
 
        if (ll_sbi_has_fast_read(ll_i2sbi(inode))) {
                /* do fast fault */
+               bool allow_retry = vmf->flags & FAULT_FLAG_ALLOW_RETRY;
                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;
+               /**
+                * only need FAULT_FLAG_ALLOW_RETRY prior to Linux 5.1
+                * (6b4c9f4469819), where FAULT_FLAG_RETRY_NOWAIT is enough
+                * to not drop mmap_sem when failed to lock the page.
+                */
+               vmf->flags |= FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_RETRY_NOWAIT;
                ll_cl_add(inode, env, NULL, LCC_MMAP);
                fault_ret = ll_filemap_fault(vma, vmf);
                ll_cl_remove(inode, env);
                if (!has_retry)
                        vmf->flags &= ~FAULT_FLAG_RETRY_NOWAIT;
+               if (!allow_retry)
+                       vmf->flags &= ~FAULT_FLAG_ALLOW_RETRY;
 
                /* - If there is no error, then the page was found in cache and
                 *   uptodate;