mm: Drop Google's picks and put do_wp_page back in line with stable backups/20240517-1949/lineage-21
authorKevin F. Haggerty <haggertk@lineageos.org>
Fri, 19 Aug 2022 20:53:18 +0000 (14:53 -0600)
committerNolen Johnson <johnsonnolen@gmail.com>
Mon, 29 Apr 2024 05:30:22 +0000 (01:30 -0400)
This causes TEEGRIS to crash out and die. The user-visible result is
that the lockscreen pin is claimed to be incorrect, making the tablet
unusable. The device may be unlocked once upon boot, if done quickly
enough, but not after relocking or sitting long enough after boot.

This is a squash of:
* Revert "UPSTREAM: mm: reuse only-pte-mapped KSM page in do_wp_page()"
  This reverts commit 2b438ad3d5bad3d42b772d79f1aed4e143fe4c75.
* Revert "UPSTREAM: mm/ksm: Remove reuse_ksm_page()"
  This reverts commit e374fe2602945f563e12ba9e3276f196523a4802.
* Revert "BACKPORT: mm: do_wp_page() simplification"
  This reverts commit 32c2bf987549e56f11784b194a33b091fa3bc482.
* Revert "UPSTREAM: mm: fix misplaced unlock_page in do_wp_page()"
  This reverts commit ecff1109d781e1ef07f5b63658ce9429a0948f07.

Signed-off-by: Kevin F. Haggerty <haggertk@lineageos.org>
Change-Id: I83980aea81a0b667068acdf6ffc7d698ff1d51bf

mm/ksm.c
mm/memory.c

index 2f0c9b2221f26f9f93adc836f3e47af0168bddd6..6d3bc2723c9b3d8ce548593a7963cd68342ff31d 100644 (file)
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -695,9 +695,8 @@ again:
         * case this node is no longer referenced, and should be freed;
         * however, it might mean that the page is under page_freeze_refs().
         * The __remove_mapping() case is easy, again the node is now stale;
-        * the same is in reuse_ksm_page() case; but if page is swapcache
-        * in migrate_page_move_mapping(), it might still be our page,
-        * in which case it's essential to keep the node.
+        * but if page is swapcache in migrate_page_move_mapping(), it might
+        * still be our page, in which case it's essential to keep the node.
         */
        while (!get_page_unless_zero(page)) {
                /*
index d913d78a08c0bb6b9e1d076e99bbbc6b6e1aa2da..222c8d9753521840cb3f440f9abbd2944db16d49 100644 (file)
@@ -2876,31 +2876,43 @@ static int do_wp_page(struct vm_fault *vmf)
         * Take out anonymous pages first, anonymous shared vmas are
         * not dirty accountable.
         */
-       if (PageAnon(vmf->page)) {
-               struct page *page = vmf->page;
-
-               /* PageKsm() doesn't necessarily raise the page refcount */
-               if (PageKsm(page) || page_count(page) != 1)
-                       goto copy;
-               if (!trylock_page(page))
-                       goto copy;
-               if (PageKsm(page) || page_mapcount(page) != 1 || page_count(page) != 1) {
-                       unlock_page(page);
-                       goto copy;
+       if (PageAnon(vmf->page) && !PageKsm(vmf->page)) {
+               int total_map_swapcount;
+               if (!trylock_page(vmf->page)) {
+                       get_page(vmf->page);
+                       pte_unmap_unlock(vmf->pte, vmf->ptl);
+                       lock_page(vmf->page);
+                       vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd,
+                                       vmf->address, &vmf->ptl);
+                       if (!pte_same(*vmf->pte, vmf->orig_pte)) {
+                               unlock_page(vmf->page);
+                               pte_unmap_unlock(vmf->pte, vmf->ptl);
+                               put_page(vmf->page);
+                               return 0;
+                       }
+                       put_page(vmf->page);
                }
-               /*
-                * Ok, we've got the only map reference, and the only
-                * page count reference, and the page is locked,
-                * it's dark out, and we're wearing sunglasses. Hit it.
-                */
-               unlock_page(page);
-               wp_page_reuse(vmf);
-               return VM_FAULT_WRITE;
+               if (reuse_swap_page(vmf->page, &total_map_swapcount)) {
+                       if (total_map_swapcount == 1) {
+                               /*
+                                * The page is all ours. Move it to
+                                * our anon_vma so the rmap code will
+                                * not search our parent or siblings.
+                                * Protected against the rmap code by
+                                * the page lock.
+                                */
+                               page_move_anon_rmap(vmf->page, vma);
+                       }
+                       unlock_page(vmf->page);
+                       wp_page_reuse(vmf);
+                       return VM_FAULT_WRITE;
+               }
+               unlock_page(vmf->page);
        } else if (unlikely((vma->vm_flags & (VM_WRITE|VM_SHARED)) ==
                                        (VM_WRITE|VM_SHARED))) {
                return wp_page_shared(vmf);
        }
-copy:
+
        /*
         * Ok, we need to copy. Oh, well..
         */