@@ -455,8 +455,9 @@ static void update_pgdat_span(struct pglist_data *pgdat)
455
455
pgdat -> node_spanned_pages = node_end_pfn - node_start_pfn ;
456
456
}
457
457
458
- static void __remove_zone (struct zone * zone , unsigned long start_pfn ,
459
- unsigned long nr_pages )
458
+ void __ref remove_pfn_range_from_zone (struct zone * zone ,
459
+ unsigned long start_pfn ,
460
+ unsigned long nr_pages )
460
461
{
461
462
struct pglist_data * pgdat = zone -> zone_pgdat ;
462
463
unsigned long flags ;
@@ -469,28 +470,30 @@ static void __remove_zone(struct zone *zone, unsigned long start_pfn,
469
470
if (zone_idx (zone ) == ZONE_DEVICE )
470
471
return ;
471
472
473
+ clear_zone_contiguous (zone );
474
+
472
475
pgdat_resize_lock (zone -> zone_pgdat , & flags );
473
476
shrink_zone_span (zone , start_pfn , start_pfn + nr_pages );
474
477
update_pgdat_span (pgdat );
475
478
pgdat_resize_unlock (zone -> zone_pgdat , & flags );
479
+
480
+ set_zone_contiguous (zone );
476
481
}
477
482
478
- static void __remove_section (struct zone * zone , unsigned long pfn ,
479
- unsigned long nr_pages , unsigned long map_offset ,
480
- struct vmem_altmap * altmap )
483
+ static void __remove_section (unsigned long pfn , unsigned long nr_pages ,
484
+ unsigned long map_offset ,
485
+ struct vmem_altmap * altmap )
481
486
{
482
487
struct mem_section * ms = __nr_to_section (pfn_to_section_nr (pfn ));
483
488
484
489
if (WARN_ON_ONCE (!valid_section (ms )))
485
490
return ;
486
491
487
- __remove_zone (zone , pfn , nr_pages );
488
492
sparse_remove_section (ms , pfn , nr_pages , map_offset , altmap );
489
493
}
490
494
491
495
/**
492
- * __remove_pages() - remove sections of pages from a zone
493
- * @zone: zone from which pages need to be removed
496
+ * __remove_pages() - remove sections of pages
494
497
* @pfn: starting pageframe (must be aligned to start of a section)
495
498
* @nr_pages: number of pages to remove (must be multiple of section size)
496
499
* @altmap: alternative device page map or %NULL if default memmap is used
@@ -500,16 +503,14 @@ static void __remove_section(struct zone *zone, unsigned long pfn,
500
503
* sure that pages are marked reserved and zones are adjust properly by
501
504
* calling offline_pages().
502
505
*/
503
- void __remove_pages (struct zone * zone , unsigned long pfn ,
504
- unsigned long nr_pages , struct vmem_altmap * altmap )
506
+ void __remove_pages (unsigned long pfn , unsigned long nr_pages ,
507
+ struct vmem_altmap * altmap )
505
508
{
506
509
unsigned long map_offset = 0 ;
507
510
unsigned long nr , start_sec , end_sec ;
508
511
509
512
map_offset = vmem_altmap_offset (altmap );
510
513
511
- clear_zone_contiguous (zone );
512
-
513
514
if (check_pfn_span (pfn , nr_pages , "remove" ))
514
515
return ;
515
516
@@ -521,13 +522,11 @@ void __remove_pages(struct zone *zone, unsigned long pfn,
521
522
cond_resched ();
522
523
pfns = min (nr_pages , PAGES_PER_SECTION
523
524
- (pfn & ~PAGE_SECTION_MASK ));
524
- __remove_section (zone , pfn , pfns , map_offset , altmap );
525
+ __remove_section (pfn , pfns , map_offset , altmap );
525
526
pfn += pfns ;
526
527
nr_pages -= pfns ;
527
528
map_offset = 0 ;
528
529
}
529
-
530
- set_zone_contiguous (zone );
531
530
}
532
531
533
532
int set_online_page_callback (online_page_callback_t callback )
@@ -839,6 +838,7 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_typ
839
838
(unsigned long long ) pfn << PAGE_SHIFT ,
840
839
(((unsigned long long ) pfn + nr_pages ) << PAGE_SHIFT ) - 1 );
841
840
memory_notify (MEM_CANCEL_ONLINE , & arg );
841
+ remove_pfn_range_from_zone (zone , pfn , nr_pages );
842
842
mem_hotplug_done ();
843
843
return ret ;
844
844
}
@@ -1585,6 +1585,7 @@ static int __ref __offline_pages(unsigned long start_pfn,
1585
1585
writeback_set_ratelimit ();
1586
1586
1587
1587
memory_notify (MEM_OFFLINE , & arg );
1588
+ remove_pfn_range_from_zone (zone , start_pfn , nr_pages );
1588
1589
mem_hotplug_done ();
1589
1590
return 0 ;
1590
1591
0 commit comments