Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
[cascardo/linux.git] / mm / huge_memory.c
index 5b2c687..817a875 100644 (file)
@@ -804,7 +804,7 @@ int do_huge_pmd_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
                return VM_FAULT_OOM;
        if (unlikely(khugepaged_enter(vma, vma->vm_flags)))
                return VM_FAULT_OOM;
-       if (!(flags & FAULT_FLAG_WRITE) &&
+       if (!(flags & FAULT_FLAG_WRITE) && !mm_forbids_zeropage(mm) &&
                        transparent_hugepage_use_zero_page()) {
                spinlock_t *ptl;
                pgtable_t pgtable;
@@ -1035,7 +1035,7 @@ static int do_huge_pmd_wp_page_fallback(struct mm_struct *mm,
                goto out_free_pages;
        VM_BUG_ON_PAGE(!PageHead(page), page);
 
-       pmdp_clear_flush(vma, haddr, pmd);
+       pmdp_clear_flush_notify(vma, haddr, pmd);
        /* leave pmd empty until pte is filled */
 
        pgtable = pgtable_trans_huge_withdraw(mm, pmd);
@@ -1178,7 +1178,7 @@ alloc:
                pmd_t entry;
                entry = mk_huge_pmd(new_page, vma->vm_page_prot);
                entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma);
-               pmdp_clear_flush(vma, haddr, pmd);
+               pmdp_clear_flush_notify(vma, haddr, pmd);
                page_add_new_anon_rmap(new_page, vma, haddr);
                mem_cgroup_commit_charge(new_page, memcg, false);
                lru_cache_add_active_or_unevictable(new_page, vma);
@@ -1399,7 +1399,8 @@ int zap_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
                 * pgtable_trans_huge_withdraw after finishing pmdp related
                 * operations.
                 */
-               orig_pmd = pmdp_get_and_clear(tlb->mm, addr, pmd);
+               orig_pmd = pmdp_get_and_clear_full(tlb->mm, addr, pmd,
+                                                  tlb->fullmm);
                tlb_remove_pmd_tlb_entry(tlb, pmd, addr);
                pgtable = pgtable_trans_huge_withdraw(tlb->mm, pmd);
                if (is_huge_zero_pmd(orig_pmd)) {
@@ -1511,7 +1512,7 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
                pmd_t entry;
                ret = 1;
                if (!prot_numa) {
-                       entry = pmdp_get_and_clear(mm, addr, pmd);
+                       entry = pmdp_get_and_clear_notify(mm, addr, pmd);
                        if (pmd_numa(entry))
                                entry = pmd_mknonnuma(entry);
                        entry = pmd_modify(entry, newprot);
@@ -1643,6 +1644,7 @@ static int __split_huge_page_splitting(struct page *page,
                 * serialize against split_huge_page*.
                 */
                pmdp_splitting_flush(vma, address, pmd);
+
                ret = 1;
                spin_unlock(ptl);
        }
@@ -2833,7 +2835,7 @@ static void __split_huge_zero_page_pmd(struct vm_area_struct *vma,
        pmd_t _pmd;
        int i;
 
-       pmdp_clear_flush(vma, haddr, pmd);
+       pmdp_clear_flush_notify(vma, haddr, pmd);
        /* leave pmd empty until pte is filled */
 
        pgtable = pgtable_trans_huge_withdraw(mm, pmd);