aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorAndrew Morton <akpm@linux-foundation.org>2012-11-16 17:15:06 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-11-16 17:33:04 -0500
commit5576646f3c1abd60d72d19829de6f5d8c2ca8ecf (patch)
tree600e8d1df6536bbeb0b15b51f137d37a94f69843 /mm
parent0f3c42f522dc1ad7e27affc0a4aa8c790bce0a66 (diff)
revert "mm: fix-up zone present pages"
Revert commit 7f1290f2f2a4 ("mm: fix-up zone present pages") That patch tried to fix a issue when calculating zone->present_pages, but it caused a regression on 32bit systems with HIGHMEM. With that change, reset_zone_present_pages() resets all zone->present_pages to zero, and fixup_zone_present_pages() is called to recalculate zone->present_pages when the boot allocator frees core memory pages into buddy allocator. Because highmem pages are not freed by bootmem allocator, all highmem zones' present_pages becomes zero. Various options for improving the situation are being discussed but for now, let's return to the 3.6 code. Cc: Jianguo Wu <wujianguo@huawei.com> Cc: Jiang Liu <jiang.liu@huawei.com> Cc: Petr Tesarik <ptesarik@suse.cz> Cc: "Luck, Tony" <tony.luck@intel.com> Cc: Mel Gorman <mel@csn.ul.ie> Cc: Yinghai Lu <yinghai@kernel.org> Cc: Minchan Kim <minchan.kim@gmail.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Acked-by: David Rientjes <rientjes@google.com> Tested-by: Chris Clayton <chris2553@googlemail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/bootmem.c10
-rw-r--r--mm/memory_hotplug.c7
-rw-r--r--mm/nobootmem.c3
-rw-r--r--mm/page_alloc.c34
4 files changed, 1 insertions, 53 deletions
diff --git a/mm/bootmem.c b/mm/bootmem.c
index 434be4ae7a04..f468185b3b28 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -198,8 +198,6 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
198 int order = ilog2(BITS_PER_LONG); 198 int order = ilog2(BITS_PER_LONG);
199 199
200 __free_pages_bootmem(pfn_to_page(start), order); 200 __free_pages_bootmem(pfn_to_page(start), order);
201 fixup_zone_present_pages(page_to_nid(pfn_to_page(start)),
202 start, start + BITS_PER_LONG);
203 count += BITS_PER_LONG; 201 count += BITS_PER_LONG;
204 start += BITS_PER_LONG; 202 start += BITS_PER_LONG;
205 } else { 203 } else {
@@ -210,9 +208,6 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
210 if (vec & 1) { 208 if (vec & 1) {
211 page = pfn_to_page(start + off); 209 page = pfn_to_page(start + off);
212 __free_pages_bootmem(page, 0); 210 __free_pages_bootmem(page, 0);
213 fixup_zone_present_pages(
214 page_to_nid(page),
215 start + off, start + off + 1);
216 count++; 211 count++;
217 } 212 }
218 vec >>= 1; 213 vec >>= 1;
@@ -226,11 +221,8 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
226 pages = bdata->node_low_pfn - bdata->node_min_pfn; 221 pages = bdata->node_low_pfn - bdata->node_min_pfn;
227 pages = bootmem_bootmap_pages(pages); 222 pages = bootmem_bootmap_pages(pages);
228 count += pages; 223 count += pages;
229 while (pages--) { 224 while (pages--)
230 fixup_zone_present_pages(page_to_nid(page),
231 page_to_pfn(page), page_to_pfn(page) + 1);
232 __free_pages_bootmem(page++, 0); 225 __free_pages_bootmem(page++, 0);
233 }
234 226
235 bdebug("nid=%td released=%lx\n", bdata - bootmem_node_data, count); 227 bdebug("nid=%td released=%lx\n", bdata - bootmem_node_data, count);
236 228
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 56b758ae57d2..e4eeacae2b91 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -106,7 +106,6 @@ static void get_page_bootmem(unsigned long info, struct page *page,
106void __ref put_page_bootmem(struct page *page) 106void __ref put_page_bootmem(struct page *page)
107{ 107{
108 unsigned long type; 108 unsigned long type;
109 struct zone *zone;
110 109
111 type = (unsigned long) page->lru.next; 110 type = (unsigned long) page->lru.next;
112 BUG_ON(type < MEMORY_HOTPLUG_MIN_BOOTMEM_TYPE || 111 BUG_ON(type < MEMORY_HOTPLUG_MIN_BOOTMEM_TYPE ||
@@ -117,12 +116,6 @@ void __ref put_page_bootmem(struct page *page)
117 set_page_private(page, 0); 116 set_page_private(page, 0);
118 INIT_LIST_HEAD(&page->lru); 117 INIT_LIST_HEAD(&page->lru);
119 __free_pages_bootmem(page, 0); 118 __free_pages_bootmem(page, 0);
120
121 zone = page_zone(page);
122 zone_span_writelock(zone);
123 zone->present_pages++;
124 zone_span_writeunlock(zone);
125 totalram_pages++;
126 } 119 }
127 120
128} 121}
diff --git a/mm/nobootmem.c b/mm/nobootmem.c
index 714d5d650470..bd82f6b31411 100644
--- a/mm/nobootmem.c
+++ b/mm/nobootmem.c
@@ -116,8 +116,6 @@ static unsigned long __init __free_memory_core(phys_addr_t start,
116 return 0; 116 return 0;
117 117
118 __free_pages_memory(start_pfn, end_pfn); 118 __free_pages_memory(start_pfn, end_pfn);
119 fixup_zone_present_pages(pfn_to_nid(start >> PAGE_SHIFT),
120 start_pfn, end_pfn);
121 119
122 return end_pfn - start_pfn; 120 return end_pfn - start_pfn;
123} 121}
@@ -128,7 +126,6 @@ unsigned long __init free_low_memory_core_early(int nodeid)
128 phys_addr_t start, end, size; 126 phys_addr_t start, end, size;
129 u64 i; 127 u64 i;
130 128
131 reset_zone_present_pages();
132 for_each_free_mem_range(i, MAX_NUMNODES, &start, &end, NULL) 129 for_each_free_mem_range(i, MAX_NUMNODES, &start, &end, NULL)
133 count += __free_memory_core(start, end); 130 count += __free_memory_core(start, end);
134 131
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index c91598b1b4c0..7bb35ac0964a 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -6098,37 +6098,3 @@ void dump_page(struct page *page)
6098 dump_page_flags(page->flags); 6098 dump_page_flags(page->flags);
6099 mem_cgroup_print_bad_page(page); 6099 mem_cgroup_print_bad_page(page);
6100} 6100}
6101
6102/* reset zone->present_pages */
6103void reset_zone_present_pages(void)
6104{
6105 struct zone *z;
6106 int i, nid;
6107
6108 for_each_node_state(nid, N_HIGH_MEMORY) {
6109 for (i = 0; i < MAX_NR_ZONES; i++) {
6110 z = NODE_DATA(nid)->node_zones + i;
6111 z->present_pages = 0;
6112 }
6113 }
6114}
6115
6116/* calculate zone's present pages in buddy system */
6117void fixup_zone_present_pages(int nid, unsigned long start_pfn,
6118 unsigned long end_pfn)
6119{
6120 struct zone *z;
6121 unsigned long zone_start_pfn, zone_end_pfn;
6122 int i;
6123
6124 for (i = 0; i < MAX_NR_ZONES; i++) {
6125 z = NODE_DATA(nid)->node_zones + i;
6126 zone_start_pfn = z->zone_start_pfn;
6127 zone_end_pfn = zone_start_pfn + z->spanned_pages;
6128
6129 /* if the two regions intersect */
6130 if (!(zone_start_pfn >= end_pfn || zone_end_pfn <= start_pfn))
6131 z->present_pages += min(end_pfn, zone_end_pfn) -
6132 max(start_pfn, zone_start_pfn);
6133 }
6134}