mm/memory.c: fix a huge pud insertion race during faulting
[linux-2.6-microblaze.git] / include / asm-generic / pgtable.h
index 3127f90..798ea36 100644 (file)
@@ -938,6 +938,31 @@ static inline int pud_trans_huge(pud_t pud)
 }
 #endif
 
+/* See pmd_none_or_trans_huge_or_clear_bad for discussion. */
+static inline int pud_none_or_trans_huge_or_dev_or_clear_bad(pud_t *pud)
+{
+       pud_t pudval = READ_ONCE(*pud);
+
+       if (pud_none(pudval) || pud_trans_huge(pudval) || pud_devmap(pudval))
+               return 1;
+       if (unlikely(pud_bad(pudval))) {
+               pud_clear_bad(pud);
+               return 1;
+       }
+       return 0;
+}
+
+/* See pmd_trans_unstable for discussion. */
+static inline int pud_trans_unstable(pud_t *pud)
+{
+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) &&                    \
+       defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD)
+       return pud_none_or_trans_huge_or_dev_or_clear_bad(pud);
+#else
+       return 0;
+#endif
+}
+
 #ifndef pmd_read_atomic
 static inline pmd_t pmd_read_atomic(pmd_t *pmdp)
 {