aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memory_hotplug.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memory_hotplug.c')
-rw-r--r--mm/memory_hotplug.c39
1 files changed, 18 insertions, 21 deletions
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 9bbd6982d4e4..b2bd52ff7605 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -247,7 +247,7 @@ void __init register_page_bootmem_info_node(struct pglist_data *pgdat)
247#endif /* CONFIG_HAVE_BOOTMEM_INFO_NODE */ 247#endif /* CONFIG_HAVE_BOOTMEM_INFO_NODE */
248 248
249static int __meminit __add_section(int nid, unsigned long phys_start_pfn, 249static int __meminit __add_section(int nid, unsigned long phys_start_pfn,
250 bool want_memblock) 250 struct vmem_altmap *altmap, bool want_memblock)
251{ 251{
252 int ret; 252 int ret;
253 int i; 253 int i;
@@ -255,7 +255,7 @@ static int __meminit __add_section(int nid, unsigned long phys_start_pfn,
255 if (pfn_valid(phys_start_pfn)) 255 if (pfn_valid(phys_start_pfn))
256 return -EEXIST; 256 return -EEXIST;
257 257
258 ret = sparse_add_one_section(NODE_DATA(nid), phys_start_pfn); 258 ret = sparse_add_one_section(NODE_DATA(nid), phys_start_pfn, altmap);
259 if (ret < 0) 259 if (ret < 0)
260 return ret; 260 return ret;
261 261
@@ -289,18 +289,17 @@ static int __meminit __add_section(int nid, unsigned long phys_start_pfn,
289 * add the new pages. 289 * add the new pages.
290 */ 290 */
291int __ref __add_pages(int nid, unsigned long phys_start_pfn, 291int __ref __add_pages(int nid, unsigned long phys_start_pfn,
292 unsigned long nr_pages, bool want_memblock) 292 unsigned long nr_pages, struct vmem_altmap *altmap,
293 bool want_memblock)
293{ 294{
294 unsigned long i; 295 unsigned long i;
295 int err = 0; 296 int err = 0;
296 int start_sec, end_sec; 297 int start_sec, end_sec;
297 struct vmem_altmap *altmap;
298 298
299 /* during initialize mem_map, align hot-added range to section */ 299 /* during initialize mem_map, align hot-added range to section */
300 start_sec = pfn_to_section_nr(phys_start_pfn); 300 start_sec = pfn_to_section_nr(phys_start_pfn);
301 end_sec = pfn_to_section_nr(phys_start_pfn + nr_pages - 1); 301 end_sec = pfn_to_section_nr(phys_start_pfn + nr_pages - 1);
302 302
303 altmap = to_vmem_altmap((unsigned long) pfn_to_page(phys_start_pfn));
304 if (altmap) { 303 if (altmap) {
305 /* 304 /*
306 * Validate altmap is within bounds of the total request 305 * Validate altmap is within bounds of the total request
@@ -315,7 +314,8 @@ int __ref __add_pages(int nid, unsigned long phys_start_pfn,
315 } 314 }
316 315
317 for (i = start_sec; i <= end_sec; i++) { 316 for (i = start_sec; i <= end_sec; i++) {
318 err = __add_section(nid, section_nr_to_pfn(i), want_memblock); 317 err = __add_section(nid, section_nr_to_pfn(i), altmap,
318 want_memblock);
319 319
320 /* 320 /*
321 * EEXIST is finally dealt with by ioresource collision 321 * EEXIST is finally dealt with by ioresource collision
@@ -331,7 +331,6 @@ int __ref __add_pages(int nid, unsigned long phys_start_pfn,
331out: 331out:
332 return err; 332 return err;
333} 333}
334EXPORT_SYMBOL_GPL(__add_pages);
335 334
336#ifdef CONFIG_MEMORY_HOTREMOVE 335#ifdef CONFIG_MEMORY_HOTREMOVE
337/* find the smallest valid pfn in the range [start_pfn, end_pfn) */ 336/* find the smallest valid pfn in the range [start_pfn, end_pfn) */
@@ -534,7 +533,7 @@ static void __remove_zone(struct zone *zone, unsigned long start_pfn)
534} 533}
535 534
536static int __remove_section(struct zone *zone, struct mem_section *ms, 535static int __remove_section(struct zone *zone, struct mem_section *ms,
537 unsigned long map_offset) 536 unsigned long map_offset, struct vmem_altmap *altmap)
538{ 537{
539 unsigned long start_pfn; 538 unsigned long start_pfn;
540 int scn_nr; 539 int scn_nr;
@@ -551,7 +550,7 @@ static int __remove_section(struct zone *zone, struct mem_section *ms,
551 start_pfn = section_nr_to_pfn((unsigned long)scn_nr); 550 start_pfn = section_nr_to_pfn((unsigned long)scn_nr);
552 __remove_zone(zone, start_pfn); 551 __remove_zone(zone, start_pfn);
553 552
554 sparse_remove_one_section(zone, ms, map_offset); 553 sparse_remove_one_section(zone, ms, map_offset, altmap);
555 return 0; 554 return 0;
556} 555}
557 556
@@ -567,7 +566,7 @@ static int __remove_section(struct zone *zone, struct mem_section *ms,
567 * calling offline_pages(). 566 * calling offline_pages().
568 */ 567 */
569int __remove_pages(struct zone *zone, unsigned long phys_start_pfn, 568int __remove_pages(struct zone *zone, unsigned long phys_start_pfn,
570 unsigned long nr_pages) 569 unsigned long nr_pages, struct vmem_altmap *altmap)
571{ 570{
572 unsigned long i; 571 unsigned long i;
573 unsigned long map_offset = 0; 572 unsigned long map_offset = 0;
@@ -575,10 +574,6 @@ int __remove_pages(struct zone *zone, unsigned long phys_start_pfn,
575 574
576 /* In the ZONE_DEVICE case device driver owns the memory region */ 575 /* In the ZONE_DEVICE case device driver owns the memory region */
577 if (is_dev_zone(zone)) { 576 if (is_dev_zone(zone)) {
578 struct page *page = pfn_to_page(phys_start_pfn);
579 struct vmem_altmap *altmap;
580
581 altmap = to_vmem_altmap((unsigned long) page);
582 if (altmap) 577 if (altmap)
583 map_offset = vmem_altmap_offset(altmap); 578 map_offset = vmem_altmap_offset(altmap);
584 } else { 579 } else {
@@ -609,7 +604,8 @@ int __remove_pages(struct zone *zone, unsigned long phys_start_pfn,
609 for (i = 0; i < sections_to_remove; i++) { 604 for (i = 0; i < sections_to_remove; i++) {
610 unsigned long pfn = phys_start_pfn + i*PAGES_PER_SECTION; 605 unsigned long pfn = phys_start_pfn + i*PAGES_PER_SECTION;
611 606
612 ret = __remove_section(zone, __pfn_to_section(pfn), map_offset); 607 ret = __remove_section(zone, __pfn_to_section(pfn), map_offset,
608 altmap);
613 map_offset = 0; 609 map_offset = 0;
614 if (ret) 610 if (ret)
615 break; 611 break;
@@ -799,8 +795,8 @@ static void __meminit resize_pgdat_range(struct pglist_data *pgdat, unsigned lon
799 pgdat->node_spanned_pages = max(start_pfn + nr_pages, old_end_pfn) - pgdat->node_start_pfn; 795 pgdat->node_spanned_pages = max(start_pfn + nr_pages, old_end_pfn) - pgdat->node_start_pfn;
800} 796}
801 797
802void __ref move_pfn_range_to_zone(struct zone *zone, 798void __ref move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn,
803 unsigned long start_pfn, unsigned long nr_pages) 799 unsigned long nr_pages, struct vmem_altmap *altmap)
804{ 800{
805 struct pglist_data *pgdat = zone->zone_pgdat; 801 struct pglist_data *pgdat = zone->zone_pgdat;
806 int nid = pgdat->node_id; 802 int nid = pgdat->node_id;
@@ -825,7 +821,8 @@ void __ref move_pfn_range_to_zone(struct zone *zone,
825 * expects the zone spans the pfn range. All the pages in the range 821 * expects the zone spans the pfn range. All the pages in the range
826 * are reserved so nobody should be touching them so we should be safe 822 * are reserved so nobody should be touching them so we should be safe
827 */ 823 */
828 memmap_init_zone(nr_pages, nid, zone_idx(zone), start_pfn, MEMMAP_HOTPLUG); 824 memmap_init_zone(nr_pages, nid, zone_idx(zone), start_pfn,
825 MEMMAP_HOTPLUG, altmap);
829 826
830 set_zone_contiguous(zone); 827 set_zone_contiguous(zone);
831} 828}
@@ -897,7 +894,7 @@ static struct zone * __meminit move_pfn_range(int online_type, int nid,
897 struct zone *zone; 894 struct zone *zone;
898 895
899 zone = zone_for_pfn_range(online_type, nid, start_pfn, nr_pages); 896 zone = zone_for_pfn_range(online_type, nid, start_pfn, nr_pages);
900 move_pfn_range_to_zone(zone, start_pfn, nr_pages); 897 move_pfn_range_to_zone(zone, start_pfn, nr_pages, NULL);
901 return zone; 898 return zone;
902} 899}
903 900
@@ -1146,7 +1143,7 @@ int __ref add_memory_resource(int nid, struct resource *res, bool online)
1146 } 1143 }
1147 1144
1148 /* call arch's memory hotadd */ 1145 /* call arch's memory hotadd */
1149 ret = arch_add_memory(nid, start, size, true); 1146 ret = arch_add_memory(nid, start, size, NULL, true);
1150 1147
1151 if (ret < 0) 1148 if (ret < 0)
1152 goto error; 1149 goto error;
@@ -1888,7 +1885,7 @@ void __ref remove_memory(int nid, u64 start, u64 size)
1888 memblock_free(start, size); 1885 memblock_free(start, size);
1889 memblock_remove(start, size); 1886 memblock_remove(start, size);
1890 1887
1891 arch_remove_memory(start, size); 1888 arch_remove_memory(start, size, NULL);
1892 1889
1893 try_offline_node(nid); 1890 try_offline_node(nid);
1894 1891