mm: close PageTail race
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / include / linux / mm.h
index 3bf21c3502d0074fc9fb552d33a165babef7c963..a9a48309f0458aa8faf408dc06edf9a623d9c5c4 100644 (file)
@@ -361,8 +361,18 @@ static inline void compound_unlock_irqrestore(struct page *page,
 
 static inline struct page *compound_head(struct page *page)
 {
-       if (unlikely(PageTail(page)))
-               return page->first_page;
+       if (unlikely(PageTail(page))) {
+               struct page *head = page->first_page;
+
+               /*
+                * page->first_page may be a dangling pointer to an old
+                * compound page, so recheck that it is still a tail
+                * page before returning.
+                */
+               smp_rmb();
+               if (likely(PageTail(page)))
+                       return head;
+       }
        return page;
 }