mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	mem-hotplug: introduce {un}lock_memory_hotplug()
Presently hwpoison is using lock_system_sleep() to prevent a race with memory hotplug. However lock_system_sleep() is a no-op if CONFIG_HIBERNATION=n. Therefore we need a new lock. Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: Andi Kleen <andi@firstfloor.org> Cc: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Suggested-by: Hugh Dickins <hughd@google.com> Acked-by: Hugh Dickins <hughd@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
		
							parent
							
								
									4fe65cab84
								
							
						
					
					
						commit
						20d6c96b5f
					
				
					 3 changed files with 34 additions and 11 deletions
				
			
		| 
						 | 
				
			
			@ -161,6 +161,9 @@ extern void register_page_bootmem_info_node(struct pglist_data *pgdat);
 | 
			
		|||
extern void put_page_bootmem(struct page *page);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void lock_memory_hotplug(void);
 | 
			
		||||
void unlock_memory_hotplug(void);
 | 
			
		||||
 | 
			
		||||
#else /* ! CONFIG_MEMORY_HOTPLUG */
 | 
			
		||||
/*
 | 
			
		||||
 * Stub functions for when hotplug is off
 | 
			
		||||
| 
						 | 
				
			
			@ -192,6 +195,9 @@ static inline void register_page_bootmem_info_node(struct pglist_data *pgdat)
 | 
			
		|||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void lock_memory_hotplug(void) {}
 | 
			
		||||
static inline void unlock_memory_hotplug(void) {}
 | 
			
		||||
 | 
			
		||||
#endif /* ! CONFIG_MEMORY_HOTPLUG */
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_MEMORY_HOTREMOVE
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,6 +51,7 @@
 | 
			
		|||
#include <linux/slab.h>
 | 
			
		||||
#include <linux/swapops.h>
 | 
			
		||||
#include <linux/hugetlb.h>
 | 
			
		||||
#include <linux/memory_hotplug.h>
 | 
			
		||||
#include "internal.h"
 | 
			
		||||
 | 
			
		||||
int sysctl_memory_failure_early_kill __read_mostly = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -1230,11 +1231,10 @@ static int get_any_page(struct page *p, unsigned long pfn, int flags)
 | 
			
		|||
		return 1;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * The lock_system_sleep prevents a race with memory hotplug,
 | 
			
		||||
	 * because the isolation assumes there's only a single user.
 | 
			
		||||
	 * The lock_memory_hotplug prevents a race with memory hotplug.
 | 
			
		||||
	 * This is a big hammer, a better would be nicer.
 | 
			
		||||
	 */
 | 
			
		||||
	lock_system_sleep();
 | 
			
		||||
	lock_memory_hotplug();
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Isolate the page, so that it doesn't get reallocated if it
 | 
			
		||||
| 
						 | 
				
			
			@ -1264,7 +1264,7 @@ static int get_any_page(struct page *p, unsigned long pfn, int flags)
 | 
			
		|||
		ret = 1;
 | 
			
		||||
	}
 | 
			
		||||
	unset_migratetype_isolate(p);
 | 
			
		||||
	unlock_system_sleep();
 | 
			
		||||
	unlock_memory_hotplug();
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,6 +34,23 @@
 | 
			
		|||
 | 
			
		||||
#include "internal.h"
 | 
			
		||||
 | 
			
		||||
DEFINE_MUTEX(mem_hotplug_mutex);
 | 
			
		||||
 | 
			
		||||
void lock_memory_hotplug(void)
 | 
			
		||||
{
 | 
			
		||||
	mutex_lock(&mem_hotplug_mutex);
 | 
			
		||||
 | 
			
		||||
	/* for exclusive hibernation if CONFIG_HIBERNATION=y */
 | 
			
		||||
	lock_system_sleep();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void unlock_memory_hotplug(void)
 | 
			
		||||
{
 | 
			
		||||
	unlock_system_sleep();
 | 
			
		||||
	mutex_unlock(&mem_hotplug_mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* add this memory to iomem resource */
 | 
			
		||||
static struct resource *register_memory_resource(u64 start, u64 size)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -493,7 +510,7 @@ int mem_online_node(int nid)
 | 
			
		|||
	pg_data_t	*pgdat;
 | 
			
		||||
	int	ret;
 | 
			
		||||
 | 
			
		||||
	lock_system_sleep();
 | 
			
		||||
	lock_memory_hotplug();
 | 
			
		||||
	pgdat = hotadd_new_pgdat(nid, 0);
 | 
			
		||||
	if (pgdat) {
 | 
			
		||||
		ret = -ENOMEM;
 | 
			
		||||
| 
						 | 
				
			
			@ -504,7 +521,7 @@ int mem_online_node(int nid)
 | 
			
		|||
	BUG_ON(ret);
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
	unlock_system_sleep();
 | 
			
		||||
	unlock_memory_hotplug();
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -516,7 +533,7 @@ int __ref add_memory(int nid, u64 start, u64 size)
 | 
			
		|||
	struct resource *res;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	lock_system_sleep();
 | 
			
		||||
	lock_memory_hotplug();
 | 
			
		||||
 | 
			
		||||
	res = register_memory_resource(start, size);
 | 
			
		||||
	ret = -EEXIST;
 | 
			
		||||
| 
						 | 
				
			
			@ -563,7 +580,7 @@ int __ref add_memory(int nid, u64 start, u64 size)
 | 
			
		|||
		release_memory_resource(res);
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
	unlock_system_sleep();
 | 
			
		||||
	unlock_memory_hotplug();
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL_GPL(add_memory);
 | 
			
		||||
| 
						 | 
				
			
			@ -791,7 +808,7 @@ static int offline_pages(unsigned long start_pfn,
 | 
			
		|||
	if (!test_pages_in_a_zone(start_pfn, end_pfn))
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	lock_system_sleep();
 | 
			
		||||
	lock_memory_hotplug();
 | 
			
		||||
 | 
			
		||||
	zone = page_zone(pfn_to_page(start_pfn));
 | 
			
		||||
	node = zone_to_nid(zone);
 | 
			
		||||
| 
						 | 
				
			
			@ -880,7 +897,7 @@ static int offline_pages(unsigned long start_pfn,
 | 
			
		|||
	writeback_set_ratelimit();
 | 
			
		||||
 | 
			
		||||
	memory_notify(MEM_OFFLINE, &arg);
 | 
			
		||||
	unlock_system_sleep();
 | 
			
		||||
	unlock_memory_hotplug();
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
failed_removal:
 | 
			
		||||
| 
						 | 
				
			
			@ -891,7 +908,7 @@ static int offline_pages(unsigned long start_pfn,
 | 
			
		|||
	undo_isolate_page_range(start_pfn, end_pfn);
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
	unlock_system_sleep();
 | 
			
		||||
	unlock_memory_hotplug();
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue