diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-03-04 11:29:39 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-03-04 11:29:39 -0500 |
| commit | 3f803abf2e49fe18aaeff9532afc353e68e689c7 (patch) | |
| tree | e91cad0816d9ce7f959b0d1b5d96e144970d9bfa /include/linux | |
| parent | 0c0bd34a142963ca3454f530e47ce1c230d8cc9d (diff) | |
| parent | 27329369c9ecf37771b2a65202cbf5578cff3331 (diff) | |
Merge branch 'akpm' (patches from Andrew Morton)
Merge misc fixes from Andrew Morton.
* emailed patches from Andrew Morton akpm@linux-foundation.org>:
mm: page_alloc: exempt GFP_THISNODE allocations from zone fairness
mm: numa: bugfix for LAST_CPUPID_NOT_IN_PAGE_FLAGS
MAINTAINERS: add and correct types of some "T:" entries
MAINTAINERS: use tab for separator
rapidio/tsi721: fix tasklet termination in dma channel release
hfsplus: fix remount issue
zram: avoid null access when fail to alloc meta
sh: prefix sh-specific "CCR" and "CCR2" by "SH_"
ocfs2: fix quota file corruption
drivers/rtc/rtc-s3c.c: fix incorrect way of save/restore of S3C2410_TICNT for TYPE_S3C64XX
kallsyms: fix absolute addresses for kASLR
scripts/gen_initramfs_list.sh: fix flags for initramfs LZ4 compression
mm: include VM_MIXEDMAP flag in the VM_SPECIAL list to avoid m(un)locking
memcg: reparent charges of children before processing parent
memcg: fix endless loop in __mem_cgroup_iter_next()
lib/radix-tree.c: swapoff tmpfs radix_tree: remember to rcu_read_unlock
dma debug: account for cachelines and read-only mappings in overlap tracking
mm: close PageTail race
MAINTAINERS: EDAC: add Mauro and Borislav as interim patch collectors
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/huge_mm.h | 41 | ||||
| -rw-r--r-- | include/linux/mm.h | 20 |
2 files changed, 15 insertions, 46 deletions
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index db512014e061..b826239bdce0 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h | |||
| @@ -157,46 +157,6 @@ static inline int hpage_nr_pages(struct page *page) | |||
| 157 | return HPAGE_PMD_NR; | 157 | return HPAGE_PMD_NR; |
| 158 | return 1; | 158 | return 1; |
| 159 | } | 159 | } |
| 160 | /* | ||
| 161 | * compound_trans_head() should be used instead of compound_head(), | ||
| 162 | * whenever the "page" passed as parameter could be the tail of a | ||
| 163 | * transparent hugepage that could be undergoing a | ||
| 164 | * __split_huge_page_refcount(). The page structure layout often | ||
| 165 | * changes across releases and it makes extensive use of unions. So if | ||
| 166 | * the page structure layout will change in a way that | ||
| 167 | * page->first_page gets clobbered by __split_huge_page_refcount, the | ||
| 168 | * implementation making use of smp_rmb() will be required. | ||
| 169 | * | ||
| 170 | * Currently we define compound_trans_head as compound_head, because | ||
| 171 | * page->private is in the same union with page->first_page, and | ||
| 172 | * page->private isn't clobbered. However this also means we're | ||
| 173 | * currently leaving dirt into the page->private field of anonymous | ||
| 174 | * pages resulting from a THP split, instead of setting page->private | ||
| 175 | * to zero like for every other page that has PG_private not set. But | ||
| 176 | * anonymous pages don't use page->private so this is not a problem. | ||
| 177 | */ | ||
| 178 | #if 0 | ||
| 179 | /* This will be needed if page->private will be clobbered in split_huge_page */ | ||
| 180 | static inline struct page *compound_trans_head(struct page *page) | ||
| 181 | { | ||
| 182 | if (PageTail(page)) { | ||
| 183 | struct page *head; | ||
| 184 | head = page->first_page; | ||
| 185 | smp_rmb(); | ||
| 186 | /* | ||
| 187 | * head may be a dangling pointer. | ||
| 188 | * __split_huge_page_refcount clears PageTail before | ||
| 189 | * overwriting first_page, so if PageTail is still | ||
| 190 | * there it means the head pointer isn't dangling. | ||
| 191 | */ | ||
| 192 | if (PageTail(page)) | ||
| 193 | return head; | ||
| 194 | } | ||
| 195 | return page; | ||
| 196 | } | ||
| 197 | #else | ||
| 198 | #define compound_trans_head(page) compound_head(page) | ||
| 199 | #endif | ||
| 200 | 160 | ||
| 201 | extern int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma, | 161 | extern int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma, |
| 202 | unsigned long addr, pmd_t pmd, pmd_t *pmdp); | 162 | unsigned long addr, pmd_t pmd, pmd_t *pmdp); |
| @@ -226,7 +186,6 @@ static inline int split_huge_page(struct page *page) | |||
| 226 | do { } while (0) | 186 | do { } while (0) |
| 227 | #define split_huge_page_pmd_mm(__mm, __address, __pmd) \ | 187 | #define split_huge_page_pmd_mm(__mm, __address, __pmd) \ |
| 228 | do { } while (0) | 188 | do { } while (0) |
| 229 | #define compound_trans_head(page) compound_head(page) | ||
| 230 | static inline int hugepage_madvise(struct vm_area_struct *vma, | 189 | static inline int hugepage_madvise(struct vm_area_struct *vma, |
| 231 | unsigned long *vm_flags, int advice) | 190 | unsigned long *vm_flags, int advice) |
| 232 | { | 191 | { |
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) |
