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