diff options
Diffstat (limited to 'mm/memory_hotplug.c')
| -rw-r--r-- | mm/memory_hotplug.c | 34 | 
1 files changed, 20 insertions, 14 deletions
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 21890994c1d3..a444e2d7dd2b 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -1087,7 +1087,7 @@ void adjust_present_page_count(struct page *page, struct memory_group *group,  }  int mhp_init_memmap_on_memory(unsigned long pfn, unsigned long nr_pages, -			      struct zone *zone) +			      struct zone *zone, bool mhp_off_inaccessible)  {  	unsigned long end_pfn = pfn + nr_pages;  	int ret, i; @@ -1096,6 +1096,15 @@ int mhp_init_memmap_on_memory(unsigned long pfn, unsigned long nr_pages,  	if (ret)  		return ret; +	/* +	 * Memory block is accessible at this stage and hence poison the struct +	 * pages now.  If the memory block is accessible during memory hotplug +	 * addition phase, then page poisining is already performed in +	 * sparse_add_section(). +	 */ +	if (mhp_off_inaccessible) +		page_init_poison(pfn_to_page(pfn), sizeof(struct page) * nr_pages); +  	move_pfn_range_to_zone(zone, pfn, nr_pages, NULL, MIGRATE_UNMOVABLE);  	for (i = 0; i < nr_pages; i++) @@ -1328,7 +1337,7 @@ static inline bool arch_supports_memmap_on_memory(unsigned long vmemmap_size)  }  #endif -static bool mhp_supports_memmap_on_memory(unsigned long size) +bool mhp_supports_memmap_on_memory(void)  {  	unsigned long vmemmap_size = memory_block_memmap_size();  	unsigned long memmap_pages = memory_block_memmap_on_memory_pages(); @@ -1337,17 +1346,11 @@ static bool mhp_supports_memmap_on_memory(unsigned long size)  	 * Besides having arch support and the feature enabled at runtime, we  	 * need a few more assumptions to hold true:  	 * -	 * a) We span a single memory block: memory onlining/offlinin;g happens -	 *    in memory block granularity. We don't want the vmemmap of online -	 *    memory blocks to reside on offline memory blocks. In the future, -	 *    we might want to support variable-sized memory blocks to make the -	 *    feature more versatile. -	 * -	 * b) The vmemmap pages span complete PMDs: We don't want vmemmap code +	 * a) The vmemmap pages span complete PMDs: We don't want vmemmap code  	 *    to populate memory from the altmap for unrelated parts (i.e.,  	 *    other memory blocks)  	 * -	 * c) The vmemmap pages (and thereby the pages that will be exposed to +	 * b) The vmemmap pages (and thereby the pages that will be exposed to  	 *    the buddy) have to cover full pageblocks: memory onlining/offlining  	 *    code requires applicable ranges to be page-aligned, for example, to  	 *    set the migratetypes properly. @@ -1359,7 +1362,7 @@ static bool mhp_supports_memmap_on_memory(unsigned long size)  	 *       altmap as an alternative source of memory, and we do not exactly  	 *       populate a single PMD.  	 */ -	if (!mhp_memmap_on_memory() || size != memory_block_size_bytes()) +	if (!mhp_memmap_on_memory())  		return false;  	/* @@ -1382,6 +1385,7 @@ static bool mhp_supports_memmap_on_memory(unsigned long size)  	return arch_supports_memmap_on_memory(vmemmap_size);  } +EXPORT_SYMBOL_GPL(mhp_supports_memmap_on_memory);  static void __ref remove_memory_blocks_and_altmaps(u64 start, u64 size)  { @@ -1415,7 +1419,7 @@ static void __ref remove_memory_blocks_and_altmaps(u64 start, u64 size)  }  static int create_altmaps_and_memory_blocks(int nid, struct memory_group *group, -					    u64 start, u64 size) +					    u64 start, u64 size, mhp_t mhp_flags)  {  	unsigned long memblock_size = memory_block_size_bytes();  	u64 cur_start; @@ -1431,6 +1435,8 @@ static int create_altmaps_and_memory_blocks(int nid, struct memory_group *group,  		};  		mhp_altmap.free = memory_block_memmap_on_memory_pages(); +		if (mhp_flags & MHP_OFFLINE_INACCESSIBLE) +			mhp_altmap.inaccessible = true;  		params.altmap = kmemdup(&mhp_altmap, sizeof(struct vmem_altmap),  					GFP_KERNEL);  		if (!params.altmap) { @@ -1515,8 +1521,8 @@ int __ref add_memory_resource(int nid, struct resource *res, mhp_t mhp_flags)  	 * Self hosted memmap array  	 */  	if ((mhp_flags & MHP_MEMMAP_ON_MEMORY) && -	    mhp_supports_memmap_on_memory(memory_block_size_bytes())) { -		ret = create_altmaps_and_memory_blocks(nid, group, start, size); +	    mhp_supports_memmap_on_memory()) { +		ret = create_altmaps_and_memory_blocks(nid, group, start, size, mhp_flags);  		if (ret)  			goto error;  	} else {  |