aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-13 16:11:15 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-13 16:11:15 -0500
commitf6e858a00af788bab0fd4c0b7f5cd788000edc18 (patch)
treef9403ca3671be9821dbf83e726e61dbe75fbca6b /include
parent193c0d682525987db59ac3a24531a77e4947aa95 (diff)
parent98870901cce098bbe94d90d2c41d8d1fa8d94392 (diff)
Merge branch 'akpm' (Andrew's patch-bomb)
Merge misc VM changes from Andrew Morton: "The rest of most-of-MM. The other MM bits await a slab merge. This patch includes the addition of a huge zero_page. Not a performance boost but it an save large amounts of physical memory in some situations. Also a bunch of Fujitsu engineers are working on memory hotplug. Which, as it turns out, was badly broken. About half of their patches are included here; the remainder are 3.8 material." However, this merge disables CONFIG_MOVABLE_NODE, which was totally broken. We don't add new features with "default y", nor do we add Kconfig questions that are incomprehensible to most people without any help text. Does the feature even make sense without compaction or memory hotplug? * akpm: (54 commits) mm/bootmem.c: remove unused wrapper function reserve_bootmem_generic() mm/memory.c: remove unused code from do_wp_page() asm-generic, mm: pgtable: consolidate zero page helpers mm/hugetlb.c: fix warning on freeing hwpoisoned hugepage hwpoison, hugetlbfs: fix RSS-counter warning hwpoison, hugetlbfs: fix "bad pmd" warning in unmapping hwpoisoned hugepage mm: protect against concurrent vma expansion memcg: do not check for mm in __mem_cgroup_count_vm_event tmpfs: support SEEK_DATA and SEEK_HOLE (reprise) mm: provide more accurate estimation of pages occupied by memmap fs/buffer.c: remove redundant initialization in alloc_page_buffers() fs/buffer.c: do not inline exported function writeback: fix a typo in comment mm: introduce new field "managed_pages" to struct zone mm, oom: remove statically defined arch functions of same name mm, oom: remove redundant sleep in pagefault oom handler mm, oom: cleanup pagefault oom handler memory_hotplug: allow online/offline memory to result movable node numa: add CONFIG_MOVABLE_NODE for movable-dedicated node mm, memcg: avoid unnecessary function call when memcg is disabled ...
Diffstat (limited to 'include')
-rw-r--r--include/asm-generic/pgtable.h26
-rw-r--r--include/linux/bootmem.h3
-rw-r--r--include/linux/cpuset.h2
-rw-r--r--include/linux/gfp.h1
-rw-r--r--include/linux/huge_mm.h18
-rw-r--r--include/linux/memcontrol.h9
-rw-r--r--include/linux/memory.h1
-rw-r--r--include/linux/mmzone.h41
-rw-r--r--include/linux/nodemask.h5
-rw-r--r--include/linux/res_counter.h5
-rw-r--r--include/linux/vm_event_item.h2
11 files changed, 92 insertions, 21 deletions
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index b36ce40bd1c6..284e80831d2c 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -449,6 +449,32 @@ extern void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,
449 unsigned long size); 449 unsigned long size);
450#endif 450#endif
451 451
452#ifdef __HAVE_COLOR_ZERO_PAGE
453static inline int is_zero_pfn(unsigned long pfn)
454{
455 extern unsigned long zero_pfn;
456 unsigned long offset_from_zero_pfn = pfn - zero_pfn;
457 return offset_from_zero_pfn <= (zero_page_mask >> PAGE_SHIFT);
458}
459
460static inline unsigned long my_zero_pfn(unsigned long addr)
461{
462 return page_to_pfn(ZERO_PAGE(addr));
463}
464#else
465static inline int is_zero_pfn(unsigned long pfn)
466{
467 extern unsigned long zero_pfn;
468 return pfn == zero_pfn;
469}
470
471static inline unsigned long my_zero_pfn(unsigned long addr)
472{
473 extern unsigned long zero_pfn;
474 return zero_pfn;
475}
476#endif
477
452#ifdef CONFIG_MMU 478#ifdef CONFIG_MMU
453 479
454#ifndef CONFIG_TRANSPARENT_HUGEPAGE 480#ifndef CONFIG_TRANSPARENT_HUGEPAGE
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h
index 7b74452c5317..3f778c27f825 100644
--- a/include/linux/bootmem.h
+++ b/include/linux/bootmem.h
@@ -137,9 +137,6 @@ extern void *__alloc_bootmem_low_node(pg_data_t *pgdat,
137#define alloc_bootmem_low_pages_node(pgdat, x) \ 137#define alloc_bootmem_low_pages_node(pgdat, x) \
138 __alloc_bootmem_low_node(pgdat, x, PAGE_SIZE, 0) 138 __alloc_bootmem_low_node(pgdat, x, PAGE_SIZE, 0)
139 139
140extern int reserve_bootmem_generic(unsigned long addr, unsigned long size,
141 int flags);
142
143#ifdef CONFIG_HAVE_ARCH_ALLOC_REMAP 140#ifdef CONFIG_HAVE_ARCH_ALLOC_REMAP
144extern void *alloc_remap(int nid, unsigned long size); 141extern void *alloc_remap(int nid, unsigned long size);
145#else 142#else
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
index 838320fc3d1d..8c8a60d29407 100644
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -144,7 +144,7 @@ static inline nodemask_t cpuset_mems_allowed(struct task_struct *p)
144 return node_possible_map; 144 return node_possible_map;
145} 145}
146 146
147#define cpuset_current_mems_allowed (node_states[N_HIGH_MEMORY]) 147#define cpuset_current_mems_allowed (node_states[N_MEMORY])
148static inline void cpuset_init_current_mems_allowed(void) {} 148static inline void cpuset_init_current_mems_allowed(void) {}
149 149
150static inline int cpuset_nodemask_valid_mems_allowed(nodemask_t *nodemask) 150static inline int cpuset_nodemask_valid_mems_allowed(nodemask_t *nodemask)
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 31e8041274f6..f74856e17e48 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -34,6 +34,7 @@ struct vm_area_struct;
34#define ___GFP_NO_KSWAPD 0x400000u 34#define ___GFP_NO_KSWAPD 0x400000u
35#define ___GFP_OTHER_NODE 0x800000u 35#define ___GFP_OTHER_NODE 0x800000u
36#define ___GFP_WRITE 0x1000000u 36#define ___GFP_WRITE 0x1000000u
37/* If the above are modified, __GFP_BITS_SHIFT may need updating */
37 38
38/* 39/*
39 * GFP bitmasks.. 40 * GFP bitmasks..
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index 1af477552459..092dc5305a32 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -39,6 +39,7 @@ enum transparent_hugepage_flag {
39 TRANSPARENT_HUGEPAGE_DEFRAG_FLAG, 39 TRANSPARENT_HUGEPAGE_DEFRAG_FLAG,
40 TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG, 40 TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG,
41 TRANSPARENT_HUGEPAGE_DEFRAG_KHUGEPAGED_FLAG, 41 TRANSPARENT_HUGEPAGE_DEFRAG_KHUGEPAGED_FLAG,
42 TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG,
42#ifdef CONFIG_DEBUG_VM 43#ifdef CONFIG_DEBUG_VM
43 TRANSPARENT_HUGEPAGE_DEBUG_COW_FLAG, 44 TRANSPARENT_HUGEPAGE_DEBUG_COW_FLAG,
44#endif 45#endif
@@ -78,6 +79,9 @@ extern bool is_vma_temporary_stack(struct vm_area_struct *vma);
78 (transparent_hugepage_flags & \ 79 (transparent_hugepage_flags & \
79 (1<<TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG) && \ 80 (1<<TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG) && \
80 (__vma)->vm_flags & VM_HUGEPAGE)) 81 (__vma)->vm_flags & VM_HUGEPAGE))
82#define transparent_hugepage_use_zero_page() \
83 (transparent_hugepage_flags & \
84 (1<<TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG))
81#ifdef CONFIG_DEBUG_VM 85#ifdef CONFIG_DEBUG_VM
82#define transparent_hugepage_debug_cow() \ 86#define transparent_hugepage_debug_cow() \
83 (transparent_hugepage_flags & \ 87 (transparent_hugepage_flags & \
@@ -95,12 +99,14 @@ extern int handle_pte_fault(struct mm_struct *mm,
95 struct vm_area_struct *vma, unsigned long address, 99 struct vm_area_struct *vma, unsigned long address,
96 pte_t *pte, pmd_t *pmd, unsigned int flags); 100 pte_t *pte, pmd_t *pmd, unsigned int flags);
97extern int split_huge_page(struct page *page); 101extern int split_huge_page(struct page *page);
98extern void __split_huge_page_pmd(struct mm_struct *mm, pmd_t *pmd); 102extern void __split_huge_page_pmd(struct vm_area_struct *vma,
99#define split_huge_page_pmd(__mm, __pmd) \ 103 unsigned long address, pmd_t *pmd);
104#define split_huge_page_pmd(__vma, __address, __pmd) \
100 do { \ 105 do { \
101 pmd_t *____pmd = (__pmd); \ 106 pmd_t *____pmd = (__pmd); \
102 if (unlikely(pmd_trans_huge(*____pmd))) \ 107 if (unlikely(pmd_trans_huge(*____pmd))) \
103 __split_huge_page_pmd(__mm, ____pmd); \ 108 __split_huge_page_pmd(__vma, __address, \
109 ____pmd); \
104 } while (0) 110 } while (0)
105#define wait_split_huge_page(__anon_vma, __pmd) \ 111#define wait_split_huge_page(__anon_vma, __pmd) \
106 do { \ 112 do { \
@@ -110,6 +116,8 @@ extern void __split_huge_page_pmd(struct mm_struct *mm, pmd_t *pmd);
110 BUG_ON(pmd_trans_splitting(*____pmd) || \ 116 BUG_ON(pmd_trans_splitting(*____pmd) || \
111 pmd_trans_huge(*____pmd)); \ 117 pmd_trans_huge(*____pmd)); \
112 } while (0) 118 } while (0)
119extern void split_huge_page_pmd_mm(struct mm_struct *mm, unsigned long address,
120 pmd_t *pmd);
113#if HPAGE_PMD_ORDER > MAX_ORDER 121#if HPAGE_PMD_ORDER > MAX_ORDER
114#error "hugepages can't be allocated by the buddy allocator" 122#error "hugepages can't be allocated by the buddy allocator"
115#endif 123#endif
@@ -177,10 +185,12 @@ static inline int split_huge_page(struct page *page)
177{ 185{
178 return 0; 186 return 0;
179} 187}
180#define split_huge_page_pmd(__mm, __pmd) \ 188#define split_huge_page_pmd(__vma, __address, __pmd) \
181 do { } while (0) 189 do { } while (0)
182#define wait_split_huge_page(__anon_vma, __pmd) \ 190#define wait_split_huge_page(__anon_vma, __pmd) \
183 do { } while (0) 191 do { } while (0)
192#define split_huge_page_pmd_mm(__mm, __address, __pmd) \
193 do { } while (0)
184#define compound_trans_head(page) compound_head(page) 194#define compound_trans_head(page) compound_head(page)
185static inline int hugepage_madvise(struct vm_area_struct *vma, 195static inline int hugepage_madvise(struct vm_area_struct *vma,
186 unsigned long *vm_flags, int advice) 196 unsigned long *vm_flags, int advice)
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 11ddc7ffeba8..e98a74c0c9c0 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -181,7 +181,14 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
181 gfp_t gfp_mask, 181 gfp_t gfp_mask,
182 unsigned long *total_scanned); 182 unsigned long *total_scanned);
183 183
184void mem_cgroup_count_vm_event(struct mm_struct *mm, enum vm_event_item idx); 184void __mem_cgroup_count_vm_event(struct mm_struct *mm, enum vm_event_item idx);
185static inline void mem_cgroup_count_vm_event(struct mm_struct *mm,
186 enum vm_event_item idx)
187{
188 if (mem_cgroup_disabled())
189 return;
190 __mem_cgroup_count_vm_event(mm, idx);
191}
185#ifdef CONFIG_TRANSPARENT_HUGEPAGE 192#ifdef CONFIG_TRANSPARENT_HUGEPAGE
186void mem_cgroup_split_huge_fixup(struct page *head); 193void mem_cgroup_split_huge_fixup(struct page *head);
187#endif 194#endif
diff --git a/include/linux/memory.h b/include/linux/memory.h
index a09216d0dcc7..45e93b468878 100644
--- a/include/linux/memory.h
+++ b/include/linux/memory.h
@@ -54,6 +54,7 @@ struct memory_notify {
54 unsigned long start_pfn; 54 unsigned long start_pfn;
55 unsigned long nr_pages; 55 unsigned long nr_pages;
56 int status_change_nid_normal; 56 int status_change_nid_normal;
57 int status_change_nid_high;
57 int status_change_nid; 58 int status_change_nid;
58}; 59};
59 60
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 0c0b1d608a69..cd55dad56aac 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -460,17 +460,44 @@ struct zone {
460 unsigned long zone_start_pfn; 460 unsigned long zone_start_pfn;
461 461
462 /* 462 /*
463 * zone_start_pfn, spanned_pages and present_pages are all 463 * spanned_pages is the total pages spanned by the zone, including
464 * protected by span_seqlock. It is a seqlock because it has 464 * holes, which is calculated as:
465 * to be read outside of zone->lock, and it is done in the main 465 * spanned_pages = zone_end_pfn - zone_start_pfn;
466 * allocator path. But, it is written quite infrequently.
467 * 466 *
468 * The lock is declared along with zone->lock because it is 467 * present_pages is physical pages existing within the zone, which
468 * is calculated as:
469 * present_pages = spanned_pages - absent_pages(pags in holes);
470 *
471 * managed_pages is present pages managed by the buddy system, which
472 * is calculated as (reserved_pages includes pages allocated by the
473 * bootmem allocator):
474 * managed_pages = present_pages - reserved_pages;
475 *
476 * So present_pages may be used by memory hotplug or memory power
477 * management logic to figure out unmanaged pages by checking
478 * (present_pages - managed_pages). And managed_pages should be used
479 * by page allocator and vm scanner to calculate all kinds of watermarks
480 * and thresholds.
481 *
482 * Locking rules:
483 *
484 * zone_start_pfn and spanned_pages are protected by span_seqlock.
485 * It is a seqlock because it has to be read outside of zone->lock,
486 * and it is done in the main allocator path. But, it is written
487 * quite infrequently.
488 *
489 * The span_seq lock is declared along with zone->lock because it is
469 * frequently read in proximity to zone->lock. It's good to 490 * frequently read in proximity to zone->lock. It's good to
470 * give them a chance of being in the same cacheline. 491 * give them a chance of being in the same cacheline.
492 *
493 * Write access to present_pages and managed_pages at runtime should
494 * be protected by lock_memory_hotplug()/unlock_memory_hotplug().
495 * Any reader who can't tolerant drift of present_pages and
496 * managed_pages should hold memory hotplug lock to get a stable value.
471 */ 497 */
472 unsigned long spanned_pages; /* total size, including holes */ 498 unsigned long spanned_pages;
473 unsigned long present_pages; /* amount of memory (excluding holes) */ 499 unsigned long present_pages;
500 unsigned long managed_pages;
474 501
475 /* 502 /*
476 * rarely used fields: 503 * rarely used fields:
diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h
index 7afc36334d52..4e2cbfa640b7 100644
--- a/include/linux/nodemask.h
+++ b/include/linux/nodemask.h
@@ -380,6 +380,11 @@ enum node_states {
380#else 380#else
381 N_HIGH_MEMORY = N_NORMAL_MEMORY, 381 N_HIGH_MEMORY = N_NORMAL_MEMORY,
382#endif 382#endif
383#ifdef CONFIG_MOVABLE_NODE
384 N_MEMORY, /* The node has memory(regular, high, movable) */
385#else
386 N_MEMORY = N_HIGH_MEMORY,
387#endif
383 N_CPU, /* The node has one or more cpus */ 388 N_CPU, /* The node has one or more cpus */
384 NR_NODE_STATES 389 NR_NODE_STATES
385}; 390};
diff --git a/include/linux/res_counter.h b/include/linux/res_counter.h
index 7d7fbe2ef782..6f54e40fa218 100644
--- a/include/linux/res_counter.h
+++ b/include/linux/res_counter.h
@@ -74,14 +74,9 @@ ssize_t res_counter_read(struct res_counter *counter, int member,
74 const char __user *buf, size_t nbytes, loff_t *pos, 74 const char __user *buf, size_t nbytes, loff_t *pos,
75 int (*read_strategy)(unsigned long long val, char *s)); 75 int (*read_strategy)(unsigned long long val, char *s));
76 76
77typedef int (*write_strategy_fn)(const char *buf, unsigned long long *val);
78
79int res_counter_memparse_write_strategy(const char *buf, 77int res_counter_memparse_write_strategy(const char *buf,
80 unsigned long long *res); 78 unsigned long long *res);
81 79
82int res_counter_write(struct res_counter *counter, int member,
83 const char *buffer, write_strategy_fn write_strategy);
84
85/* 80/*
86 * the field descriptors. one for each member of res_counter 81 * the field descriptors. one for each member of res_counter
87 */ 82 */
diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h
index 3d3114594370..fe786f07d2bd 100644
--- a/include/linux/vm_event_item.h
+++ b/include/linux/vm_event_item.h
@@ -58,6 +58,8 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
58 THP_COLLAPSE_ALLOC, 58 THP_COLLAPSE_ALLOC,
59 THP_COLLAPSE_ALLOC_FAILED, 59 THP_COLLAPSE_ALLOC_FAILED,
60 THP_SPLIT, 60 THP_SPLIT,
61 THP_ZERO_PAGE_ALLOC,
62 THP_ZERO_PAGE_ALLOC_FAILED,
61#endif 63#endif
62 NR_VM_EVENT_ITEMS 64 NR_VM_EVENT_ITEMS
63}; 65};