diff options
author | Alex Shi <alex.shi@linaro.org> | 2014-04-04 10:51:41 +0800 |
---|---|---|
committer | Alex Shi <alex.shi@linaro.org> | 2014-04-04 10:51:41 +0800 |
commit | 920553ba25498d26fbc7de610cdcf2f74d470ba0 (patch) | |
tree | 81d981168bbce09a7afda5b6780b72dc983ff1e5 /include | |
parent | f3124ba519b42426525585f50dbde3235b1fb89a (diff) | |
parent | 8f0c10ea2ec6e1086fbb73ff8bcbbf1ed8584b11 (diff) |
Merge tag 'v3.10.36' into linux-linaro-lsk
This is the 3.10.36 stable release
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/bitops.h | 15 | ||||
-rw-r--r-- | include/linux/huge_mm.h | 18 | ||||
-rw-r--r-- | include/linux/mm.h | 14 |
3 files changed, 27 insertions, 20 deletions
diff --git a/include/linux/bitops.h b/include/linux/bitops.h index a3b6b82108b..c1dde8e00d2 100644 --- a/include/linux/bitops.h +++ b/include/linux/bitops.h @@ -185,6 +185,21 @@ static inline unsigned long __ffs64(u64 word) #ifdef __KERNEL__ +#ifndef set_mask_bits +#define set_mask_bits(ptr, _mask, _bits) \ +({ \ + const typeof(*ptr) mask = (_mask), bits = (_bits); \ + typeof(*ptr) old, new; \ + \ + do { \ + old = ACCESS_ONCE(*ptr); \ + new = (old & ~mask) | bits; \ + } while (cmpxchg(ptr, old, new) != old); \ + \ + new; \ +}) +#endif + #ifndef find_last_bit /** * find_last_bit - find the last set bit in a memory region diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index 528454c2caa..a193bb3e413 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h @@ -159,23 +159,6 @@ static inline int hpage_nr_pages(struct page *page) return HPAGE_PMD_NR; return 1; } -static inline struct page *compound_trans_head(struct page *page) -{ - if (PageTail(page)) { - struct page *head; - head = page->first_page; - smp_rmb(); - /* - * head may be a dangling pointer. - * __split_huge_page_refcount clears PageTail before - * overwriting first_page, so if PageTail is still - * there it means the head pointer isn't dangling. - */ - if (PageTail(page)) - return head; - } - return page; -} extern int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, pmd_t pmd, pmd_t *pmdp); @@ -205,7 +188,6 @@ static inline int split_huge_page(struct page *page) do { } while (0) #define split_huge_page_pmd_mm(__mm, __address, __pmd) \ do { } while (0) -#define compound_trans_head(page) compound_head(page) static inline int hugepage_madvise(struct vm_area_struct *vma, unsigned long *vm_flags, int advice) { diff --git a/include/linux/mm.h b/include/linux/mm.h index 3bf21c3502d..a9a48309f04 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -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; } |