diff options
Diffstat (limited to 'mm/memory_hotplug.c')
| -rw-r--r-- | mm/memory_hotplug.c | 31 | 
1 files changed, 16 insertions, 15 deletions
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 55ac23ef11c1..a91a072f2b2c 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -483,8 +483,9 @@ static void update_pgdat_span(struct pglist_data *pgdat)  	pgdat->node_spanned_pages = node_end_pfn - node_start_pfn;  } -static void __remove_zone(struct zone *zone, unsigned long start_pfn, -		unsigned long nr_pages) +void __ref remove_pfn_range_from_zone(struct zone *zone, +				      unsigned long start_pfn, +				      unsigned long nr_pages)  {  	struct pglist_data *pgdat = zone->zone_pgdat;  	unsigned long flags; @@ -499,28 +500,30 @@ static void __remove_zone(struct zone *zone, unsigned long start_pfn,  		return;  #endif +	clear_zone_contiguous(zone); +  	pgdat_resize_lock(zone->zone_pgdat, &flags);  	shrink_zone_span(zone, start_pfn, start_pfn + nr_pages);  	update_pgdat_span(pgdat);  	pgdat_resize_unlock(zone->zone_pgdat, &flags); + +	set_zone_contiguous(zone);  } -static void __remove_section(struct zone *zone, unsigned long pfn, -		unsigned long nr_pages, unsigned long map_offset, -		struct vmem_altmap *altmap) +static void __remove_section(unsigned long pfn, unsigned long nr_pages, +			     unsigned long map_offset, +			     struct vmem_altmap *altmap)  {  	struct mem_section *ms = __nr_to_section(pfn_to_section_nr(pfn));  	if (WARN_ON_ONCE(!valid_section(ms)))  		return; -	__remove_zone(zone, pfn, nr_pages);  	sparse_remove_section(ms, pfn, nr_pages, map_offset, altmap);  }  /** - * __remove_pages() - remove sections of pages from a zone - * @zone: zone from which pages need to be removed + * __remove_pages() - remove sections of pages   * @pfn: starting pageframe (must be aligned to start of a section)   * @nr_pages: number of pages to remove (must be multiple of section size)   * @altmap: alternative device page map or %NULL if default memmap is used @@ -530,16 +533,14 @@ static void __remove_section(struct zone *zone, unsigned long pfn,   * sure that pages are marked reserved and zones are adjust properly by   * calling offline_pages().   */ -void __remove_pages(struct zone *zone, unsigned long pfn, -		    unsigned long nr_pages, struct vmem_altmap *altmap) +void __remove_pages(unsigned long pfn, unsigned long nr_pages, +		    struct vmem_altmap *altmap)  {  	unsigned long map_offset = 0;  	unsigned long nr, start_sec, end_sec;  	map_offset = vmem_altmap_offset(altmap); -	clear_zone_contiguous(zone); -  	if (check_pfn_span(pfn, nr_pages, "remove"))  		return; @@ -551,13 +552,11 @@ void __remove_pages(struct zone *zone, unsigned long pfn,  		cond_resched();  		pfns = min(nr_pages, PAGES_PER_SECTION  				- (pfn & ~PAGE_SECTION_MASK)); -		__remove_section(zone, pfn, pfns, map_offset, altmap); +		__remove_section(pfn, pfns, map_offset, altmap);  		pfn += pfns;  		nr_pages -= pfns;  		map_offset = 0;  	} - -	set_zone_contiguous(zone);  }  int set_online_page_callback(online_page_callback_t callback) @@ -869,6 +868,7 @@ failed_addition:  		 (unsigned long long) pfn << PAGE_SHIFT,  		 (((unsigned long long) pfn + nr_pages) << PAGE_SHIFT) - 1);  	memory_notify(MEM_CANCEL_ONLINE, &arg); +	remove_pfn_range_from_zone(zone, pfn, nr_pages);  	mem_hotplug_done();  	return ret;  } @@ -1628,6 +1628,7 @@ static int __ref __offline_pages(unsigned long start_pfn,  	writeback_set_ratelimit();  	memory_notify(MEM_OFFLINE, &arg); +	remove_pfn_range_from_zone(zone, start_pfn, nr_pages);  	mem_hotplug_done();  	return 0;  | 

