From 7cf5ad81641214d2c4bb6404b64436a787791749 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 13 Oct 2020 11:00:33 -0700 Subject: [PATCH 3/3] mm: do_cow_fault() does not need the source page to be locked This removes the "lock if it wasn't locked" logic from do_cow_fault(), since we're not even going to install that page into the destination address space (finish_fault() will use ->cow_page rather than ->page), and copying the source page does not need the source to be locked. So instead of doing "lock if it wasn't locked" followed by an unconditional unlock of the page, just do "unlock if it was locked". Of course, since all the normal file mapping ->fault() handlers currently lock the page they return (see filemap_fault() for details), all of this is pretty much theoretical. But this is the right thing to do - making sure we hold the page lock when we really don't is just confusing and wrong. And this prepares the way for any future changes to filemap_fault() where we go "Oh, we actually _don't_ need to lock the page for this case at all". Signed-off-by: Linus Torvalds --- mm/memory.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/mm/memory.c b/mm/memory.c index d7e30273bef1..44653b5b2af6 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -3971,16 +3971,13 @@ static vm_fault_t do_cow_fault(struct vm_fault *vmf) if (ret & VM_FAULT_DONE_COW) return ret; - if (unlikely(!(ret & VM_FAULT_LOCKED))) - lock_page(vmf->page); - else - VM_BUG_ON_PAGE(!PageLocked(vmf->page), vmf->page); - copy_user_highpage(vmf->cow_page, vmf->page, vmf->address, vma); __SetPageUptodate(vmf->cow_page); + if (ret & VM_FAULT_LOCKED) + unlock_page(vmf->page); + ret |= finish_fault(vmf); - unlock_page(vmf->page); put_page(vmf->page); if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE | VM_FAULT_RETRY))) goto uncharge_out; -- 2.30.0.352.gf6a05684e6