powerpc/64s: Fix page table fragment refcount race vs speculative references
[linux-2.6-block.git] / arch / powerpc / mm / mmu_context_book3s64.c
index 8b24168ea8c436cbea406186138b55c0bbd45d8d..4a892d894a0f1b2d96ed319ab0f4a622104c7526 100644 (file)
@@ -200,9 +200,9 @@ static void pte_frag_destroy(void *pte_frag)
        /* drop all the pending references */
        count = ((unsigned long)pte_frag & ~PAGE_MASK) >> PTE_FRAG_SIZE_SHIFT;
        /* We allow PTE_FRAG_NR fragments from a PTE page */
-       if (page_ref_sub_and_test(page, PTE_FRAG_NR - count)) {
+       if (atomic_sub_and_test(PTE_FRAG_NR - count, &page->pt_frag_refcount)) {
                pgtable_page_dtor(page);
-               free_unref_page(page);
+               __free_page(page);
        }
 }
 
@@ -215,9 +215,9 @@ static void pmd_frag_destroy(void *pmd_frag)
        /* drop all the pending references */
        count = ((unsigned long)pmd_frag & ~PAGE_MASK) >> PMD_FRAG_SIZE_SHIFT;
        /* We allow PTE_FRAG_NR fragments from a PTE page */
-       if (page_ref_sub_and_test(page, PMD_FRAG_NR - count)) {
+       if (atomic_sub_and_test(PMD_FRAG_NR - count, &page->pt_frag_refcount)) {
                pgtable_pmd_page_dtor(page);
-               free_unref_page(page);
+               __free_page(page);
        }
 }