]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - mm/migrate.c
Merge tag 'driver-core-4.13-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git...
[karo-tx-linux.git] / mm / migrate.c
index 051cc1555d36e34f4734a7e54faac1a6c2fe144c..d68a41da6abb0743d6b09cc49c5c9524463715c3 100644 (file)
@@ -1252,6 +1252,8 @@ put_anon:
 out:
        if (rc != -EAGAIN)
                putback_active_hugepage(hpage);
+       if (reason == MR_MEMORY_FAILURE && !test_set_page_hwpoison(hpage))
+               num_poisoned_pages_inc();
 
        /*
         * If migration was not successful and there's a freeing callback, use
@@ -1914,7 +1916,6 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm,
        int page_lru = page_is_file_cache(page);
        unsigned long mmun_start = address & HPAGE_PMD_MASK;
        unsigned long mmun_end = mmun_start + HPAGE_PMD_SIZE;
-       pmd_t orig_entry;
 
        /*
         * Rate-limit the amount of data that is being migrated to a node.
@@ -1936,12 +1937,6 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm,
                put_page(new_page);
                goto out_fail;
        }
-       /*
-        * We are not sure a pending tlb flush here is for a huge page
-        * mapping or not. Hence use the tlb range variant
-        */
-       if (mm_tlb_flush_pending(mm))
-               flush_tlb_range(vma, mmun_start, mmun_end);
 
        /* Prepare a page as a migration target */
        __SetPageLocked(new_page);
@@ -1957,8 +1952,7 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm,
        /* Recheck the target PMD */
        mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
        ptl = pmd_lock(mm, pmd);
-       if (unlikely(!pmd_same(*pmd, entry) || page_count(page) != 2)) {
-fail_putback:
+       if (unlikely(!pmd_same(*pmd, entry) || !page_ref_freeze(page, 2))) {
                spin_unlock(ptl);
                mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
 
@@ -1980,7 +1974,6 @@ fail_putback:
                goto out_unlock;
        }
 
-       orig_entry = *pmd;
        entry = mk_huge_pmd(new_page, vma->vm_page_prot);
        entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma);
 
@@ -1997,15 +1990,7 @@ fail_putback:
        set_pmd_at(mm, mmun_start, pmd, entry);
        update_mmu_cache_pmd(vma, address, &entry);
 
-       if (page_count(page) != 2) {
-               set_pmd_at(mm, mmun_start, pmd, orig_entry);
-               flush_pmd_tlb_range(vma, mmun_start, mmun_end);
-               mmu_notifier_invalidate_range(mm, mmun_start, mmun_end);
-               update_mmu_cache_pmd(vma, address, &entry);
-               page_remove_rmap(new_page, true);
-               goto fail_putback;
-       }
-
+       page_ref_unfreeze(page, 2);
        mlock_migrate_page(new_page, page);
        page_remove_rmap(page, true);
        set_page_owner_migrate_reason(new_page, MR_NUMA_MISPLACED);