aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorAlex Shi <alex.shi@linaro.org>2014-04-04 10:51:41 +0800
committerAlex Shi <alex.shi@linaro.org>2014-04-04 10:51:41 +0800
commit920553ba25498d26fbc7de610cdcf2f74d470ba0 (patch)
tree81d981168bbce09a7afda5b6780b72dc983ff1e5 /include
parentf3124ba519b42426525585f50dbde3235b1fb89a (diff)
parent8f0c10ea2ec6e1086fbb73ff8bcbbf1ed8584b11 (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.h15
-rw-r--r--include/linux/huge_mm.h18
-rw-r--r--include/linux/mm.h14
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;
}