aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/node.c2
-rw-r--r--include/linux/memory.h1
-rw-r--r--mm/memory_hotplug.c27
-rw-r--r--mm/page_alloc.c28
-rw-r--r--mm/sparse.c8
5 files changed, 28 insertions, 38 deletions
diff --git a/drivers/base/node.c b/drivers/base/node.c
index 92b00a7e6a02..7a3a580821e0 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -407,6 +407,8 @@ int register_mem_sect_under_node(struct memory_block *mem_blk, int nid,
407 407
408 if (!mem_blk) 408 if (!mem_blk)
409 return -EFAULT; 409 return -EFAULT;
410
411 mem_blk->nid = nid;
410 if (!node_online(nid)) 412 if (!node_online(nid))
411 return 0; 413 return 0;
412 414
diff --git a/include/linux/memory.h b/include/linux/memory.h
index 9f8cd856ca1e..31ca3e28b0eb 100644
--- a/include/linux/memory.h
+++ b/include/linux/memory.h
@@ -33,6 +33,7 @@ struct memory_block {
33 void *hw; /* optional pointer to fw/hw data */ 33 void *hw; /* optional pointer to fw/hw data */
34 int (*phys_callback)(struct memory_block *); 34 int (*phys_callback)(struct memory_block *);
35 struct device dev; 35 struct device dev;
36 int nid; /* NID for this memory block */
36}; 37};
37 38
38int arch_get_memory_phys_device(unsigned long start_pfn); 39int arch_get_memory_phys_device(unsigned long start_pfn);
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 477e183a4ac7..6a9ba14e18ed 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -250,7 +250,6 @@ static int __meminit __add_section(int nid, unsigned long phys_start_pfn,
250 struct vmem_altmap *altmap, bool want_memblock) 250 struct vmem_altmap *altmap, bool want_memblock)
251{ 251{
252 int ret; 252 int ret;
253 int i;
254 253
255 if (pfn_valid(phys_start_pfn)) 254 if (pfn_valid(phys_start_pfn))
256 return -EEXIST; 255 return -EEXIST;
@@ -259,23 +258,6 @@ static int __meminit __add_section(int nid, unsigned long phys_start_pfn,
259 if (ret < 0) 258 if (ret < 0)
260 return ret; 259 return ret;
261 260
262 /*
263 * Make all the pages reserved so that nobody will stumble over half
264 * initialized state.
265 * FIXME: We also have to associate it with a node because page_to_nid
266 * relies on having page with the proper node.
267 */
268 for (i = 0; i < PAGES_PER_SECTION; i++) {
269 unsigned long pfn = phys_start_pfn + i;
270 struct page *page;
271 if (!pfn_valid(pfn))
272 continue;
273
274 page = pfn_to_page(pfn);
275 set_page_node(page, nid);
276 SetPageReserved(page);
277 }
278
279 if (!want_memblock) 261 if (!want_memblock)
280 return 0; 262 return 0;
281 263
@@ -908,8 +890,15 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_typ
908 int nid; 890 int nid;
909 int ret; 891 int ret;
910 struct memory_notify arg; 892 struct memory_notify arg;
893 struct memory_block *mem;
894
895 /*
896 * We can't use pfn_to_nid() because nid might be stored in struct page
897 * which is not yet initialized. Instead, we find nid from memory block.
898 */
899 mem = find_memory_block(__pfn_to_section(pfn));
900 nid = mem->nid;
911 901
912 nid = pfn_to_nid(pfn);
913 /* associate pfn range with the zone */ 902 /* associate pfn range with the zone */
914 zone = move_pfn_range(online_type, nid, pfn, nr_pages); 903 zone = move_pfn_range(online_type, nid, pfn, nr_pages);
915 904
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 3183eb2f579c..a3e2ba4f76bb 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1143,10 +1143,9 @@ static void free_one_page(struct zone *zone,
1143} 1143}
1144 1144
1145static void __meminit __init_single_page(struct page *page, unsigned long pfn, 1145static void __meminit __init_single_page(struct page *page, unsigned long pfn,
1146 unsigned long zone, int nid, bool zero) 1146 unsigned long zone, int nid)
1147{ 1147{
1148 if (zero) 1148 mm_zero_struct_page(page);
1149 mm_zero_struct_page(page);
1150 set_page_links(page, zone, nid, pfn); 1149 set_page_links(page, zone, nid, pfn);
1151 init_page_count(page); 1150 init_page_count(page);
1152 page_mapcount_reset(page); 1151 page_mapcount_reset(page);
@@ -1160,12 +1159,6 @@ static void __meminit __init_single_page(struct page *page, unsigned long pfn,
1160#endif 1159#endif
1161} 1160}
1162 1161
1163static void __meminit __init_single_pfn(unsigned long pfn, unsigned long zone,
1164 int nid, bool zero)
1165{
1166 return __init_single_page(pfn_to_page(pfn), pfn, zone, nid, zero);
1167}
1168
1169#ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT 1162#ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT
1170static void __meminit init_reserved_page(unsigned long pfn) 1163static void __meminit init_reserved_page(unsigned long pfn)
1171{ 1164{
@@ -1184,7 +1177,7 @@ static void __meminit init_reserved_page(unsigned long pfn)
1184 if (pfn >= zone->zone_start_pfn && pfn < zone_end_pfn(zone)) 1177 if (pfn >= zone->zone_start_pfn && pfn < zone_end_pfn(zone))
1185 break; 1178 break;
1186 } 1179 }
1187 __init_single_pfn(pfn, zid, nid, true); 1180 __init_single_page(pfn_to_page(pfn), pfn, zid, nid);
1188} 1181}
1189#else 1182#else
1190static inline void init_reserved_page(unsigned long pfn) 1183static inline void init_reserved_page(unsigned long pfn)
@@ -1501,7 +1494,7 @@ static unsigned long __init deferred_init_pages(int nid, int zid,
1501 } else { 1494 } else {
1502 page++; 1495 page++;
1503 } 1496 }
1504 __init_single_page(page, pfn, zid, nid, true); 1497 __init_single_page(page, pfn, zid, nid);
1505 nr_pages++; 1498 nr_pages++;
1506 } 1499 }
1507 return (nr_pages); 1500 return (nr_pages);
@@ -5434,6 +5427,7 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
5434 pg_data_t *pgdat = NODE_DATA(nid); 5427 pg_data_t *pgdat = NODE_DATA(nid);
5435 unsigned long pfn; 5428 unsigned long pfn;
5436 unsigned long nr_initialised = 0; 5429 unsigned long nr_initialised = 0;
5430 struct page *page;
5437#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP 5431#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
5438 struct memblock_region *r = NULL, *tmp; 5432 struct memblock_region *r = NULL, *tmp;
5439#endif 5433#endif
@@ -5486,6 +5480,11 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
5486#endif 5480#endif
5487 5481
5488not_early: 5482not_early:
5483 page = pfn_to_page(pfn);
5484 __init_single_page(page, pfn, zone, nid);
5485 if (context == MEMMAP_HOTPLUG)
5486 SetPageReserved(page);
5487
5489 /* 5488 /*
5490 * Mark the block movable so that blocks are reserved for 5489 * Mark the block movable so that blocks are reserved for
5491 * movable at startup. This will force kernel allocations 5490 * movable at startup. This will force kernel allocations
@@ -5502,15 +5501,8 @@ not_early:
5502 * because this is done early in sparse_add_one_section 5501 * because this is done early in sparse_add_one_section
5503 */ 5502 */
5504 if (!(pfn & (pageblock_nr_pages - 1))) { 5503 if (!(pfn & (pageblock_nr_pages - 1))) {
5505 struct page *page = pfn_to_page(pfn);
5506
5507 __init_single_page(page, pfn, zone, nid,
5508 context != MEMMAP_HOTPLUG);
5509 set_pageblock_migratetype(page, MIGRATE_MOVABLE); 5504 set_pageblock_migratetype(page, MIGRATE_MOVABLE);
5510 cond_resched(); 5505 cond_resched();
5511 } else {
5512 __init_single_pfn(pfn, zone, nid,
5513 context != MEMMAP_HOTPLUG);
5514 } 5506 }
5515 } 5507 }
5516} 5508}
diff --git a/mm/sparse.c b/mm/sparse.c
index 58cab483e81b..62eef264a7bd 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -779,7 +779,13 @@ int __meminit sparse_add_one_section(struct pglist_data *pgdat,
779 goto out; 779 goto out;
780 } 780 }
781 781
782 memset(memmap, 0, sizeof(struct page) * PAGES_PER_SECTION); 782#ifdef CONFIG_DEBUG_VM
783 /*
784 * Poison uninitialized struct pages in order to catch invalid flags
785 * combinations.
786 */
787 memset(memmap, PAGE_POISON_PATTERN, sizeof(struct page) * PAGES_PER_SECTION);
788#endif
783 789
784 section_mark_present(ms); 790 section_mark_present(ms);
785 791