diff options
Diffstat (limited to 'include/linux/mm.h')
-rw-r--r-- | include/linux/mm.h | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h index f28f46eade6a..c1b7414c7bef 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -175,7 +175,7 @@ extern unsigned int kobjsize(const void *objp); | |||
175 | * Special vmas that are non-mergable, non-mlock()able. | 175 | * Special vmas that are non-mergable, non-mlock()able. |
176 | * Note: mm/huge_memory.c VM_NO_THP depends on this definition. | 176 | * Note: mm/huge_memory.c VM_NO_THP depends on this definition. |
177 | */ | 177 | */ |
178 | #define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_PFNMAP) | 178 | #define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_PFNMAP | VM_MIXEDMAP) |
179 | 179 | ||
180 | /* | 180 | /* |
181 | * mapping from the currently active vm_flags protection bits (the | 181 | * mapping from the currently active vm_flags protection bits (the |
@@ -399,8 +399,18 @@ static inline void compound_unlock_irqrestore(struct page *page, | |||
399 | 399 | ||
400 | static inline struct page *compound_head(struct page *page) | 400 | static inline struct page *compound_head(struct page *page) |
401 | { | 401 | { |
402 | if (unlikely(PageTail(page))) | 402 | if (unlikely(PageTail(page))) { |
403 | return page->first_page; | 403 | struct page *head = page->first_page; |
404 | |||
405 | /* | ||
406 | * page->first_page may be a dangling pointer to an old | ||
407 | * compound page, so recheck that it is still a tail | ||
408 | * page before returning. | ||
409 | */ | ||
410 | smp_rmb(); | ||
411 | if (likely(PageTail(page))) | ||
412 | return head; | ||
413 | } | ||
404 | return page; | 414 | return page; |
405 | } | 415 | } |
406 | 416 | ||
@@ -757,7 +767,7 @@ static inline bool __cpupid_match_pid(pid_t task_pid, int cpupid) | |||
757 | #ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS | 767 | #ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS |
758 | static inline int page_cpupid_xchg_last(struct page *page, int cpupid) | 768 | static inline int page_cpupid_xchg_last(struct page *page, int cpupid) |
759 | { | 769 | { |
760 | return xchg(&page->_last_cpupid, cpupid); | 770 | return xchg(&page->_last_cpupid, cpupid & LAST_CPUPID_MASK); |
761 | } | 771 | } |
762 | 772 | ||
763 | static inline int page_cpupid_last(struct page *page) | 773 | static inline int page_cpupid_last(struct page *page) |
@@ -766,7 +776,7 @@ static inline int page_cpupid_last(struct page *page) | |||
766 | } | 776 | } |
767 | static inline void page_cpupid_reset_last(struct page *page) | 777 | static inline void page_cpupid_reset_last(struct page *page) |
768 | { | 778 | { |
769 | page->_last_cpupid = -1; | 779 | page->_last_cpupid = -1 & LAST_CPUPID_MASK; |
770 | } | 780 | } |
771 | #else | 781 | #else |
772 | static inline int page_cpupid_last(struct page *page) | 782 | static inline int page_cpupid_last(struct page *page) |