Merge branch 'for-4.2/writeback' of git://git.kernel.dk/linux-block
[firefly-linux-kernel-4.4.55.git] / mm / rmap.c
index 8fc556ce2dcb7f538c81a7c590c769d9da34aa6a..171b68768df1478355bcddd5e30c2edd616ba05b 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -627,7 +627,7 @@ pmd_t *mm_find_pmd(struct mm_struct *mm, unsigned long address)
 
        pmd = pmd_offset(pud, address);
        /*
-        * Some THP functions use the sequence pmdp_clear_flush(), set_pmd_at()
+        * Some THP functions use the sequence pmdp_huge_clear_flush(), set_pmd_at()
         * without holding anon_vma lock for write.  So when looking for a
         * genuine pmde (in which to find pte), test present and !THP together.
         */
@@ -952,7 +952,12 @@ void page_move_anon_rmap(struct page *page,
        VM_BUG_ON_PAGE(page->index != linear_page_index(vma, address), page);
 
        anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON;
-       page->mapping = (struct address_space *) anon_vma;
+       /*
+        * Ensure that anon_vma and the PAGE_MAPPING_ANON bit are written
+        * simultaneously, so a concurrent reader (eg page_referenced()'s
+        * PageAnon()) will not see one without the other.
+        */
+       WRITE_ONCE(page->mapping, (struct address_space *) anon_vma);
 }
 
 /**