aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/mm.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/mm.h')
-rw-r--r--include/linux/mm.h30
1 files changed, 23 insertions, 7 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h
index f28f46eade6a..a0df4295e171 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
400static inline struct page *compound_head(struct page *page) 400static 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
758static inline int page_cpupid_xchg_last(struct page *page, int cpupid) 768static 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
763static inline int page_cpupid_last(struct page *page) 773static inline int page_cpupid_last(struct page *page)
@@ -766,7 +776,7 @@ static inline int page_cpupid_last(struct page *page)
766} 776}
767static inline void page_cpupid_reset_last(struct page *page) 777static 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
772static inline int page_cpupid_last(struct page *page) 782static inline int page_cpupid_last(struct page *page)
@@ -1477,9 +1487,15 @@ static inline void pgtable_page_dtor(struct page *page)
1477 1487
1478#if USE_SPLIT_PMD_PTLOCKS 1488#if USE_SPLIT_PMD_PTLOCKS
1479 1489
1490static struct page *pmd_to_page(pmd_t *pmd)
1491{
1492 unsigned long mask = ~(PTRS_PER_PMD * sizeof(pmd_t) - 1);
1493 return virt_to_page((void *)((unsigned long) pmd & mask));
1494}
1495
1480static inline spinlock_t *pmd_lockptr(struct mm_struct *mm, pmd_t *pmd) 1496static inline spinlock_t *pmd_lockptr(struct mm_struct *mm, pmd_t *pmd)
1481{ 1497{
1482 return ptlock_ptr(virt_to_page(pmd)); 1498 return ptlock_ptr(pmd_to_page(pmd));
1483} 1499}
1484 1500
1485static inline bool pgtable_pmd_page_ctor(struct page *page) 1501static inline bool pgtable_pmd_page_ctor(struct page *page)
@@ -1498,7 +1514,7 @@ static inline void pgtable_pmd_page_dtor(struct page *page)
1498 ptlock_free(page); 1514 ptlock_free(page);
1499} 1515}
1500 1516
1501#define pmd_huge_pte(mm, pmd) (virt_to_page(pmd)->pmd_huge_pte) 1517#define pmd_huge_pte(mm, pmd) (pmd_to_page(pmd)->pmd_huge_pte)
1502 1518
1503#else 1519#else
1504 1520