From 98383031ed77c6eb49ab612166fef9c0efe1604a Mon Sep 17 00:00:00 2001 From: Robin Holt Date: Wed, 29 Sep 2010 14:00:55 -0500 Subject: driver core: Introduce find_memory_block_hinted which utilizes kset_find_obj_hinted. Introduce a find_memory_block_hinted() which utilizes the recently added kset_find_obj_hinted(). Signed-off-by: Robin Holt To: Dave Hansen To: Matt Tolentino Reviewed-by: KAMEZAWA Hiroyuki Signed-off-by: Greg Kroah-Hartman --- drivers/base/memory.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'drivers/base/memory.c') diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 933442f4032..a7994409b9a 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -468,28 +468,23 @@ static int add_memory_block(int nid, struct mem_section *section, return ret; } -/* - * For now, we have a linear search to go find the appropriate - * memory_block corresponding to a particular phys_index. If - * this gets to be a real problem, we can always use a radix - * tree or something here. - * - * This could be made generic for all sysdev classes. - */ -struct memory_block *find_memory_block(struct mem_section *section) +struct memory_block *find_memory_block_hinted(struct mem_section *section, + struct memory_block *hint) { struct kobject *kobj; struct sys_device *sysdev; struct memory_block *mem; char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1]; + kobj = hint ? &hint->sysdev.kobj : NULL; + /* * This only works because we know that section == sysdev->id * slightly redundant with sysdev_register() */ sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, __section_nr(section)); - kobj = kset_find_obj(&memory_sysdev_class.kset, name); + kobj = kset_find_obj_hinted(&memory_sysdev_class.kset, name, kobj); if (!kobj) return NULL; @@ -499,6 +494,19 @@ struct memory_block *find_memory_block(struct mem_section *section) return mem; } +/* + * For now, we have a linear search to go find the appropriate + * memory_block corresponding to a particular phys_index. If + * this gets to be a real problem, we can always use a radix + * tree or something here. + * + * This could be made generic for all sysdev classes. + */ +struct memory_block *find_memory_block(struct mem_section *section) +{ + return find_memory_block_hinted(section, NULL); +} + int remove_memory_block(unsigned long node_id, struct mem_section *section, int phys_device) { -- cgit v1.2.3-18-g5258 From e4619c857d1d769b1172a75ba6b6ebd1186a9c58 Mon Sep 17 00:00:00 2001 From: Nathan Fontenot Date: Tue, 19 Oct 2010 12:44:20 -0500 Subject: Driver core: Move find_memory_block routine Move the find_memory_block() routine up to avoid needing a forward declaration in subsequent patches. Signed-off-by: Nathan Fontenot Reviewed-by: Robin Holt Reviewed-By: KAMEZAWA Hiroyuki Signed-off-by: Greg Kroah-Hartman --- drivers/base/memory.c | 66 +++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) (limited to 'drivers/base/memory.c') diff --git a/drivers/base/memory.c b/drivers/base/memory.c index a7994409b9a..63c25601572 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -435,39 +435,6 @@ int __weak arch_get_memory_phys_device(unsigned long start_pfn) return 0; } -static int add_memory_block(int nid, struct mem_section *section, - unsigned long state, enum mem_add_context context) -{ - struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL); - unsigned long start_pfn; - int ret = 0; - - if (!mem) - return -ENOMEM; - - mem->phys_index = __section_nr(section); - mem->state = state; - mutex_init(&mem->state_mutex); - start_pfn = section_nr_to_pfn(mem->phys_index); - mem->phys_device = arch_get_memory_phys_device(start_pfn); - - ret = register_memory(mem, section); - if (!ret) - ret = mem_create_simple_file(mem, phys_index); - if (!ret) - ret = mem_create_simple_file(mem, state); - if (!ret) - ret = mem_create_simple_file(mem, phys_device); - if (!ret) - ret = mem_create_simple_file(mem, removable); - if (!ret) { - if (context == HOTPLUG) - ret = register_mem_sect_under_node(mem, nid); - } - - return ret; -} - struct memory_block *find_memory_block_hinted(struct mem_section *section, struct memory_block *hint) { @@ -507,6 +474,39 @@ struct memory_block *find_memory_block(struct mem_section *section) return find_memory_block_hinted(section, NULL); } +static int add_memory_block(int nid, struct mem_section *section, + unsigned long state, enum mem_add_context context) +{ + struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL); + unsigned long start_pfn; + int ret = 0; + + if (!mem) + return -ENOMEM; + + mem->phys_index = __section_nr(section); + mem->state = state; + mutex_init(&mem->state_mutex); + start_pfn = section_nr_to_pfn(mem->phys_index); + mem->phys_device = arch_get_memory_phys_device(start_pfn); + + ret = register_memory(mem, section); + if (!ret) + ret = mem_create_simple_file(mem, phys_index); + if (!ret) + ret = mem_create_simple_file(mem, state); + if (!ret) + ret = mem_create_simple_file(mem, phys_device); + if (!ret) + ret = mem_create_simple_file(mem, removable); + if (!ret) { + if (context == HOTPLUG) + ret = register_mem_sect_under_node(mem, nid); + } + + return ret; +} + int remove_memory_block(unsigned long node_id, struct mem_section *section, int phys_device) { -- cgit v1.2.3-18-g5258 From 2938ffbd466d2811a6012609684a2298eef35065 Mon Sep 17 00:00:00 2001 From: Nathan Fontenot Date: Tue, 19 Oct 2010 12:45:24 -0500 Subject: Driver core: Add mutex for adding/removing memory blocks Add a new mutex for use in adding and removing of memory blocks. This is needed to avoid any race conditions in which the same memory block could be added and removed at the same time. Signed-off-by: Nathan Fontenot Reviewed-by: Robin Holt Reviewed-By: KAMEZAWA Hiroyuki Signed-off-by: Greg Kroah-Hartman --- drivers/base/memory.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/base/memory.c') diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 63c25601572..5185bcff2de 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -27,6 +27,8 @@ #include #include +static DEFINE_MUTEX(mem_sysfs_mutex); + #define MEMORY_CLASS_NAME "memory" static struct sysdev_class memory_sysdev_class = { @@ -484,6 +486,8 @@ static int add_memory_block(int nid, struct mem_section *section, if (!mem) return -ENOMEM; + mutex_lock(&mem_sysfs_mutex); + mem->phys_index = __section_nr(section); mem->state = state; mutex_init(&mem->state_mutex); @@ -504,6 +508,7 @@ static int add_memory_block(int nid, struct mem_section *section, ret = register_mem_sect_under_node(mem, nid); } + mutex_unlock(&mem_sysfs_mutex); return ret; } @@ -512,6 +517,7 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section, { struct memory_block *mem; + mutex_lock(&mem_sysfs_mutex); mem = find_memory_block(section); unregister_mem_sect_under_nodes(mem); mem_remove_simple_file(mem, phys_index); @@ -520,6 +526,7 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section, mem_remove_simple_file(mem, removable); unregister_memory(mem, section); + mutex_unlock(&mem_sysfs_mutex); return 0; } -- cgit v1.2.3-18-g5258 From 07681215975e05a1454b0afdeef07deb0db626ee Mon Sep 17 00:00:00 2001 From: Nathan Fontenot Date: Tue, 19 Oct 2010 12:46:19 -0500 Subject: Driver core: Add section count to memory_block struct Add a section count property to the memory_block struct to track the number of memory sections that have been added/removed from a memory block. This allows us to know when the last memory section of a memory block has been removed so we can remove the memory block. Signed-off-by: Nathan Fontenot Reviewed-by: Robin Holt Reviewed-by: KAMEZAWA Hiroyuki Signed-off-by: Greg Kroah-Hartman --- drivers/base/memory.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'drivers/base/memory.c') diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 5185bcff2de..cafeaaf0428 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -490,6 +490,7 @@ static int add_memory_block(int nid, struct mem_section *section, mem->phys_index = __section_nr(section); mem->state = state; + mem->section_count++; mutex_init(&mem->state_mutex); start_pfn = section_nr_to_pfn(mem->phys_index); mem->phys_device = arch_get_memory_phys_device(start_pfn); @@ -519,12 +520,16 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section, mutex_lock(&mem_sysfs_mutex); mem = find_memory_block(section); - unregister_mem_sect_under_nodes(mem); - mem_remove_simple_file(mem, phys_index); - mem_remove_simple_file(mem, state); - mem_remove_simple_file(mem, phys_device); - mem_remove_simple_file(mem, removable); - unregister_memory(mem, section); + + mem->section_count--; + if (mem->section_count == 0) { + unregister_mem_sect_under_nodes(mem); + mem_remove_simple_file(mem, phys_index); + mem_remove_simple_file(mem, state); + mem_remove_simple_file(mem, phys_device); + mem_remove_simple_file(mem, removable); + unregister_memory(mem, section); + } mutex_unlock(&mem_sysfs_mutex); return 0; -- cgit v1.2.3-18-g5258