remove libdss from Makefile
[GitHub/moto-9609/android_kernel_motorola_exynos9610.git] / mm / migrate.c
index e00814ca390ea46dab6174e3c7c183e7bd4faf73..5d295c0c3bef06f4fce676e84aaa6cbb3f1cab93 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Memory Migration functionality - linux/mm/migrate.c
  *
@@ -246,10 +247,8 @@ static bool remove_migration_pte(struct page *page, struct vm_area_struct *vma,
                                pte = swp_entry_to_pte(entry);
                        } else if (is_device_public_page(new)) {
                                pte = pte_mkdevmap(pte);
-                               flush_dcache_page(new);
                        }
-               } else
-                       flush_dcache_page(new);
+               }
 
 #ifdef CONFIG_HUGETLB_PAGE
                if (PageHuge(new)) {
@@ -273,6 +272,9 @@ static bool remove_migration_pte(struct page *page, struct vm_area_struct *vma,
                if (vma->vm_flags & VM_LOCKED && !PageTransCompound(new))
                        mlock_vma_page(new);
 
+               if (PageTransHuge(page) && PageMlocked(page))
+                       clear_page_mlock(page);
+
                /* No need to invalidate - it was non-present before */
                update_mmu_cache(vma, pvmw.address, pvmw.pte);
        }
@@ -669,6 +671,8 @@ void migrate_page_states(struct page *newpage, struct page *page)
                SetPageActive(newpage);
        } else if (TestClearPageUnevictable(page))
                SetPageUnevictable(newpage);
+       if (PageWorkingset(page))
+               SetPageWorkingset(newpage);
        if (PageChecked(page))
                SetPageChecked(newpage);
        if (PageMappedToDisk(page))
@@ -967,6 +971,13 @@ static int move_to_new_page(struct page *newpage, struct page *page,
                 */
                if (!PageMappingFlags(page))
                        page->mapping = NULL;
+
+               if (unlikely(is_zone_device_page(newpage))) {
+                       if (is_device_public_page(newpage))
+                               flush_dcache_page(newpage);
+               } else
+                       flush_dcache_page(newpage);
+
        }
 out:
        return rc;
@@ -1102,10 +1113,13 @@ out:
         * If migration is successful, decrease refcount of the newpage
         * which will not free the page because new page owner increased
         * refcounter. As well, if it is LRU page, add the page to LRU
-        * list in here.
+        * list in here. Use the old state of the isolated source page to
+        * determine if we migrated a LRU page. newpage was already unlocked
+        * and possibly modified by its owner - don't rely on the page
+        * state.
         */
        if (rc == MIGRATEPAGE_SUCCESS) {
-               if (unlikely(__PageMovable(newpage)))
+               if (unlikely(!is_lru))
                        put_page(newpage);
                else
                        putback_lru_page(newpage);
@@ -1296,6 +1310,16 @@ static int unmap_and_move_huge_page(new_page_t get_new_page,
                lock_page(hpage);
        }
 
+       /*
+        * Check for pages which are in the process of being freed.  Without
+        * page_mapping() set, hugetlbfs specific move page routine will not
+        * be called and we could leak usage counts for subpools.
+        */
+       if (page_private(hpage) && !page_mapping(hpage)) {
+               rc = -EBUSY;
+               goto out_unlock;
+       }
+
        if (PageAnon(hpage))
                anon_vma = page_get_anon_vma(hpage);
 
@@ -1327,6 +1351,7 @@ put_anon:
                set_page_owner_migrate_reason(new_hpage, reason);
        }
 
+out_unlock:
        unlock_page(hpage);
 out:
        if (rc != -EAGAIN)
@@ -1405,6 +1430,17 @@ int migrate_pages(struct list_head *from, new_page_t get_new_page,
                                                private, page, pass > 2, mode,
                                                reason);
 
+                       if ((reason == MR_CMA) && (rc != -EAGAIN) &&
+                                               (rc != MIGRATEPAGE_SUCCESS)) {
+                               phys_addr_t pa = page_to_phys(page);
+
+                               pr_err("%s failed(%d): PA%pa,mapcnt%d,cnt%d\n",
+                                       __func__, rc, &pa,
+                                       page_mapcount(page), page_count(page));
+
+                               dump_page_owner(page);
+                       }
+
                        switch(rc) {
                        case -ENOMEM:
                                nr_failed++;