diff options
Diffstat (limited to 'drivers/base/memory.c')
| -rw-r--r-- | drivers/base/memory.c | 40 | 
1 files changed, 15 insertions, 25 deletions
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 84c4e1f72cbd..799b43191dea 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -19,15 +19,12 @@  #include <linux/memory.h>  #include <linux/memory_hotplug.h>  #include <linux/mm.h> -#include <linux/mutex.h>  #include <linux/stat.h>  #include <linux/slab.h>  #include <linux/atomic.h>  #include <linux/uaccess.h> -static DEFINE_MUTEX(mem_sysfs_mutex); -  #define MEMORY_CLASS_NAME	"memory"  #define to_memory_block(dev) container_of(dev, struct memory_block, dev) @@ -538,12 +535,7 @@ static ssize_t soft_offline_page_store(struct device *dev,  	if (kstrtoull(buf, 0, &pfn) < 0)  		return -EINVAL;  	pfn >>= PAGE_SHIFT; -	if (!pfn_valid(pfn)) -		return -ENXIO; -	/* Only online pages can be soft-offlined (esp., not ZONE_DEVICE). */ -	if (!pfn_to_online_page(pfn)) -		return -EIO; -	ret = soft_offline_page(pfn_to_page(pfn), 0); +	ret = soft_offline_page(pfn, 0);  	return ret == 0 ? count : ret;  } @@ -705,6 +697,8 @@ static void unregister_memory(struct memory_block *memory)   * Create memory block devices for the given memory area. Start and size   * have to be aligned to memory block granularity. Memory block devices   * will be initialized as offline. + * + * Called under device_hotplug_lock.   */  int create_memory_block_devices(unsigned long start, unsigned long size)  { @@ -718,7 +712,6 @@ int create_memory_block_devices(unsigned long start, unsigned long size)  			 !IS_ALIGNED(size, memory_block_size_bytes())))  		return -EINVAL; -	mutex_lock(&mem_sysfs_mutex);  	for (block_id = start_block_id; block_id != end_block_id; block_id++) {  		ret = init_memory_block(&mem, block_id, MEM_OFFLINE);  		if (ret) @@ -730,11 +723,12 @@ int create_memory_block_devices(unsigned long start, unsigned long size)  		for (block_id = start_block_id; block_id != end_block_id;  		     block_id++) {  			mem = find_memory_block_by_id(block_id); +			if (WARN_ON_ONCE(!mem)) +				continue;  			mem->section_count = 0;  			unregister_memory(mem);  		}  	} -	mutex_unlock(&mem_sysfs_mutex);  	return ret;  } @@ -742,6 +736,8 @@ int create_memory_block_devices(unsigned long start, unsigned long size)   * Remove memory block devices for the given memory area. Start and size   * have to be aligned to memory block granularity. Memory block devices   * have to be offline. + * + * Called under device_hotplug_lock.   */  void remove_memory_block_devices(unsigned long start, unsigned long size)  { @@ -754,7 +750,6 @@ void remove_memory_block_devices(unsigned long start, unsigned long size)  			 !IS_ALIGNED(size, memory_block_size_bytes())))  		return; -	mutex_lock(&mem_sysfs_mutex);  	for (block_id = start_block_id; block_id != end_block_id; block_id++) {  		mem = find_memory_block_by_id(block_id);  		if (WARN_ON_ONCE(!mem)) @@ -763,7 +758,6 @@ void remove_memory_block_devices(unsigned long start, unsigned long size)  		unregister_memory_block_under_nodes(mem);  		unregister_memory(mem);  	} -	mutex_unlock(&mem_sysfs_mutex);  }  /* return true if the memory block is offlined, otherwise, return false */ @@ -797,12 +791,13 @@ static const struct attribute_group *memory_root_attr_groups[] = {  };  /* - * Initialize the sysfs support for memory devices... + * Initialize the sysfs support for memory devices. At the time this function + * is called, we cannot have concurrent creation/deletion of memory block + * devices, the device_hotplug_lock is not needed.   */  void __init memory_dev_init(void)  {  	int ret; -	int err;  	unsigned long block_sz, nr;  	/* Validate the configured memory block size */ @@ -813,24 +808,19 @@ void __init memory_dev_init(void)  	ret = subsys_system_register(&memory_subsys, memory_root_attr_groups);  	if (ret) -		goto out; +		panic("%s() failed to register subsystem: %d\n", __func__, ret);  	/*  	 * Create entries for memory sections that were found  	 * during boot and have been initialized  	 */ -	mutex_lock(&mem_sysfs_mutex);  	for (nr = 0; nr <= __highest_present_section_nr;  	     nr += sections_per_block) { -		err = add_memory_block(nr); -		if (!ret) -			ret = err; +		ret = add_memory_block(nr); +		if (ret) +			panic("%s() failed to add memory block: %d\n", __func__, +			      ret);  	} -	mutex_unlock(&mem_sysfs_mutex); - -out: -	if (ret) -		panic("%s() failed: %d\n", __func__, ret);  }  /**  |