History

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.

Andrew Morton committed 13 years ago

Commit 55766461 parent 0f3c42f6 files · +1 −58Browse files

Unified · Split

6 files
  1. arch/ia64/mm/init.c +0 −1
  2. include/linux/mm.h +0 −4
  3. mm/bootmem.c +1 −9
  4. mm/memory_hotplug.c +0 −7
  5. mm/nobootmem.c +0 −3
  6. mm/page_alloc.c +0 −34
arch/ia64/mm/init.c+0−1
@@ -637,7 +637,6 @@ mem_init (void) · 636 unmodified lines
637 637
638 high_memory = __va(max_low_pfn * PAGE_SIZE);638 high_memory = __va(max_low_pfn * PAGE_SIZE);
639 639
640 reset_zone_present_pages();
641 for_each_online_pgdat(pgdat)640 for_each_online_pgdat(pgdat)
642 if (pgdat->bdata->node_bootmem_map)641 if (pgdat->bdata->node_bootmem_map)
643 totalram_pages += free_all_bootmem_node(pgdat);642 totalram_pages += free_all_bootmem_node(pgdat);
include/linux/mm.h+0−4
@@ -1684,9 +1684,5 @@ static inline unsigned int debug_guardpage_minorder(void) { return 0; } · 1683 unmodified lines
1684static inline bool page_is_guard(struct page *page) { return false; }1684static inline bool page_is_guard(struct page *page) { return false; }
1685#endif /* CONFIG_DEBUG_PAGEALLOC */1685#endif /* CONFIG_DEBUG_PAGEALLOC */
1686 1686
1687extern void reset_zone_present_pages(void);
1688extern void fixup_zone_present_pages(int nid, unsigned long start_pfn,
1689 unsigned long end_pfn);
1690
1691#endif /* __KERNEL__ */1687#endif /* __KERNEL__ */
1692#endif /* _LINUX_MM_H */1688#endif /* _LINUX_MM_H */
mm/bootmem.c+1−9
@@ -198,8 +198,6 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) · 197 unmodified lines
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) · 4 unmodified lines
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) · 7 unmodified lines
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
mm/memory_hotplug.c+0−7
@@ -106,7 +106,6 @@ static void get_page_bootmem(unsigned long info, struct page *page, · 105 unmodified lines
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) · 4 unmodified lines
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}
mm/nobootmem.c+0−3
@@ -116,8 +116,6 @@ static unsigned long __init __free_memory_core(phys_addr_t start, · 115 unmodified lines
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) · 4 unmodified lines
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
mm/page_alloc.c+0−34
@@ -6098,37 +6098,3 @@ void dump_page(struct page *page) · 6097 unmodified lines
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}