* [PATCH 0/8] v3 De-couple sysfs memory directories from memory sections @ 2010-07-20 3:45 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:45 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: greg, KAMEZAWA Hiroyuki This set of patches de-couples the idea that there is a single directory in sysfs for each memory section. The intent of the patches is to reduce the number of sysfs directories created to resolve a boot-time performance issue. On very large systems boot time are getting very long (as seen on powerpc hardware) due to the enormous number of sysfs directories being created. On a system with 1 TB of memory we create ~63,000 directories. For even larger systems boot times are being measured in hours. This set of patches allows for each directory created in sysfs to cover more than one memory section. The default behavior for sysfs directory creation is the same, in that each directory represents a single memory section. A new file 'end_phys_index' in each directory contains the physical_id of the last memory section covered by the directory so that users can easily determine the memory section range of a directory. -Nathan Fontenot ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 0/8] v3 De-couple sysfs memory directories from memory sections @ 2010-07-20 3:45 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:45 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: KAMEZAWA Hiroyuki, greg This set of patches de-couples the idea that there is a single directory in sysfs for each memory section. The intent of the patches is to reduce the number of sysfs directories created to resolve a boot-time performance issue. On very large systems boot time are getting very long (as seen on powerpc hardware) due to the enormous number of sysfs directories being created. On a system with 1 TB of memory we create ~63,000 directories. For even larger systems boot times are being measured in hours. This set of patches allows for each directory created in sysfs to cover more than one memory section. The default behavior for sysfs directory creation is the same, in that each directory represents a single memory section. A new file 'end_phys_index' in each directory contains the physical_id of the last memory section covered by the directory so that users can easily determine the memory section range of a directory. -Nathan Fontenot -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 0/8] v3 De-couple sysfs memory directories from memory sections @ 2010-07-20 3:45 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:45 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: KAMEZAWA Hiroyuki, greg This set of patches de-couples the idea that there is a single directory in sysfs for each memory section. The intent of the patches is to reduce the number of sysfs directories created to resolve a boot-time performance issue. On very large systems boot time are getting very long (as seen on powerpc hardware) due to the enormous number of sysfs directories being created. On a system with 1 TB of memory we create ~63,000 directories. For even larger systems boot times are being measured in hours. This set of patches allows for each directory created in sysfs to cover more than one memory section. The default behavior for sysfs directory creation is the same, in that each directory represents a single memory section. A new file 'end_phys_index' in each directory contains the physical_id of the last memory section covered by the directory so that users can easily determine the memory section range of a directory. -Nathan Fontenot ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 1/8] v3 Move the find_memory_block() routine up 2010-07-20 3:45 ` Nathan Fontenot (?) @ 2010-07-20 3:51 ` Nathan Fontenot -1 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:51 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: greg, KAMEZAWA Hiroyuki Move the find_me mory_block() routine up to avoid needing a forward declaration in subsequent patches. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> --- drivers/base/memory.c | 62 +++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) Index: linux-2.6/drivers/base/memory.c =================================================================== --- linux-2.6.orig/drivers/base/memory.c 2010-07-16 12:41:30.000000000 -0500 +++ linux-2.6/drivers/base/memory.c 2010-07-19 20:42:11.000000000 -0500 @@ -435,6 +435,37 @@ int __weak arch_get_memory_phys_device(u return 0; } +/* + * 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 kobject *kobj; + struct sys_device *sysdev; + struct memory_block *mem; + char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1]; + + /* + * 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); + if (!kobj) + return NULL; + + sysdev = container_of(kobj, struct sys_device, kobj); + mem = container_of(sysdev, struct memory_block, sysdev); + + return mem; +} + static int add_memory_block(int nid, struct mem_section *section, unsigned long state, enum mem_add_context context) { @@ -468,37 +499,6 @@ static int add_memory_block(int nid, str 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 kobject *kobj; - struct sys_device *sysdev; - struct memory_block *mem; - char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1]; - - /* - * 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); - if (!kobj) - return NULL; - - sysdev = container_of(kobj, struct sys_device, kobj); - mem = container_of(sysdev, struct memory_block, sysdev); - - return mem; -} - int remove_memory_block(unsigned long node_id, struct mem_section *section, int phys_device) { ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 1/8] v3 Move the find_memory_block() routine up @ 2010-07-20 3:51 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:51 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: KAMEZAWA Hiroyuki, greg Move the find_me mory_block() routine up to avoid needing a forward declaration in subsequent patches. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> --- drivers/base/memory.c | 62 +++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) Index: linux-2.6/drivers/base/memory.c =================================================================== --- linux-2.6.orig/drivers/base/memory.c 2010-07-16 12:41:30.000000000 -0500 +++ linux-2.6/drivers/base/memory.c 2010-07-19 20:42:11.000000000 -0500 @@ -435,6 +435,37 @@ int __weak arch_get_memory_phys_device(u return 0; } +/* + * 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 kobject *kobj; + struct sys_device *sysdev; + struct memory_block *mem; + char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1]; + + /* + * 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); + if (!kobj) + return NULL; + + sysdev = container_of(kobj, struct sys_device, kobj); + mem = container_of(sysdev, struct memory_block, sysdev); + + return mem; +} + static int add_memory_block(int nid, struct mem_section *section, unsigned long state, enum mem_add_context context) { @@ -468,37 +499,6 @@ static int add_memory_block(int nid, str 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 kobject *kobj; - struct sys_device *sysdev; - struct memory_block *mem; - char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1]; - - /* - * 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); - if (!kobj) - return NULL; - - sysdev = container_of(kobj, struct sys_device, kobj); - mem = container_of(sysdev, struct memory_block, sysdev); - - return mem; -} - int remove_memory_block(unsigned long node_id, struct mem_section *section, int phys_device) { -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 1/8] v3 Move the find_memory_block() routine up @ 2010-07-20 3:51 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:51 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: KAMEZAWA Hiroyuki, greg Move the find_me mory_block() routine up to avoid needing a forward declaration in subsequent patches. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> --- drivers/base/memory.c | 62 +++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) Index: linux-2.6/drivers/base/memory.c =================================================================== --- linux-2.6.orig/drivers/base/memory.c 2010-07-16 12:41:30.000000000 -0500 +++ linux-2.6/drivers/base/memory.c 2010-07-19 20:42:11.000000000 -0500 @@ -435,6 +435,37 @@ int __weak arch_get_memory_phys_device(u return 0; } +/* + * 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 kobject *kobj; + struct sys_device *sysdev; + struct memory_block *mem; + char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1]; + + /* + * 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); + if (!kobj) + return NULL; + + sysdev = container_of(kobj, struct sys_device, kobj); + mem = container_of(sysdev, struct memory_block, sysdev); + + return mem; +} + static int add_memory_block(int nid, struct mem_section *section, unsigned long state, enum mem_add_context context) { @@ -468,37 +499,6 @@ static int add_memory_block(int nid, str 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 kobject *kobj; - struct sys_device *sysdev; - struct memory_block *mem; - char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1]; - - /* - * 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); - if (!kobj) - return NULL; - - sysdev = container_of(kobj, struct sys_device, kobj); - mem = container_of(sysdev, struct memory_block, sysdev); - - return mem; -} - int remove_memory_block(unsigned long node_id, struct mem_section *section, int phys_device) { ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 1/8] v3 Move the find_memory_block() routine up 2010-07-20 3:51 ` Nathan Fontenot (?) @ 2010-07-20 6:55 ` KAMEZAWA Hiroyuki -1 siblings, 0 replies; 90+ messages in thread From: KAMEZAWA Hiroyuki @ 2010-07-20 6:55 UTC (permalink / raw) To: Nathan Fontenot; +Cc: linux-mm, greg, linux-kernel, linuxppc-dev On Mon, 19 Jul 2010 22:51:42 -0500 Nathan Fontenot <nfont@austin.ibm.com> wrote: > Move the find_me mory_block() routine up to avoid needing a forward > declaration in subsequent patches. > > Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> > --- > drivers/base/memory.c | 62 +++++++++++++++++++++++++------------------------- > 1 file changed, 31 insertions(+), 31 deletions(-) > > Index: linux-2.6/drivers/base/memory.c > =================================================================== > --- linux-2.6.orig/drivers/base/memory.c 2010-07-16 12:41:30.000000000 -0500 > +++ linux-2.6/drivers/base/memory.c 2010-07-19 20:42:11.000000000 -0500 > @@ -435,6 +435,37 @@ int __weak arch_get_memory_phys_device(u > return 0; > } > > +/* > + * 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 kobject *kobj; > + struct sys_device *sysdev; > + struct memory_block *mem; > + char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1]; > + > + /* > + * 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); > + if (!kobj) > + return NULL; > + > + sysdev = container_of(kobj, struct sys_device, kobj); > + mem = container_of(sysdev, struct memory_block, sysdev); > + > + return mem; > +} > + > static int add_memory_block(int nid, struct mem_section *section, > unsigned long state, enum mem_add_context context) > { > @@ -468,37 +499,6 @@ static int add_memory_block(int nid, str > 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 kobject *kobj; > - struct sys_device *sysdev; > - struct memory_block *mem; > - char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1]; > - > - /* > - * 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); > - if (!kobj) > - return NULL; > - > - sysdev = container_of(kobj, struct sys_device, kobj); > - mem = container_of(sysdev, struct memory_block, sysdev); > - > - return mem; > -} > - > int remove_memory_block(unsigned long node_id, struct mem_section *section, > int phys_device) > { > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ > ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 1/8] v3 Move the find_memory_block() routine up @ 2010-07-20 6:55 ` KAMEZAWA Hiroyuki 0 siblings, 0 replies; 90+ messages in thread From: KAMEZAWA Hiroyuki @ 2010-07-20 6:55 UTC (permalink / raw) To: Nathan Fontenot; +Cc: linux-kernel, linux-mm, linuxppc-dev, greg On Mon, 19 Jul 2010 22:51:42 -0500 Nathan Fontenot <nfont@austin.ibm.com> wrote: > Move the find_me mory_block() routine up to avoid needing a forward > declaration in subsequent patches. > > Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> > --- > drivers/base/memory.c | 62 +++++++++++++++++++++++++------------------------- > 1 file changed, 31 insertions(+), 31 deletions(-) > > Index: linux-2.6/drivers/base/memory.c > =================================================================== > --- linux-2.6.orig/drivers/base/memory.c 2010-07-16 12:41:30.000000000 -0500 > +++ linux-2.6/drivers/base/memory.c 2010-07-19 20:42:11.000000000 -0500 > @@ -435,6 +435,37 @@ int __weak arch_get_memory_phys_device(u > return 0; > } > > +/* > + * 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 kobject *kobj; > + struct sys_device *sysdev; > + struct memory_block *mem; > + char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1]; > + > + /* > + * 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); > + if (!kobj) > + return NULL; > + > + sysdev = container_of(kobj, struct sys_device, kobj); > + mem = container_of(sysdev, struct memory_block, sysdev); > + > + return mem; > +} > + > static int add_memory_block(int nid, struct mem_section *section, > unsigned long state, enum mem_add_context context) > { > @@ -468,37 +499,6 @@ static int add_memory_block(int nid, str > 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 kobject *kobj; > - struct sys_device *sysdev; > - struct memory_block *mem; > - char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1]; > - > - /* > - * 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); > - if (!kobj) > - return NULL; > - > - sysdev = container_of(kobj, struct sys_device, kobj); > - mem = container_of(sysdev, struct memory_block, sysdev); > - > - return mem; > -} > - > int remove_memory_block(unsigned long node_id, struct mem_section *section, > int phys_device) > { > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ > -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 1/8] v3 Move the find_memory_block() routine up @ 2010-07-20 6:55 ` KAMEZAWA Hiroyuki 0 siblings, 0 replies; 90+ messages in thread From: KAMEZAWA Hiroyuki @ 2010-07-20 6:55 UTC (permalink / raw) To: Nathan Fontenot; +Cc: linux-kernel, linux-mm, linuxppc-dev, greg On Mon, 19 Jul 2010 22:51:42 -0500 Nathan Fontenot <nfont@austin.ibm.com> wrote: > Move the find_me mory_block() routine up to avoid needing a forward > declaration in subsequent patches. > > Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> > --- > drivers/base/memory.c | 62 +++++++++++++++++++++++++------------------------- > 1 file changed, 31 insertions(+), 31 deletions(-) > > Index: linux-2.6/drivers/base/memory.c > =================================================================== > --- linux-2.6.orig/drivers/base/memory.c 2010-07-16 12:41:30.000000000 -0500 > +++ linux-2.6/drivers/base/memory.c 2010-07-19 20:42:11.000000000 -0500 > @@ -435,6 +435,37 @@ int __weak arch_get_memory_phys_device(u > return 0; > } > > +/* > + * 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 kobject *kobj; > + struct sys_device *sysdev; > + struct memory_block *mem; > + char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1]; > + > + /* > + * 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); > + if (!kobj) > + return NULL; > + > + sysdev = container_of(kobj, struct sys_device, kobj); > + mem = container_of(sysdev, struct memory_block, sysdev); > + > + return mem; > +} > + > static int add_memory_block(int nid, struct mem_section *section, > unsigned long state, enum mem_add_context context) > { > @@ -468,37 +499,6 @@ static int add_memory_block(int nid, str > 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 kobject *kobj; > - struct sys_device *sysdev; > - struct memory_block *mem; > - char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1]; > - > - /* > - * 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); > - if (!kobj) > - return NULL; > - > - sysdev = container_of(kobj, struct sys_device, kobj); > - mem = container_of(sysdev, struct memory_block, sysdev); > - > - return mem; > -} > - > int remove_memory_block(unsigned long node_id, struct mem_section *section, > int phys_device) > { > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ > ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 2/8] v3 Add new phys_index properties 2010-07-20 3:45 ` Nathan Fontenot (?) @ 2010-07-20 3:52 ` Nathan Fontenot -1 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:52 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: greg, KAMEZAWA Hiroyuki Update the 'phys_index' properties of a memory block to include a 'start_phys_index' which is the same as the current 'phys_index' property. This also adds an 'end_phys_index' property to indicate the id of the last section in th memory block. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> --- drivers/base/memory.c | 32 ++++++++++++++++++++++---------- include/linux/memory.h | 3 ++- 2 files changed, 24 insertions(+), 11 deletions(-) Index: linux-2.6/drivers/base/memory.c =================================================================== --- linux-2.6.orig/drivers/base/memory.c 2010-07-19 20:42:11.000000000 -0500 +++ linux-2.6/drivers/base/memory.c 2010-07-19 20:43:49.000000000 -0500 @@ -109,12 +109,20 @@ unregister_memory(struct memory_block *m * uses. */ -static ssize_t show_mem_phys_index(struct sys_device *dev, +static ssize_t show_mem_start_phys_index(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) { struct memory_block *mem = container_of(dev, struct memory_block, sysdev); - return sprintf(buf, "%08lx\n", mem->phys_index); + return sprintf(buf, "%08lx\n", mem->start_phys_index); +} + +static ssize_t show_mem_end_phys_index(struct sys_device *dev, + struct sysdev_attribute *attr, char *buf) +{ + struct memory_block *mem = + container_of(dev, struct memory_block, sysdev); + return sprintf(buf, "%08lx\n", mem->end_phys_index); } /* @@ -128,7 +136,7 @@ static ssize_t show_mem_removable(struct struct memory_block *mem = container_of(dev, struct memory_block, sysdev); - start_pfn = section_nr_to_pfn(mem->phys_index); + start_pfn = section_nr_to_pfn(mem->start_phys_index); ret = is_mem_section_removable(start_pfn, PAGES_PER_SECTION); return sprintf(buf, "%d\n", ret); } @@ -191,7 +199,7 @@ memory_block_action(struct memory_block int ret; int old_state = mem->state; - psection = mem->phys_index; + psection = mem->start_phys_index; first_page = pfn_to_page(psection << PFN_SECTION_SHIFT); /* @@ -264,7 +272,7 @@ store_mem_state(struct sys_device *dev, int ret = -EINVAL; mem = container_of(dev, struct memory_block, sysdev); - phys_section_nr = mem->phys_index; + phys_section_nr = mem->start_phys_index; if (!present_section_nr(phys_section_nr)) goto out; @@ -296,7 +304,8 @@ static ssize_t show_phys_device(struct s return sprintf(buf, "%d\n", mem->phys_device); } -static SYSDEV_ATTR(phys_index, 0444, show_mem_phys_index, NULL); +static SYSDEV_ATTR(start_phys_index, 0444, show_mem_start_phys_index, NULL); +static SYSDEV_ATTR(end_phys_index, 0444, show_mem_end_phys_index, NULL); static SYSDEV_ATTR(state, 0644, show_mem_state, store_mem_state); static SYSDEV_ATTR(phys_device, 0444, show_phys_device, NULL); static SYSDEV_ATTR(removable, 0444, show_mem_removable, NULL); @@ -476,15 +485,17 @@ static int add_memory_block(int nid, str if (!mem) return -ENOMEM; - mem->phys_index = __section_nr(section); + mem->start_phys_index = __section_nr(section); mem->state = state; mutex_init(&mem->state_mutex); - start_pfn = section_nr_to_pfn(mem->phys_index); + start_pfn = section_nr_to_pfn(mem->start_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); + ret = mem_create_simple_file(mem, start_phys_index); + if (!ret) + ret = mem_create_simple_file(mem, end_phys_index); if (!ret) ret = mem_create_simple_file(mem, state); if (!ret) @@ -506,7 +517,8 @@ int remove_memory_block(unsigned long no mem = find_memory_block(section); unregister_mem_sect_under_nodes(mem); - mem_remove_simple_file(mem, phys_index); + mem_remove_simple_file(mem, start_phys_index); + mem_remove_simple_file(mem, end_phys_index); mem_remove_simple_file(mem, state); mem_remove_simple_file(mem, phys_device); mem_remove_simple_file(mem, removable); Index: linux-2.6/include/linux/memory.h =================================================================== --- linux-2.6.orig/include/linux/memory.h 2010-07-19 20:42:11.000000000 -0500 +++ linux-2.6/include/linux/memory.h 2010-07-19 20:43:49.000000000 -0500 @@ -21,7 +21,8 @@ #include <linux/mutex.h> struct memory_block { - unsigned long phys_index; + unsigned long start_phys_index; + unsigned long end_phys_index; unsigned long state; /* * This serializes all state change requests. It isn't ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 2/8] v3 Add new phys_index properties @ 2010-07-20 3:52 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:52 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: KAMEZAWA Hiroyuki, greg Update the 'phys_index' properties of a memory block to include a 'start_phys_index' which is the same as the current 'phys_index' property. This also adds an 'end_phys_index' property to indicate the id of the last section in th memory block. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> --- drivers/base/memory.c | 32 ++++++++++++++++++++++---------- include/linux/memory.h | 3 ++- 2 files changed, 24 insertions(+), 11 deletions(-) Index: linux-2.6/drivers/base/memory.c =================================================================== --- linux-2.6.orig/drivers/base/memory.c 2010-07-19 20:42:11.000000000 -0500 +++ linux-2.6/drivers/base/memory.c 2010-07-19 20:43:49.000000000 -0500 @@ -109,12 +109,20 @@ unregister_memory(struct memory_block *m * uses. */ -static ssize_t show_mem_phys_index(struct sys_device *dev, +static ssize_t show_mem_start_phys_index(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) { struct memory_block *mem = container_of(dev, struct memory_block, sysdev); - return sprintf(buf, "%08lx\n", mem->phys_index); + return sprintf(buf, "%08lx\n", mem->start_phys_index); +} + +static ssize_t show_mem_end_phys_index(struct sys_device *dev, + struct sysdev_attribute *attr, char *buf) +{ + struct memory_block *mem = + container_of(dev, struct memory_block, sysdev); + return sprintf(buf, "%08lx\n", mem->end_phys_index); } /* @@ -128,7 +136,7 @@ static ssize_t show_mem_removable(struct struct memory_block *mem = container_of(dev, struct memory_block, sysdev); - start_pfn = section_nr_to_pfn(mem->phys_index); + start_pfn = section_nr_to_pfn(mem->start_phys_index); ret = is_mem_section_removable(start_pfn, PAGES_PER_SECTION); return sprintf(buf, "%d\n", ret); } @@ -191,7 +199,7 @@ memory_block_action(struct memory_block int ret; int old_state = mem->state; - psection = mem->phys_index; + psection = mem->start_phys_index; first_page = pfn_to_page(psection << PFN_SECTION_SHIFT); /* @@ -264,7 +272,7 @@ store_mem_state(struct sys_device *dev, int ret = -EINVAL; mem = container_of(dev, struct memory_block, sysdev); - phys_section_nr = mem->phys_index; + phys_section_nr = mem->start_phys_index; if (!present_section_nr(phys_section_nr)) goto out; @@ -296,7 +304,8 @@ static ssize_t show_phys_device(struct s return sprintf(buf, "%d\n", mem->phys_device); } -static SYSDEV_ATTR(phys_index, 0444, show_mem_phys_index, NULL); +static SYSDEV_ATTR(start_phys_index, 0444, show_mem_start_phys_index, NULL); +static SYSDEV_ATTR(end_phys_index, 0444, show_mem_end_phys_index, NULL); static SYSDEV_ATTR(state, 0644, show_mem_state, store_mem_state); static SYSDEV_ATTR(phys_device, 0444, show_phys_device, NULL); static SYSDEV_ATTR(removable, 0444, show_mem_removable, NULL); @@ -476,15 +485,17 @@ static int add_memory_block(int nid, str if (!mem) return -ENOMEM; - mem->phys_index = __section_nr(section); + mem->start_phys_index = __section_nr(section); mem->state = state; mutex_init(&mem->state_mutex); - start_pfn = section_nr_to_pfn(mem->phys_index); + start_pfn = section_nr_to_pfn(mem->start_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); + ret = mem_create_simple_file(mem, start_phys_index); + if (!ret) + ret = mem_create_simple_file(mem, end_phys_index); if (!ret) ret = mem_create_simple_file(mem, state); if (!ret) @@ -506,7 +517,8 @@ int remove_memory_block(unsigned long no mem = find_memory_block(section); unregister_mem_sect_under_nodes(mem); - mem_remove_simple_file(mem, phys_index); + mem_remove_simple_file(mem, start_phys_index); + mem_remove_simple_file(mem, end_phys_index); mem_remove_simple_file(mem, state); mem_remove_simple_file(mem, phys_device); mem_remove_simple_file(mem, removable); Index: linux-2.6/include/linux/memory.h =================================================================== --- linux-2.6.orig/include/linux/memory.h 2010-07-19 20:42:11.000000000 -0500 +++ linux-2.6/include/linux/memory.h 2010-07-19 20:43:49.000000000 -0500 @@ -21,7 +21,8 @@ #include <linux/mutex.h> struct memory_block { - unsigned long phys_index; + unsigned long start_phys_index; + unsigned long end_phys_index; unsigned long state; /* * This serializes all state change requests. It isn't -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 2/8] v3 Add new phys_index properties @ 2010-07-20 3:52 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:52 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: KAMEZAWA Hiroyuki, greg Update the 'phys_index' properties of a memory block to include a 'start_phys_index' which is the same as the current 'phys_index' property. This also adds an 'end_phys_index' property to indicate the id of the last section in th memory block. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> --- drivers/base/memory.c | 32 ++++++++++++++++++++++---------- include/linux/memory.h | 3 ++- 2 files changed, 24 insertions(+), 11 deletions(-) Index: linux-2.6/drivers/base/memory.c =================================================================== --- linux-2.6.orig/drivers/base/memory.c 2010-07-19 20:42:11.000000000 -0500 +++ linux-2.6/drivers/base/memory.c 2010-07-19 20:43:49.000000000 -0500 @@ -109,12 +109,20 @@ unregister_memory(struct memory_block *m * uses. */ -static ssize_t show_mem_phys_index(struct sys_device *dev, +static ssize_t show_mem_start_phys_index(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) { struct memory_block *mem = container_of(dev, struct memory_block, sysdev); - return sprintf(buf, "%08lx\n", mem->phys_index); + return sprintf(buf, "%08lx\n", mem->start_phys_index); +} + +static ssize_t show_mem_end_phys_index(struct sys_device *dev, + struct sysdev_attribute *attr, char *buf) +{ + struct memory_block *mem = + container_of(dev, struct memory_block, sysdev); + return sprintf(buf, "%08lx\n", mem->end_phys_index); } /* @@ -128,7 +136,7 @@ static ssize_t show_mem_removable(struct struct memory_block *mem = container_of(dev, struct memory_block, sysdev); - start_pfn = section_nr_to_pfn(mem->phys_index); + start_pfn = section_nr_to_pfn(mem->start_phys_index); ret = is_mem_section_removable(start_pfn, PAGES_PER_SECTION); return sprintf(buf, "%d\n", ret); } @@ -191,7 +199,7 @@ memory_block_action(struct memory_block int ret; int old_state = mem->state; - psection = mem->phys_index; + psection = mem->start_phys_index; first_page = pfn_to_page(psection << PFN_SECTION_SHIFT); /* @@ -264,7 +272,7 @@ store_mem_state(struct sys_device *dev, int ret = -EINVAL; mem = container_of(dev, struct memory_block, sysdev); - phys_section_nr = mem->phys_index; + phys_section_nr = mem->start_phys_index; if (!present_section_nr(phys_section_nr)) goto out; @@ -296,7 +304,8 @@ static ssize_t show_phys_device(struct s return sprintf(buf, "%d\n", mem->phys_device); } -static SYSDEV_ATTR(phys_index, 0444, show_mem_phys_index, NULL); +static SYSDEV_ATTR(start_phys_index, 0444, show_mem_start_phys_index, NULL); +static SYSDEV_ATTR(end_phys_index, 0444, show_mem_end_phys_index, NULL); static SYSDEV_ATTR(state, 0644, show_mem_state, store_mem_state); static SYSDEV_ATTR(phys_device, 0444, show_phys_device, NULL); static SYSDEV_ATTR(removable, 0444, show_mem_removable, NULL); @@ -476,15 +485,17 @@ static int add_memory_block(int nid, str if (!mem) return -ENOMEM; - mem->phys_index = __section_nr(section); + mem->start_phys_index = __section_nr(section); mem->state = state; mutex_init(&mem->state_mutex); - start_pfn = section_nr_to_pfn(mem->phys_index); + start_pfn = section_nr_to_pfn(mem->start_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); + ret = mem_create_simple_file(mem, start_phys_index); + if (!ret) + ret = mem_create_simple_file(mem, end_phys_index); if (!ret) ret = mem_create_simple_file(mem, state); if (!ret) @@ -506,7 +517,8 @@ int remove_memory_block(unsigned long no mem = find_memory_block(section); unregister_mem_sect_under_nodes(mem); - mem_remove_simple_file(mem, phys_index); + mem_remove_simple_file(mem, start_phys_index); + mem_remove_simple_file(mem, end_phys_index); mem_remove_simple_file(mem, state); mem_remove_simple_file(mem, phys_device); mem_remove_simple_file(mem, removable); Index: linux-2.6/include/linux/memory.h =================================================================== --- linux-2.6.orig/include/linux/memory.h 2010-07-19 20:42:11.000000000 -0500 +++ linux-2.6/include/linux/memory.h 2010-07-19 20:43:49.000000000 -0500 @@ -21,7 +21,8 @@ #include <linux/mutex.h> struct memory_block { - unsigned long phys_index; + unsigned long start_phys_index; + unsigned long end_phys_index; unsigned long state; /* * This serializes all state change requests. It isn't ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 2/8] v3 Add new phys_index properties 2010-07-20 3:52 ` Nathan Fontenot (?) @ 2010-07-20 6:57 ` KAMEZAWA Hiroyuki -1 siblings, 0 replies; 90+ messages in thread From: KAMEZAWA Hiroyuki @ 2010-07-20 6:57 UTC (permalink / raw) To: Nathan Fontenot; +Cc: linux-mm, greg, linux-kernel, linuxppc-dev On Mon, 19 Jul 2010 22:52:50 -0500 Nathan Fontenot <nfont@austin.ibm.com> wrote: > Update the 'phys_index' properties of a memory block to include a > 'start_phys_index' which is the same as the current 'phys_index' property. > This also adds an 'end_phys_index' property to indicate the id of the > last section in th memory block. > > Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> No, please remain "phys_index" as it is. please don't rename it. IMHO, just adding end_phys_index is better. please avoid interface change AFAP. Do you have a problem if phys_index means start_phys_index ? Thanks, -Kame ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 2/8] v3 Add new phys_index properties @ 2010-07-20 6:57 ` KAMEZAWA Hiroyuki 0 siblings, 0 replies; 90+ messages in thread From: KAMEZAWA Hiroyuki @ 2010-07-20 6:57 UTC (permalink / raw) To: Nathan Fontenot; +Cc: linux-kernel, linux-mm, linuxppc-dev, greg On Mon, 19 Jul 2010 22:52:50 -0500 Nathan Fontenot <nfont@austin.ibm.com> wrote: > Update the 'phys_index' properties of a memory block to include a > 'start_phys_index' which is the same as the current 'phys_index' property. > This also adds an 'end_phys_index' property to indicate the id of the > last section in th memory block. > > Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> No, please remain "phys_index" as it is. please don't rename it. IMHO, just adding end_phys_index is better. please avoid interface change AFAP. Do you have a problem if phys_index means start_phys_index ? Thanks, -Kame -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 2/8] v3 Add new phys_index properties @ 2010-07-20 6:57 ` KAMEZAWA Hiroyuki 0 siblings, 0 replies; 90+ messages in thread From: KAMEZAWA Hiroyuki @ 2010-07-20 6:57 UTC (permalink / raw) To: Nathan Fontenot; +Cc: linux-kernel, linux-mm, linuxppc-dev, greg On Mon, 19 Jul 2010 22:52:50 -0500 Nathan Fontenot <nfont@austin.ibm.com> wrote: > Update the 'phys_index' properties of a memory block to include a > 'start_phys_index' which is the same as the current 'phys_index' property. > This also adds an 'end_phys_index' property to indicate the id of the > last section in th memory block. > > Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> No, please remain "phys_index" as it is. please don't rename it. IMHO, just adding end_phys_index is better. please avoid interface change AFAP. Do you have a problem if phys_index means start_phys_index ? Thanks, -Kame ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 2/8] v3 Add new phys_index properties 2010-07-20 3:52 ` Nathan Fontenot (?) @ 2010-07-20 13:24 ` Nathan Fontenot -1 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 13:24 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: greg, KAMEZAWA Hiroyuki Update the 'phys_index' properties of a memory block to include a 'start_phys_index' which is the same as the current 'phys_index' property. This also adds an 'end_phys_index' property to indicate the id of the last section in th memory block. Patch updated to keep the name of the phys_index property instead of renaming it to start_phys_index. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> --- drivers/base/memory.c | 28 ++++++++++++++++++++-------- include/linux/memory.h | 3 ++- 2 files changed, 22 insertions(+), 9 deletions(-) Index: linux-2.6/drivers/base/memory.c =================================================================== --- linux-2.6.orig/drivers/base/memory.c 2010-07-19 20:42:11.000000000 -0500 +++ linux-2.6/drivers/base/memory.c 2010-07-20 06:38:21.000000000 -0500 @@ -109,12 +109,20 @@ unregister_memory(struct memory_block *m * uses. */ -static ssize_t show_mem_phys_index(struct sys_device *dev, +static ssize_t show_mem_start_phys_index(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) { struct memory_block *mem = container_of(dev, struct memory_block, sysdev); - return sprintf(buf, "%08lx\n", mem->phys_index); + return sprintf(buf, "%08lx\n", mem->start_phys_index); +} + +static ssize_t show_mem_end_phys_index(struct sys_device *dev, + struct sysdev_attribute *attr, char *buf) +{ + struct memory_block *mem = + container_of(dev, struct memory_block, sysdev); + return sprintf(buf, "%08lx\n", mem->end_phys_index); } /* @@ -128,7 +136,7 @@ static ssize_t show_mem_removable(struct struct memory_block *mem = container_of(dev, struct memory_block, sysdev); - start_pfn = section_nr_to_pfn(mem->phys_index); + start_pfn = section_nr_to_pfn(mem->start_phys_index); ret = is_mem_section_removable(start_pfn, PAGES_PER_SECTION); return sprintf(buf, "%d\n", ret); } @@ -191,7 +199,7 @@ memory_block_action(struct memory_block int ret; int old_state = mem->state; - psection = mem->phys_index; + psection = mem->start_phys_index; first_page = pfn_to_page(psection << PFN_SECTION_SHIFT); /* @@ -264,7 +272,7 @@ store_mem_state(struct sys_device *dev, int ret = -EINVAL; mem = container_of(dev, struct memory_block, sysdev); - phys_section_nr = mem->phys_index; + phys_section_nr = mem->start_phys_index; if (!present_section_nr(phys_section_nr)) goto out; @@ -296,7 +304,8 @@ static ssize_t show_phys_device(struct s return sprintf(buf, "%d\n", mem->phys_device); } -static SYSDEV_ATTR(phys_index, 0444, show_mem_phys_index, NULL); +static SYSDEV_ATTR(phys_index, 0444, show_mem_start_phys_index, NULL); +static SYSDEV_ATTR(end_phys_index, 0444, show_mem_end_phys_index, NULL); static SYSDEV_ATTR(state, 0644, show_mem_state, store_mem_state); static SYSDEV_ATTR(phys_device, 0444, show_phys_device, NULL); static SYSDEV_ATTR(removable, 0444, show_mem_removable, NULL); @@ -476,16 +485,18 @@ static int add_memory_block(int nid, str if (!mem) return -ENOMEM; - mem->phys_index = __section_nr(section); + mem->start_phys_index = __section_nr(section); mem->state = state; mutex_init(&mem->state_mutex); - start_pfn = section_nr_to_pfn(mem->phys_index); + start_pfn = section_nr_to_pfn(mem->start_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, end_phys_index); + if (!ret) ret = mem_create_simple_file(mem, state); if (!ret) ret = mem_create_simple_file(mem, phys_device); @@ -507,6 +518,7 @@ int remove_memory_block(unsigned long no mem = find_memory_block(section); unregister_mem_sect_under_nodes(mem); mem_remove_simple_file(mem, phys_index); + mem_remove_simple_file(mem, end_phys_index); mem_remove_simple_file(mem, state); mem_remove_simple_file(mem, phys_device); mem_remove_simple_file(mem, removable); Index: linux-2.6/include/linux/memory.h =================================================================== --- linux-2.6.orig/include/linux/memory.h 2010-07-19 20:42:11.000000000 -0500 +++ linux-2.6/include/linux/memory.h 2010-07-20 06:35:38.000000000 -0500 @@ -21,7 +21,8 @@ #include <linux/mutex.h> struct memory_block { - unsigned long phys_index; + unsigned long start_phys_index; + unsigned long end_phys_index; unsigned long state; /* * This serializes all state change requests. It isn't ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 2/8] v3 Add new phys_index properties @ 2010-07-20 13:24 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 13:24 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: KAMEZAWA Hiroyuki, greg Update the 'phys_index' properties of a memory block to include a 'start_phys_index' which is the same as the current 'phys_index' property. This also adds an 'end_phys_index' property to indicate the id of the last section in th memory block. Patch updated to keep the name of the phys_index property instead of renaming it to start_phys_index. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> --- drivers/base/memory.c | 28 ++++++++++++++++++++-------- include/linux/memory.h | 3 ++- 2 files changed, 22 insertions(+), 9 deletions(-) Index: linux-2.6/drivers/base/memory.c =================================================================== --- linux-2.6.orig/drivers/base/memory.c 2010-07-19 20:42:11.000000000 -0500 +++ linux-2.6/drivers/base/memory.c 2010-07-20 06:38:21.000000000 -0500 @@ -109,12 +109,20 @@ unregister_memory(struct memory_block *m * uses. */ -static ssize_t show_mem_phys_index(struct sys_device *dev, +static ssize_t show_mem_start_phys_index(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) { struct memory_block *mem = container_of(dev, struct memory_block, sysdev); - return sprintf(buf, "%08lx\n", mem->phys_index); + return sprintf(buf, "%08lx\n", mem->start_phys_index); +} + +static ssize_t show_mem_end_phys_index(struct sys_device *dev, + struct sysdev_attribute *attr, char *buf) +{ + struct memory_block *mem = + container_of(dev, struct memory_block, sysdev); + return sprintf(buf, "%08lx\n", mem->end_phys_index); } /* @@ -128,7 +136,7 @@ static ssize_t show_mem_removable(struct struct memory_block *mem = container_of(dev, struct memory_block, sysdev); - start_pfn = section_nr_to_pfn(mem->phys_index); + start_pfn = section_nr_to_pfn(mem->start_phys_index); ret = is_mem_section_removable(start_pfn, PAGES_PER_SECTION); return sprintf(buf, "%d\n", ret); } @@ -191,7 +199,7 @@ memory_block_action(struct memory_block int ret; int old_state = mem->state; - psection = mem->phys_index; + psection = mem->start_phys_index; first_page = pfn_to_page(psection << PFN_SECTION_SHIFT); /* @@ -264,7 +272,7 @@ store_mem_state(struct sys_device *dev, int ret = -EINVAL; mem = container_of(dev, struct memory_block, sysdev); - phys_section_nr = mem->phys_index; + phys_section_nr = mem->start_phys_index; if (!present_section_nr(phys_section_nr)) goto out; @@ -296,7 +304,8 @@ static ssize_t show_phys_device(struct s return sprintf(buf, "%d\n", mem->phys_device); } -static SYSDEV_ATTR(phys_index, 0444, show_mem_phys_index, NULL); +static SYSDEV_ATTR(phys_index, 0444, show_mem_start_phys_index, NULL); +static SYSDEV_ATTR(end_phys_index, 0444, show_mem_end_phys_index, NULL); static SYSDEV_ATTR(state, 0644, show_mem_state, store_mem_state); static SYSDEV_ATTR(phys_device, 0444, show_phys_device, NULL); static SYSDEV_ATTR(removable, 0444, show_mem_removable, NULL); @@ -476,16 +485,18 @@ static int add_memory_block(int nid, str if (!mem) return -ENOMEM; - mem->phys_index = __section_nr(section); + mem->start_phys_index = __section_nr(section); mem->state = state; mutex_init(&mem->state_mutex); - start_pfn = section_nr_to_pfn(mem->phys_index); + start_pfn = section_nr_to_pfn(mem->start_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, end_phys_index); + if (!ret) ret = mem_create_simple_file(mem, state); if (!ret) ret = mem_create_simple_file(mem, phys_device); @@ -507,6 +518,7 @@ int remove_memory_block(unsigned long no mem = find_memory_block(section); unregister_mem_sect_under_nodes(mem); mem_remove_simple_file(mem, phys_index); + mem_remove_simple_file(mem, end_phys_index); mem_remove_simple_file(mem, state); mem_remove_simple_file(mem, phys_device); mem_remove_simple_file(mem, removable); Index: linux-2.6/include/linux/memory.h =================================================================== --- linux-2.6.orig/include/linux/memory.h 2010-07-19 20:42:11.000000000 -0500 +++ linux-2.6/include/linux/memory.h 2010-07-20 06:35:38.000000000 -0500 @@ -21,7 +21,8 @@ #include <linux/mutex.h> struct memory_block { - unsigned long phys_index; + unsigned long start_phys_index; + unsigned long end_phys_index; unsigned long state; /* * This serializes all state change requests. It isn't -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 2/8] v3 Add new phys_index properties @ 2010-07-20 13:24 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 13:24 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: KAMEZAWA Hiroyuki, greg Update the 'phys_index' properties of a memory block to include a 'start_phys_index' which is the same as the current 'phys_index' property. This also adds an 'end_phys_index' property to indicate the id of the last section in th memory block. Patch updated to keep the name of the phys_index property instead of renaming it to start_phys_index. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> --- drivers/base/memory.c | 28 ++++++++++++++++++++-------- include/linux/memory.h | 3 ++- 2 files changed, 22 insertions(+), 9 deletions(-) Index: linux-2.6/drivers/base/memory.c =================================================================== --- linux-2.6.orig/drivers/base/memory.c 2010-07-19 20:42:11.000000000 -0500 +++ linux-2.6/drivers/base/memory.c 2010-07-20 06:38:21.000000000 -0500 @@ -109,12 +109,20 @@ unregister_memory(struct memory_block *m * uses. */ -static ssize_t show_mem_phys_index(struct sys_device *dev, +static ssize_t show_mem_start_phys_index(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) { struct memory_block *mem = container_of(dev, struct memory_block, sysdev); - return sprintf(buf, "%08lx\n", mem->phys_index); + return sprintf(buf, "%08lx\n", mem->start_phys_index); +} + +static ssize_t show_mem_end_phys_index(struct sys_device *dev, + struct sysdev_attribute *attr, char *buf) +{ + struct memory_block *mem = + container_of(dev, struct memory_block, sysdev); + return sprintf(buf, "%08lx\n", mem->end_phys_index); } /* @@ -128,7 +136,7 @@ static ssize_t show_mem_removable(struct struct memory_block *mem = container_of(dev, struct memory_block, sysdev); - start_pfn = section_nr_to_pfn(mem->phys_index); + start_pfn = section_nr_to_pfn(mem->start_phys_index); ret = is_mem_section_removable(start_pfn, PAGES_PER_SECTION); return sprintf(buf, "%d\n", ret); } @@ -191,7 +199,7 @@ memory_block_action(struct memory_block int ret; int old_state = mem->state; - psection = mem->phys_index; + psection = mem->start_phys_index; first_page = pfn_to_page(psection << PFN_SECTION_SHIFT); /* @@ -264,7 +272,7 @@ store_mem_state(struct sys_device *dev, int ret = -EINVAL; mem = container_of(dev, struct memory_block, sysdev); - phys_section_nr = mem->phys_index; + phys_section_nr = mem->start_phys_index; if (!present_section_nr(phys_section_nr)) goto out; @@ -296,7 +304,8 @@ static ssize_t show_phys_device(struct s return sprintf(buf, "%d\n", mem->phys_device); } -static SYSDEV_ATTR(phys_index, 0444, show_mem_phys_index, NULL); +static SYSDEV_ATTR(phys_index, 0444, show_mem_start_phys_index, NULL); +static SYSDEV_ATTR(end_phys_index, 0444, show_mem_end_phys_index, NULL); static SYSDEV_ATTR(state, 0644, show_mem_state, store_mem_state); static SYSDEV_ATTR(phys_device, 0444, show_phys_device, NULL); static SYSDEV_ATTR(removable, 0444, show_mem_removable, NULL); @@ -476,16 +485,18 @@ static int add_memory_block(int nid, str if (!mem) return -ENOMEM; - mem->phys_index = __section_nr(section); + mem->start_phys_index = __section_nr(section); mem->state = state; mutex_init(&mem->state_mutex); - start_pfn = section_nr_to_pfn(mem->phys_index); + start_pfn = section_nr_to_pfn(mem->start_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, end_phys_index); + if (!ret) ret = mem_create_simple_file(mem, state); if (!ret) ret = mem_create_simple_file(mem, phys_device); @@ -507,6 +518,7 @@ int remove_memory_block(unsigned long no mem = find_memory_block(section); unregister_mem_sect_under_nodes(mem); mem_remove_simple_file(mem, phys_index); + mem_remove_simple_file(mem, end_phys_index); mem_remove_simple_file(mem, state); mem_remove_simple_file(mem, phys_device); mem_remove_simple_file(mem, removable); Index: linux-2.6/include/linux/memory.h =================================================================== --- linux-2.6.orig/include/linux/memory.h 2010-07-19 20:42:11.000000000 -0500 +++ linux-2.6/include/linux/memory.h 2010-07-20 06:35:38.000000000 -0500 @@ -21,7 +21,8 @@ #include <linux/mutex.h> struct memory_block { - unsigned long phys_index; + unsigned long start_phys_index; + unsigned long end_phys_index; unsigned long state; /* * This serializes all state change requests. It isn't ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 2/8] v3 Add new phys_index properties 2010-07-20 13:24 ` Nathan Fontenot (?) @ 2010-07-20 19:10 ` Dave Hansen -1 siblings, 0 replies; 90+ messages in thread From: Dave Hansen @ 2010-07-20 19:10 UTC (permalink / raw) To: Nathan Fontenot Cc: linux-mm, greg, linux-kernel, KAMEZAWA Hiroyuki, linuxppc-dev On Tue, 2010-07-20 at 08:24 -0500, Nathan Fontenot wrote: > Update the 'phys_index' properties of a memory block to include a > 'start_phys_index' which is the same as the current 'phys_index' property. > This also adds an 'end_phys_index' property to indicate the id of the > last section in th memory block. > > Patch updated to keep the name of the phys_index property instead of > renaming it to start_phys_index. KAME is right on this. We should keep the old one if at all possible. The only other thing we might want to do is move 'phys_index' to 'start_phys_index', and make a new 'phys_index' that does a WARN_ONCE(), gives a deprecated warning, then calls the new 'start_phys_index' code. So, basically make the new, more clear name, but keep the old one for a while and deprecate it. Maybe we could get away with removing it in ten years. :) -- Dave ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 2/8] v3 Add new phys_index properties @ 2010-07-20 19:10 ` Dave Hansen 0 siblings, 0 replies; 90+ messages in thread From: Dave Hansen @ 2010-07-20 19:10 UTC (permalink / raw) To: Nathan Fontenot Cc: linux-kernel, linux-mm, linuxppc-dev, KAMEZAWA Hiroyuki, greg On Tue, 2010-07-20 at 08:24 -0500, Nathan Fontenot wrote: > Update the 'phys_index' properties of a memory block to include a > 'start_phys_index' which is the same as the current 'phys_index' property. > This also adds an 'end_phys_index' property to indicate the id of the > last section in th memory block. > > Patch updated to keep the name of the phys_index property instead of > renaming it to start_phys_index. KAME is right on this. We should keep the old one if at all possible. The only other thing we might want to do is move 'phys_index' to 'start_phys_index', and make a new 'phys_index' that does a WARN_ONCE(), gives a deprecated warning, then calls the new 'start_phys_index' code. So, basically make the new, more clear name, but keep the old one for a while and deprecate it. Maybe we could get away with removing it in ten years. :) -- Dave -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 2/8] v3 Add new phys_index properties @ 2010-07-20 19:10 ` Dave Hansen 0 siblings, 0 replies; 90+ messages in thread From: Dave Hansen @ 2010-07-20 19:10 UTC (permalink / raw) To: Nathan Fontenot Cc: linux-kernel, linux-mm, linuxppc-dev, KAMEZAWA Hiroyuki, greg On Tue, 2010-07-20 at 08:24 -0500, Nathan Fontenot wrote: > Update the 'phys_index' properties of a memory block to include a > 'start_phys_index' which is the same as the current 'phys_index' property. > This also adds an 'end_phys_index' property to indicate the id of the > last section in th memory block. > > Patch updated to keep the name of the phys_index property instead of > renaming it to start_phys_index. KAME is right on this. We should keep the old one if at all possible. The only other thing we might want to do is move 'phys_index' to 'start_phys_index', and make a new 'phys_index' that does a WARN_ONCE(), gives a deprecated warning, then calls the new 'start_phys_index' code. So, basically make the new, more clear name, but keep the old one for a while and deprecate it. Maybe we could get away with removing it in ten years. :) -- Dave ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 3/8] v3 Add section count to memory_block 2010-07-20 3:45 ` Nathan Fontenot (?) @ 2010-07-20 3:53 ` Nathan Fontenot -1 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:53 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: greg, KAMEZAWA Hiroyuki Add a section count property to the memory_block struct to track the number of memory sections that have been added/removed from a emory block. Signed-off-by: Nathan Fontenot <nfont@asutin.ibm.com> --- drivers/base/memory.c | 19 ++++++++++++------- include/linux/memory.h | 2 ++ 2 files changed, 14 insertions(+), 7 deletions(-) Index: linux-2.6/drivers/base/memory.c =================================================================== --- linux-2.6.orig/drivers/base/memory.c 2010-07-19 20:43:49.000000000 -0500 +++ linux-2.6/drivers/base/memory.c 2010-07-19 20:44:01.000000000 -0500 @@ -487,6 +487,7 @@ static int add_memory_block(int nid, str mem->start_phys_index = __section_nr(section); mem->state = state; + atomic_inc(&mem->section_count); mutex_init(&mem->state_mutex); start_pfn = section_nr_to_pfn(mem->start_phys_index); mem->phys_device = arch_get_memory_phys_device(start_pfn); @@ -516,13 +517,17 @@ int remove_memory_block(unsigned long no struct memory_block *mem; mem = find_memory_block(section); - unregister_mem_sect_under_nodes(mem); - mem_remove_simple_file(mem, start_phys_index); - mem_remove_simple_file(mem, end_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); + atomic_dec(&mem->section_count); + + if (atomic_read(&mem->section_count) == 0) { + unregister_mem_sect_under_nodes(mem); + mem_remove_simple_file(mem, start_phys_index); + mem_remove_simple_file(mem, end_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); + } return 0; } Index: linux-2.6/include/linux/memory.h =================================================================== --- linux-2.6.orig/include/linux/memory.h 2010-07-19 20:43:49.000000000 -0500 +++ linux-2.6/include/linux/memory.h 2010-07-19 20:44:01.000000000 -0500 @@ -19,11 +19,13 @@ #include <linux/node.h> #include <linux/compiler.h> #include <linux/mutex.h> +#include <asm/atomic.h> struct memory_block { unsigned long start_phys_index; unsigned long end_phys_index; unsigned long state; + atomic_t section_count; /* * This serializes all state change requests. It isn't * held during creation because the control files are ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 3/8] v3 Add section count to memory_block @ 2010-07-20 3:53 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:53 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: KAMEZAWA Hiroyuki, greg Add a section count property to the memory_block struct to track the number of memory sections that have been added/removed from a emory block. Signed-off-by: Nathan Fontenot <nfont@asutin.ibm.com> --- drivers/base/memory.c | 19 ++++++++++++------- include/linux/memory.h | 2 ++ 2 files changed, 14 insertions(+), 7 deletions(-) Index: linux-2.6/drivers/base/memory.c =================================================================== --- linux-2.6.orig/drivers/base/memory.c 2010-07-19 20:43:49.000000000 -0500 +++ linux-2.6/drivers/base/memory.c 2010-07-19 20:44:01.000000000 -0500 @@ -487,6 +487,7 @@ static int add_memory_block(int nid, str mem->start_phys_index = __section_nr(section); mem->state = state; + atomic_inc(&mem->section_count); mutex_init(&mem->state_mutex); start_pfn = section_nr_to_pfn(mem->start_phys_index); mem->phys_device = arch_get_memory_phys_device(start_pfn); @@ -516,13 +517,17 @@ int remove_memory_block(unsigned long no struct memory_block *mem; mem = find_memory_block(section); - unregister_mem_sect_under_nodes(mem); - mem_remove_simple_file(mem, start_phys_index); - mem_remove_simple_file(mem, end_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); + atomic_dec(&mem->section_count); + + if (atomic_read(&mem->section_count) == 0) { + unregister_mem_sect_under_nodes(mem); + mem_remove_simple_file(mem, start_phys_index); + mem_remove_simple_file(mem, end_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); + } return 0; } Index: linux-2.6/include/linux/memory.h =================================================================== --- linux-2.6.orig/include/linux/memory.h 2010-07-19 20:43:49.000000000 -0500 +++ linux-2.6/include/linux/memory.h 2010-07-19 20:44:01.000000000 -0500 @@ -19,11 +19,13 @@ #include <linux/node.h> #include <linux/compiler.h> #include <linux/mutex.h> +#include <asm/atomic.h> struct memory_block { unsigned long start_phys_index; unsigned long end_phys_index; unsigned long state; + atomic_t section_count; /* * This serializes all state change requests. It isn't * held during creation because the control files are -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 3/8] v3 Add section count to memory_block @ 2010-07-20 3:53 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:53 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: KAMEZAWA Hiroyuki, greg Add a section count property to the memory_block struct to track the number of memory sections that have been added/removed from a emory block. Signed-off-by: Nathan Fontenot <nfont@asutin.ibm.com> --- drivers/base/memory.c | 19 ++++++++++++------- include/linux/memory.h | 2 ++ 2 files changed, 14 insertions(+), 7 deletions(-) Index: linux-2.6/drivers/base/memory.c =================================================================== --- linux-2.6.orig/drivers/base/memory.c 2010-07-19 20:43:49.000000000 -0500 +++ linux-2.6/drivers/base/memory.c 2010-07-19 20:44:01.000000000 -0500 @@ -487,6 +487,7 @@ static int add_memory_block(int nid, str mem->start_phys_index = __section_nr(section); mem->state = state; + atomic_inc(&mem->section_count); mutex_init(&mem->state_mutex); start_pfn = section_nr_to_pfn(mem->start_phys_index); mem->phys_device = arch_get_memory_phys_device(start_pfn); @@ -516,13 +517,17 @@ int remove_memory_block(unsigned long no struct memory_block *mem; mem = find_memory_block(section); - unregister_mem_sect_under_nodes(mem); - mem_remove_simple_file(mem, start_phys_index); - mem_remove_simple_file(mem, end_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); + atomic_dec(&mem->section_count); + + if (atomic_read(&mem->section_count) == 0) { + unregister_mem_sect_under_nodes(mem); + mem_remove_simple_file(mem, start_phys_index); + mem_remove_simple_file(mem, end_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); + } return 0; } Index: linux-2.6/include/linux/memory.h =================================================================== --- linux-2.6.orig/include/linux/memory.h 2010-07-19 20:43:49.000000000 -0500 +++ linux-2.6/include/linux/memory.h 2010-07-19 20:44:01.000000000 -0500 @@ -19,11 +19,13 @@ #include <linux/node.h> #include <linux/compiler.h> #include <linux/mutex.h> +#include <asm/atomic.h> struct memory_block { unsigned long start_phys_index; unsigned long end_phys_index; unsigned long state; + atomic_t section_count; /* * This serializes all state change requests. It isn't * held during creation because the control files are ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 3/8] v3 Add section count to memory_block 2010-07-20 3:53 ` Nathan Fontenot (?) @ 2010-07-20 7:01 ` KAMEZAWA Hiroyuki -1 siblings, 0 replies; 90+ messages in thread From: KAMEZAWA Hiroyuki @ 2010-07-20 7:01 UTC (permalink / raw) To: Nathan Fontenot; +Cc: linux-mm, greg, linux-kernel, linuxppc-dev On Mon, 19 Jul 2010 22:53:58 -0500 Nathan Fontenot <nfont@austin.ibm.com> wrote: > Add a section count property to the memory_block struct to track the number > of memory sections that have been added/removed from a emory block. > > Signed-off-by: Nathan Fontenot <nfont@asutin.ibm.com> > --- > drivers/base/memory.c | 19 ++++++++++++------- > include/linux/memory.h | 2 ++ > 2 files changed, 14 insertions(+), 7 deletions(-) > > Index: linux-2.6/drivers/base/memory.c > =================================================================== > --- linux-2.6.orig/drivers/base/memory.c 2010-07-19 20:43:49.000000000 -0500 > +++ linux-2.6/drivers/base/memory.c 2010-07-19 20:44:01.000000000 -0500 > @@ -487,6 +487,7 @@ static int add_memory_block(int nid, str > > mem->start_phys_index = __section_nr(section); > mem->state = state; > + atomic_inc(&mem->section_count); > mutex_init(&mem->state_mutex); > start_pfn = section_nr_to_pfn(mem->start_phys_index); > mem->phys_device = arch_get_memory_phys_device(start_pfn); > @@ -516,13 +517,17 @@ int remove_memory_block(unsigned long no > struct memory_block *mem; > > mem = find_memory_block(section); > - unregister_mem_sect_under_nodes(mem); > - mem_remove_simple_file(mem, start_phys_index); > - mem_remove_simple_file(mem, end_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); > + atomic_dec(&mem->section_count); > + > + if (atomic_read(&mem->section_count) == 0) { We use atomic_dec_and_test() in usual. Otherwise, I don't see other problems in other part. Please fix this nitpick. Regards, -Kame ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 3/8] v3 Add section count to memory_block @ 2010-07-20 7:01 ` KAMEZAWA Hiroyuki 0 siblings, 0 replies; 90+ messages in thread From: KAMEZAWA Hiroyuki @ 2010-07-20 7:01 UTC (permalink / raw) To: Nathan Fontenot; +Cc: linux-kernel, linux-mm, linuxppc-dev, greg On Mon, 19 Jul 2010 22:53:58 -0500 Nathan Fontenot <nfont@austin.ibm.com> wrote: > Add a section count property to the memory_block struct to track the number > of memory sections that have been added/removed from a emory block. > > Signed-off-by: Nathan Fontenot <nfont@asutin.ibm.com> > --- > drivers/base/memory.c | 19 ++++++++++++------- > include/linux/memory.h | 2 ++ > 2 files changed, 14 insertions(+), 7 deletions(-) > > Index: linux-2.6/drivers/base/memory.c > =================================================================== > --- linux-2.6.orig/drivers/base/memory.c 2010-07-19 20:43:49.000000000 -0500 > +++ linux-2.6/drivers/base/memory.c 2010-07-19 20:44:01.000000000 -0500 > @@ -487,6 +487,7 @@ static int add_memory_block(int nid, str > > mem->start_phys_index = __section_nr(section); > mem->state = state; > + atomic_inc(&mem->section_count); > mutex_init(&mem->state_mutex); > start_pfn = section_nr_to_pfn(mem->start_phys_index); > mem->phys_device = arch_get_memory_phys_device(start_pfn); > @@ -516,13 +517,17 @@ int remove_memory_block(unsigned long no > struct memory_block *mem; > > mem = find_memory_block(section); > - unregister_mem_sect_under_nodes(mem); > - mem_remove_simple_file(mem, start_phys_index); > - mem_remove_simple_file(mem, end_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); > + atomic_dec(&mem->section_count); > + > + if (atomic_read(&mem->section_count) == 0) { We use atomic_dec_and_test() in usual. Otherwise, I don't see other problems in other part. Please fix this nitpick. Regards, -Kame -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 3/8] v3 Add section count to memory_block @ 2010-07-20 7:01 ` KAMEZAWA Hiroyuki 0 siblings, 0 replies; 90+ messages in thread From: KAMEZAWA Hiroyuki @ 2010-07-20 7:01 UTC (permalink / raw) To: Nathan Fontenot; +Cc: linux-kernel, linux-mm, linuxppc-dev, greg On Mon, 19 Jul 2010 22:53:58 -0500 Nathan Fontenot <nfont@austin.ibm.com> wrote: > Add a section count property to the memory_block struct to track the number > of memory sections that have been added/removed from a emory block. > > Signed-off-by: Nathan Fontenot <nfont@asutin.ibm.com> > --- > drivers/base/memory.c | 19 ++++++++++++------- > include/linux/memory.h | 2 ++ > 2 files changed, 14 insertions(+), 7 deletions(-) > > Index: linux-2.6/drivers/base/memory.c > =================================================================== > --- linux-2.6.orig/drivers/base/memory.c 2010-07-19 20:43:49.000000000 -0500 > +++ linux-2.6/drivers/base/memory.c 2010-07-19 20:44:01.000000000 -0500 > @@ -487,6 +487,7 @@ static int add_memory_block(int nid, str > > mem->start_phys_index = __section_nr(section); > mem->state = state; > + atomic_inc(&mem->section_count); > mutex_init(&mem->state_mutex); > start_pfn = section_nr_to_pfn(mem->start_phys_index); > mem->phys_device = arch_get_memory_phys_device(start_pfn); > @@ -516,13 +517,17 @@ int remove_memory_block(unsigned long no > struct memory_block *mem; > > mem = find_memory_block(section); > - unregister_mem_sect_under_nodes(mem); > - mem_remove_simple_file(mem, start_phys_index); > - mem_remove_simple_file(mem, end_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); > + atomic_dec(&mem->section_count); > + > + if (atomic_read(&mem->section_count) == 0) { We use atomic_dec_and_test() in usual. Otherwise, I don't see other problems in other part. Please fix this nitpick. Regards, -Kame ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 3/8] v3 Add section count to memory_block 2010-07-20 3:53 ` Nathan Fontenot (?) @ 2010-07-20 13:26 ` Nathan Fontenot -1 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 13:26 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: greg, KAMEZAWA Hiroyuki 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. Updated to use atomic_dec_and_test(). Signed-off-by: Nathan Fontenot <nfont@asutin.ibm.com> --- drivers/base/memory.c | 18 +++++++++++------- include/linux/memory.h | 2 ++ 2 files changed, 13 insertions(+), 7 deletions(-) Index: linux-2.6/drivers/base/memory.c =================================================================== --- linux-2.6.orig/drivers/base/memory.c 2010-07-20 06:38:21.000000000 -0500 +++ linux-2.6/drivers/base/memory.c 2010-07-20 06:43:29.000000000 -0500 @@ -487,6 +487,7 @@ static int add_memory_block(int nid, str mem->start_phys_index = __section_nr(section); mem->state = state; + atomic_inc(&mem->section_count); mutex_init(&mem->state_mutex); start_pfn = section_nr_to_pfn(mem->start_phys_index); mem->phys_device = arch_get_memory_phys_device(start_pfn); @@ -516,13 +517,16 @@ int remove_memory_block(unsigned long no struct memory_block *mem; mem = find_memory_block(section); - unregister_mem_sect_under_nodes(mem); - mem_remove_simple_file(mem, phys_index); - mem_remove_simple_file(mem, end_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); + + if (atomic_dec_and_test(&mem->section_count)) { + unregister_mem_sect_under_nodes(mem); + mem_remove_simple_file(mem, phys_index); + mem_remove_simple_file(mem, end_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); + } return 0; } Index: linux-2.6/include/linux/memory.h =================================================================== --- linux-2.6.orig/include/linux/memory.h 2010-07-20 06:35:38.000000000 -0500 +++ linux-2.6/include/linux/memory.h 2010-07-20 06:38:59.000000000 -0500 @@ -19,11 +19,13 @@ #include <linux/node.h> #include <linux/compiler.h> #include <linux/mutex.h> +#include <asm/atomic.h> struct memory_block { unsigned long start_phys_index; unsigned long end_phys_index; unsigned long state; + atomic_t section_count; /* * This serializes all state change requests. It isn't * held during creation because the control files are ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 3/8] v3 Add section count to memory_block @ 2010-07-20 13:26 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 13:26 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: KAMEZAWA Hiroyuki, greg 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. Updated to use atomic_dec_and_test(). Signed-off-by: Nathan Fontenot <nfont@asutin.ibm.com> --- drivers/base/memory.c | 18 +++++++++++------- include/linux/memory.h | 2 ++ 2 files changed, 13 insertions(+), 7 deletions(-) Index: linux-2.6/drivers/base/memory.c =================================================================== --- linux-2.6.orig/drivers/base/memory.c 2010-07-20 06:38:21.000000000 -0500 +++ linux-2.6/drivers/base/memory.c 2010-07-20 06:43:29.000000000 -0500 @@ -487,6 +487,7 @@ static int add_memory_block(int nid, str mem->start_phys_index = __section_nr(section); mem->state = state; + atomic_inc(&mem->section_count); mutex_init(&mem->state_mutex); start_pfn = section_nr_to_pfn(mem->start_phys_index); mem->phys_device = arch_get_memory_phys_device(start_pfn); @@ -516,13 +517,16 @@ int remove_memory_block(unsigned long no struct memory_block *mem; mem = find_memory_block(section); - unregister_mem_sect_under_nodes(mem); - mem_remove_simple_file(mem, phys_index); - mem_remove_simple_file(mem, end_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); + + if (atomic_dec_and_test(&mem->section_count)) { + unregister_mem_sect_under_nodes(mem); + mem_remove_simple_file(mem, phys_index); + mem_remove_simple_file(mem, end_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); + } return 0; } Index: linux-2.6/include/linux/memory.h =================================================================== --- linux-2.6.orig/include/linux/memory.h 2010-07-20 06:35:38.000000000 -0500 +++ linux-2.6/include/linux/memory.h 2010-07-20 06:38:59.000000000 -0500 @@ -19,11 +19,13 @@ #include <linux/node.h> #include <linux/compiler.h> #include <linux/mutex.h> +#include <asm/atomic.h> struct memory_block { unsigned long start_phys_index; unsigned long end_phys_index; unsigned long state; + atomic_t section_count; /* * This serializes all state change requests. It isn't * held during creation because the control files are -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 3/8] v3 Add section count to memory_block @ 2010-07-20 13:26 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 13:26 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: KAMEZAWA Hiroyuki, greg 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. Updated to use atomic_dec_and_test(). Signed-off-by: Nathan Fontenot <nfont@asutin.ibm.com> --- drivers/base/memory.c | 18 +++++++++++------- include/linux/memory.h | 2 ++ 2 files changed, 13 insertions(+), 7 deletions(-) Index: linux-2.6/drivers/base/memory.c =================================================================== --- linux-2.6.orig/drivers/base/memory.c 2010-07-20 06:38:21.000000000 -0500 +++ linux-2.6/drivers/base/memory.c 2010-07-20 06:43:29.000000000 -0500 @@ -487,6 +487,7 @@ static int add_memory_block(int nid, str mem->start_phys_index = __section_nr(section); mem->state = state; + atomic_inc(&mem->section_count); mutex_init(&mem->state_mutex); start_pfn = section_nr_to_pfn(mem->start_phys_index); mem->phys_device = arch_get_memory_phys_device(start_pfn); @@ -516,13 +517,16 @@ int remove_memory_block(unsigned long no struct memory_block *mem; mem = find_memory_block(section); - unregister_mem_sect_under_nodes(mem); - mem_remove_simple_file(mem, phys_index); - mem_remove_simple_file(mem, end_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); + + if (atomic_dec_and_test(&mem->section_count)) { + unregister_mem_sect_under_nodes(mem); + mem_remove_simple_file(mem, phys_index); + mem_remove_simple_file(mem, end_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); + } return 0; } Index: linux-2.6/include/linux/memory.h =================================================================== --- linux-2.6.orig/include/linux/memory.h 2010-07-20 06:35:38.000000000 -0500 +++ linux-2.6/include/linux/memory.h 2010-07-20 06:38:59.000000000 -0500 @@ -19,11 +19,13 @@ #include <linux/node.h> #include <linux/compiler.h> #include <linux/mutex.h> +#include <asm/atomic.h> struct memory_block { unsigned long start_phys_index; unsigned long end_phys_index; unsigned long state; + atomic_t section_count; /* * This serializes all state change requests. It isn't * held during creation because the control files are ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 4/8] v3 Allow memory_block to span multiple memory sections 2010-07-20 3:45 ` Nathan Fontenot (?) @ 2010-07-20 3:55 ` Nathan Fontenot -1 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:55 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: greg, KAMEZAWA Hiroyuki Update the memory sysfs code that each sysfs memory directory is now considered a memory block that can contain multiple memory sections per memory block. The default size of each memory block is SECTION_SIZE_BITS to maintain the current behavior of having a single memory section per memory block (i.e. one sysfs directory per memory section). For architectures that want to have memory blocks span multiple memory sections they need only define their own memory_block_size_bytes() routine. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> --- drivers/base/memory.c | 141 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 98 insertions(+), 43 deletions(-) Index: linux-2.6/drivers/base/memory.c =================================================================== --- linux-2.6.orig/drivers/base/memory.c 2010-07-19 20:44:01.000000000 -0500 +++ linux-2.6/drivers/base/memory.c 2010-07-19 21:12:22.000000000 -0500 @@ -28,6 +28,14 @@ #include <asm/uaccess.h> #define MEMORY_CLASS_NAME "memory" +#define MIN_MEMORY_BLOCK_SIZE (1 << SECTION_SIZE_BITS) + +static int sections_per_block; + +static inline int base_memory_block_id(int section_nr) +{ + return (section_nr / sections_per_block) * sections_per_block; +} static struct sysdev_class memory_sysdev_class = { .name = MEMORY_CLASS_NAME, @@ -82,22 +90,21 @@ EXPORT_SYMBOL(unregister_memory_isolate_ * register_memory - Setup a sysfs device for a memory block */ static -int register_memory(struct memory_block *memory, struct mem_section *section) +int register_memory(struct memory_block *memory) { int error; memory->sysdev.cls = &memory_sysdev_class; - memory->sysdev.id = __section_nr(section); + memory->sysdev.id = memory->start_phys_index; error = sysdev_register(&memory->sysdev); return error; } static void -unregister_memory(struct memory_block *memory, struct mem_section *section) +unregister_memory(struct memory_block *memory) { BUG_ON(memory->sysdev.cls != &memory_sysdev_class); - BUG_ON(memory->sysdev.id != __section_nr(section)); /* drop the ref. we got in remove_memory_block() */ kobject_put(&memory->sysdev.kobj); @@ -131,13 +138,16 @@ static ssize_t show_mem_end_phys_index(s static ssize_t show_mem_removable(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) { - unsigned long start_pfn; - int ret; + unsigned long i, pfn; + int ret = 1; struct memory_block *mem = container_of(dev, struct memory_block, sysdev); - start_pfn = section_nr_to_pfn(mem->start_phys_index); - ret = is_mem_section_removable(start_pfn, PAGES_PER_SECTION); + for (i = mem->start_phys_index; i <= mem->end_phys_index; i++) { + pfn = section_nr_to_pfn(i); + ret &= is_mem_section_removable(pfn, PAGES_PER_SECTION); + } + return sprintf(buf, "%d\n", ret); } @@ -190,17 +200,14 @@ int memory_isolate_notify(unsigned long * OK to have direct references to sparsemem variables in here. */ static int -memory_block_action(struct memory_block *mem, unsigned long action) +memory_section_action(unsigned long phys_index, unsigned long action) { int i; - unsigned long psection; unsigned long start_pfn, start_paddr; struct page *first_page; int ret; - int old_state = mem->state; - psection = mem->start_phys_index; - first_page = pfn_to_page(psection << PFN_SECTION_SHIFT); + first_page = pfn_to_page(phys_index << PFN_SECTION_SHIFT); /* * The probe routines leave the pages reserved, just @@ -213,8 +220,8 @@ memory_block_action(struct memory_block continue; printk(KERN_WARNING "section number %ld page number %d " - "not reserved, was it already online? \n", - psection, i); + "not reserved, was it already online?\n", + phys_index, i); return -EBUSY; } } @@ -225,18 +232,13 @@ memory_block_action(struct memory_block ret = online_pages(start_pfn, PAGES_PER_SECTION); break; case MEM_OFFLINE: - mem->state = MEM_GOING_OFFLINE; start_paddr = page_to_pfn(first_page) << PAGE_SHIFT; ret = remove_memory(start_paddr, PAGES_PER_SECTION << PAGE_SHIFT); - if (ret) { - mem->state = old_state; - break; - } break; default: - WARN(1, KERN_WARNING "%s(%p, %ld) unknown action: %ld\n", - __func__, mem, action, action); + WARN(1, KERN_WARNING "%s(%ld, %ld) unknown action: " + "%ld\n", __func__, phys_index, action, action); ret = -EINVAL; } @@ -246,7 +248,7 @@ memory_block_action(struct memory_block static int memory_block_change_state(struct memory_block *mem, unsigned long to_state, unsigned long from_state_req) { - int ret = 0; + int i, ret = 0; mutex_lock(&mem->state_mutex); if (mem->state != from_state_req) { @@ -254,8 +256,21 @@ static int memory_block_change_state(str goto out; } - ret = memory_block_action(mem, to_state); - if (!ret) + if (to_state == MEM_OFFLINE) + mem->state = MEM_GOING_OFFLINE; + + for (i = mem->start_phys_index; i <= mem->end_phys_index; i++) { + ret = memory_section_action(i, to_state); + if (ret) + break; + } + + if (ret) { + for (i = mem->start_phys_index; i <= mem->end_phys_index; i++) + memory_section_action(i, from_state_req); + + mem->state = from_state_req; + } else mem->state = to_state; out: @@ -268,20 +283,15 @@ store_mem_state(struct sys_device *dev, struct sysdev_attribute *attr, const char *buf, size_t count) { struct memory_block *mem; - unsigned int phys_section_nr; int ret = -EINVAL; mem = container_of(dev, struct memory_block, sysdev); - phys_section_nr = mem->start_phys_index; - - if (!present_section_nr(phys_section_nr)) - goto out; if (!strncmp(buf, "online", min((int)count, 6))) ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE); else if(!strncmp(buf, "offline", min((int)count, 7))) ret = memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE); -out: + if (ret) return ret; return count; @@ -458,12 +468,13 @@ struct memory_block *find_memory_block(s struct sys_device *sysdev; struct memory_block *mem; char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1]; + int block_id = base_memory_block_id(__section_nr(section)); /* * 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)); + sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, block_id); kobj = kset_find_obj(&memory_sysdev_class.kset, name); if (!kobj) @@ -475,24 +486,26 @@ struct memory_block *find_memory_block(s return mem; } -static int add_memory_block(int nid, struct mem_section *section, - unsigned long state, enum mem_add_context context) +static int init_memory_block(struct memory_block **memory, + struct mem_section *section, unsigned long state) { - struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL); + struct memory_block *mem; unsigned long start_pfn; int ret = 0; + mem = kzalloc(sizeof(*mem), GFP_KERNEL); if (!mem) return -ENOMEM; - mem->start_phys_index = __section_nr(section); + mem->start_phys_index = base_memory_block_id(__section_nr(section)); + mem->end_phys_index = mem->start_phys_index + sections_per_block - 1; mem->state = state; atomic_inc(&mem->section_count); mutex_init(&mem->state_mutex); start_pfn = section_nr_to_pfn(mem->start_phys_index); mem->phys_device = arch_get_memory_phys_device(start_pfn); - ret = register_memory(mem, section); + ret = register_memory(mem); if (!ret) ret = mem_create_simple_file(mem, start_phys_index); if (!ret) @@ -503,8 +516,27 @@ static int add_memory_block(int nid, str ret = mem_create_simple_file(mem, phys_device); if (!ret) ret = mem_create_simple_file(mem, removable); + + *memory = mem; + return ret; +} + +static int add_memory_section(int nid, struct mem_section *section, + unsigned long state, enum mem_add_context context) +{ + struct memory_block *mem; + int ret = 0; + + mem = find_memory_block(section); + if (mem) { + atomic_inc(&mem->section_count); + kobject_put(&mem->sysdev.kobj); + } else + ret = init_memory_block(&mem, section, state); + if (!ret) { - if (context == HOTPLUG) + if (context == HOTPLUG && + atomic_read(&mem->section_count) == sections_per_block) ret = register_mem_sect_under_node(mem, nid); } @@ -526,8 +558,9 @@ int remove_memory_block(unsigned long no mem_remove_simple_file(mem, state); mem_remove_simple_file(mem, phys_device); mem_remove_simple_file(mem, removable); - unregister_memory(mem, section); - } + unregister_memory(mem); + } else + kobject_put(&mem->sysdev.kobj); return 0; } @@ -538,7 +571,7 @@ int remove_memory_block(unsigned long no */ int register_new_memory(int nid, struct mem_section *section) { - return add_memory_block(nid, section, MEM_OFFLINE, HOTPLUG); + return add_memory_section(nid, section, MEM_OFFLINE, HOTPLUG); } int unregister_memory_section(struct mem_section *section) @@ -549,6 +582,24 @@ int unregister_memory_section(struct mem return remove_memory_block(0, section, 0); } +u32 __weak memory_block_size_bytes(void) +{ + return MIN_MEMORY_BLOCK_SIZE; +} + +static u32 get_memory_block_size(void) +{ + u32 block_sz; + + block_sz = memory_block_size_bytes(); + + /* Validate blk_sz is a power of 2 and not less than section size */ + if ((block_sz & (block_sz - 1)) || (block_sz < MIN_MEMORY_BLOCK_SIZE)) + block_sz = MIN_MEMORY_BLOCK_SIZE; + + return block_sz; +} + /* * Initialize the sysfs support for memory devices... */ @@ -557,12 +608,16 @@ int __init memory_dev_init(void) unsigned int i; int ret; int err; + int block_sz; memory_sysdev_class.kset.uevent_ops = &memory_uevent_ops; ret = sysdev_class_register(&memory_sysdev_class); if (ret) goto out; + block_sz = get_memory_block_size(); + sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE; + /* * Create entries for memory sections that were found * during boot and have been initialized @@ -570,8 +625,8 @@ int __init memory_dev_init(void) for (i = 0; i < NR_MEM_SECTIONS; i++) { if (!present_section_nr(i)) continue; - err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE, - BOOT); + err = add_memory_section(0, __nr_to_section(i), MEM_ONLINE, + BOOT); if (!ret) ret = err; } ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 4/8] v3 Allow memory_block to span multiple memory sections @ 2010-07-20 3:55 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:55 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: KAMEZAWA Hiroyuki, greg Update the memory sysfs code that each sysfs memory directory is now considered a memory block that can contain multiple memory sections per memory block. The default size of each memory block is SECTION_SIZE_BITS to maintain the current behavior of having a single memory section per memory block (i.e. one sysfs directory per memory section). For architectures that want to have memory blocks span multiple memory sections they need only define their own memory_block_size_bytes() routine. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> --- drivers/base/memory.c | 141 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 98 insertions(+), 43 deletions(-) Index: linux-2.6/drivers/base/memory.c =================================================================== --- linux-2.6.orig/drivers/base/memory.c 2010-07-19 20:44:01.000000000 -0500 +++ linux-2.6/drivers/base/memory.c 2010-07-19 21:12:22.000000000 -0500 @@ -28,6 +28,14 @@ #include <asm/uaccess.h> #define MEMORY_CLASS_NAME "memory" +#define MIN_MEMORY_BLOCK_SIZE (1 << SECTION_SIZE_BITS) + +static int sections_per_block; + +static inline int base_memory_block_id(int section_nr) +{ + return (section_nr / sections_per_block) * sections_per_block; +} static struct sysdev_class memory_sysdev_class = { .name = MEMORY_CLASS_NAME, @@ -82,22 +90,21 @@ EXPORT_SYMBOL(unregister_memory_isolate_ * register_memory - Setup a sysfs device for a memory block */ static -int register_memory(struct memory_block *memory, struct mem_section *section) +int register_memory(struct memory_block *memory) { int error; memory->sysdev.cls = &memory_sysdev_class; - memory->sysdev.id = __section_nr(section); + memory->sysdev.id = memory->start_phys_index; error = sysdev_register(&memory->sysdev); return error; } static void -unregister_memory(struct memory_block *memory, struct mem_section *section) +unregister_memory(struct memory_block *memory) { BUG_ON(memory->sysdev.cls != &memory_sysdev_class); - BUG_ON(memory->sysdev.id != __section_nr(section)); /* drop the ref. we got in remove_memory_block() */ kobject_put(&memory->sysdev.kobj); @@ -131,13 +138,16 @@ static ssize_t show_mem_end_phys_index(s static ssize_t show_mem_removable(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) { - unsigned long start_pfn; - int ret; + unsigned long i, pfn; + int ret = 1; struct memory_block *mem = container_of(dev, struct memory_block, sysdev); - start_pfn = section_nr_to_pfn(mem->start_phys_index); - ret = is_mem_section_removable(start_pfn, PAGES_PER_SECTION); + for (i = mem->start_phys_index; i <= mem->end_phys_index; i++) { + pfn = section_nr_to_pfn(i); + ret &= is_mem_section_removable(pfn, PAGES_PER_SECTION); + } + return sprintf(buf, "%d\n", ret); } @@ -190,17 +200,14 @@ int memory_isolate_notify(unsigned long * OK to have direct references to sparsemem variables in here. */ static int -memory_block_action(struct memory_block *mem, unsigned long action) +memory_section_action(unsigned long phys_index, unsigned long action) { int i; - unsigned long psection; unsigned long start_pfn, start_paddr; struct page *first_page; int ret; - int old_state = mem->state; - psection = mem->start_phys_index; - first_page = pfn_to_page(psection << PFN_SECTION_SHIFT); + first_page = pfn_to_page(phys_index << PFN_SECTION_SHIFT); /* * The probe routines leave the pages reserved, just @@ -213,8 +220,8 @@ memory_block_action(struct memory_block continue; printk(KERN_WARNING "section number %ld page number %d " - "not reserved, was it already online? \n", - psection, i); + "not reserved, was it already online?\n", + phys_index, i); return -EBUSY; } } @@ -225,18 +232,13 @@ memory_block_action(struct memory_block ret = online_pages(start_pfn, PAGES_PER_SECTION); break; case MEM_OFFLINE: - mem->state = MEM_GOING_OFFLINE; start_paddr = page_to_pfn(first_page) << PAGE_SHIFT; ret = remove_memory(start_paddr, PAGES_PER_SECTION << PAGE_SHIFT); - if (ret) { - mem->state = old_state; - break; - } break; default: - WARN(1, KERN_WARNING "%s(%p, %ld) unknown action: %ld\n", - __func__, mem, action, action); + WARN(1, KERN_WARNING "%s(%ld, %ld) unknown action: " + "%ld\n", __func__, phys_index, action, action); ret = -EINVAL; } @@ -246,7 +248,7 @@ memory_block_action(struct memory_block static int memory_block_change_state(struct memory_block *mem, unsigned long to_state, unsigned long from_state_req) { - int ret = 0; + int i, ret = 0; mutex_lock(&mem->state_mutex); if (mem->state != from_state_req) { @@ -254,8 +256,21 @@ static int memory_block_change_state(str goto out; } - ret = memory_block_action(mem, to_state); - if (!ret) + if (to_state == MEM_OFFLINE) + mem->state = MEM_GOING_OFFLINE; + + for (i = mem->start_phys_index; i <= mem->end_phys_index; i++) { + ret = memory_section_action(i, to_state); + if (ret) + break; + } + + if (ret) { + for (i = mem->start_phys_index; i <= mem->end_phys_index; i++) + memory_section_action(i, from_state_req); + + mem->state = from_state_req; + } else mem->state = to_state; out: @@ -268,20 +283,15 @@ store_mem_state(struct sys_device *dev, struct sysdev_attribute *attr, const char *buf, size_t count) { struct memory_block *mem; - unsigned int phys_section_nr; int ret = -EINVAL; mem = container_of(dev, struct memory_block, sysdev); - phys_section_nr = mem->start_phys_index; - - if (!present_section_nr(phys_section_nr)) - goto out; if (!strncmp(buf, "online", min((int)count, 6))) ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE); else if(!strncmp(buf, "offline", min((int)count, 7))) ret = memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE); -out: + if (ret) return ret; return count; @@ -458,12 +468,13 @@ struct memory_block *find_memory_block(s struct sys_device *sysdev; struct memory_block *mem; char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1]; + int block_id = base_memory_block_id(__section_nr(section)); /* * 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)); + sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, block_id); kobj = kset_find_obj(&memory_sysdev_class.kset, name); if (!kobj) @@ -475,24 +486,26 @@ struct memory_block *find_memory_block(s return mem; } -static int add_memory_block(int nid, struct mem_section *section, - unsigned long state, enum mem_add_context context) +static int init_memory_block(struct memory_block **memory, + struct mem_section *section, unsigned long state) { - struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL); + struct memory_block *mem; unsigned long start_pfn; int ret = 0; + mem = kzalloc(sizeof(*mem), GFP_KERNEL); if (!mem) return -ENOMEM; - mem->start_phys_index = __section_nr(section); + mem->start_phys_index = base_memory_block_id(__section_nr(section)); + mem->end_phys_index = mem->start_phys_index + sections_per_block - 1; mem->state = state; atomic_inc(&mem->section_count); mutex_init(&mem->state_mutex); start_pfn = section_nr_to_pfn(mem->start_phys_index); mem->phys_device = arch_get_memory_phys_device(start_pfn); - ret = register_memory(mem, section); + ret = register_memory(mem); if (!ret) ret = mem_create_simple_file(mem, start_phys_index); if (!ret) @@ -503,8 +516,27 @@ static int add_memory_block(int nid, str ret = mem_create_simple_file(mem, phys_device); if (!ret) ret = mem_create_simple_file(mem, removable); + + *memory = mem; + return ret; +} + +static int add_memory_section(int nid, struct mem_section *section, + unsigned long state, enum mem_add_context context) +{ + struct memory_block *mem; + int ret = 0; + + mem = find_memory_block(section); + if (mem) { + atomic_inc(&mem->section_count); + kobject_put(&mem->sysdev.kobj); + } else + ret = init_memory_block(&mem, section, state); + if (!ret) { - if (context == HOTPLUG) + if (context == HOTPLUG && + atomic_read(&mem->section_count) == sections_per_block) ret = register_mem_sect_under_node(mem, nid); } @@ -526,8 +558,9 @@ int remove_memory_block(unsigned long no mem_remove_simple_file(mem, state); mem_remove_simple_file(mem, phys_device); mem_remove_simple_file(mem, removable); - unregister_memory(mem, section); - } + unregister_memory(mem); + } else + kobject_put(&mem->sysdev.kobj); return 0; } @@ -538,7 +571,7 @@ int remove_memory_block(unsigned long no */ int register_new_memory(int nid, struct mem_section *section) { - return add_memory_block(nid, section, MEM_OFFLINE, HOTPLUG); + return add_memory_section(nid, section, MEM_OFFLINE, HOTPLUG); } int unregister_memory_section(struct mem_section *section) @@ -549,6 +582,24 @@ int unregister_memory_section(struct mem return remove_memory_block(0, section, 0); } +u32 __weak memory_block_size_bytes(void) +{ + return MIN_MEMORY_BLOCK_SIZE; +} + +static u32 get_memory_block_size(void) +{ + u32 block_sz; + + block_sz = memory_block_size_bytes(); + + /* Validate blk_sz is a power of 2 and not less than section size */ + if ((block_sz & (block_sz - 1)) || (block_sz < MIN_MEMORY_BLOCK_SIZE)) + block_sz = MIN_MEMORY_BLOCK_SIZE; + + return block_sz; +} + /* * Initialize the sysfs support for memory devices... */ @@ -557,12 +608,16 @@ int __init memory_dev_init(void) unsigned int i; int ret; int err; + int block_sz; memory_sysdev_class.kset.uevent_ops = &memory_uevent_ops; ret = sysdev_class_register(&memory_sysdev_class); if (ret) goto out; + block_sz = get_memory_block_size(); + sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE; + /* * Create entries for memory sections that were found * during boot and have been initialized @@ -570,8 +625,8 @@ int __init memory_dev_init(void) for (i = 0; i < NR_MEM_SECTIONS; i++) { if (!present_section_nr(i)) continue; - err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE, - BOOT); + err = add_memory_section(0, __nr_to_section(i), MEM_ONLINE, + BOOT); if (!ret) ret = err; } -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 4/8] v3 Allow memory_block to span multiple memory sections @ 2010-07-20 3:55 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:55 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: KAMEZAWA Hiroyuki, greg Update the memory sysfs code that each sysfs memory directory is now considered a memory block that can contain multiple memory sections per memory block. The default size of each memory block is SECTION_SIZE_BITS to maintain the current behavior of having a single memory section per memory block (i.e. one sysfs directory per memory section). For architectures that want to have memory blocks span multiple memory sections they need only define their own memory_block_size_bytes() routine. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> --- drivers/base/memory.c | 141 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 98 insertions(+), 43 deletions(-) Index: linux-2.6/drivers/base/memory.c =================================================================== --- linux-2.6.orig/drivers/base/memory.c 2010-07-19 20:44:01.000000000 -0500 +++ linux-2.6/drivers/base/memory.c 2010-07-19 21:12:22.000000000 -0500 @@ -28,6 +28,14 @@ #include <asm/uaccess.h> #define MEMORY_CLASS_NAME "memory" +#define MIN_MEMORY_BLOCK_SIZE (1 << SECTION_SIZE_BITS) + +static int sections_per_block; + +static inline int base_memory_block_id(int section_nr) +{ + return (section_nr / sections_per_block) * sections_per_block; +} static struct sysdev_class memory_sysdev_class = { .name = MEMORY_CLASS_NAME, @@ -82,22 +90,21 @@ EXPORT_SYMBOL(unregister_memory_isolate_ * register_memory - Setup a sysfs device for a memory block */ static -int register_memory(struct memory_block *memory, struct mem_section *section) +int register_memory(struct memory_block *memory) { int error; memory->sysdev.cls = &memory_sysdev_class; - memory->sysdev.id = __section_nr(section); + memory->sysdev.id = memory->start_phys_index; error = sysdev_register(&memory->sysdev); return error; } static void -unregister_memory(struct memory_block *memory, struct mem_section *section) +unregister_memory(struct memory_block *memory) { BUG_ON(memory->sysdev.cls != &memory_sysdev_class); - BUG_ON(memory->sysdev.id != __section_nr(section)); /* drop the ref. we got in remove_memory_block() */ kobject_put(&memory->sysdev.kobj); @@ -131,13 +138,16 @@ static ssize_t show_mem_end_phys_index(s static ssize_t show_mem_removable(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) { - unsigned long start_pfn; - int ret; + unsigned long i, pfn; + int ret = 1; struct memory_block *mem = container_of(dev, struct memory_block, sysdev); - start_pfn = section_nr_to_pfn(mem->start_phys_index); - ret = is_mem_section_removable(start_pfn, PAGES_PER_SECTION); + for (i = mem->start_phys_index; i <= mem->end_phys_index; i++) { + pfn = section_nr_to_pfn(i); + ret &= is_mem_section_removable(pfn, PAGES_PER_SECTION); + } + return sprintf(buf, "%d\n", ret); } @@ -190,17 +200,14 @@ int memory_isolate_notify(unsigned long * OK to have direct references to sparsemem variables in here. */ static int -memory_block_action(struct memory_block *mem, unsigned long action) +memory_section_action(unsigned long phys_index, unsigned long action) { int i; - unsigned long psection; unsigned long start_pfn, start_paddr; struct page *first_page; int ret; - int old_state = mem->state; - psection = mem->start_phys_index; - first_page = pfn_to_page(psection << PFN_SECTION_SHIFT); + first_page = pfn_to_page(phys_index << PFN_SECTION_SHIFT); /* * The probe routines leave the pages reserved, just @@ -213,8 +220,8 @@ memory_block_action(struct memory_block continue; printk(KERN_WARNING "section number %ld page number %d " - "not reserved, was it already online? \n", - psection, i); + "not reserved, was it already online?\n", + phys_index, i); return -EBUSY; } } @@ -225,18 +232,13 @@ memory_block_action(struct memory_block ret = online_pages(start_pfn, PAGES_PER_SECTION); break; case MEM_OFFLINE: - mem->state = MEM_GOING_OFFLINE; start_paddr = page_to_pfn(first_page) << PAGE_SHIFT; ret = remove_memory(start_paddr, PAGES_PER_SECTION << PAGE_SHIFT); - if (ret) { - mem->state = old_state; - break; - } break; default: - WARN(1, KERN_WARNING "%s(%p, %ld) unknown action: %ld\n", - __func__, mem, action, action); + WARN(1, KERN_WARNING "%s(%ld, %ld) unknown action: " + "%ld\n", __func__, phys_index, action, action); ret = -EINVAL; } @@ -246,7 +248,7 @@ memory_block_action(struct memory_block static int memory_block_change_state(struct memory_block *mem, unsigned long to_state, unsigned long from_state_req) { - int ret = 0; + int i, ret = 0; mutex_lock(&mem->state_mutex); if (mem->state != from_state_req) { @@ -254,8 +256,21 @@ static int memory_block_change_state(str goto out; } - ret = memory_block_action(mem, to_state); - if (!ret) + if (to_state == MEM_OFFLINE) + mem->state = MEM_GOING_OFFLINE; + + for (i = mem->start_phys_index; i <= mem->end_phys_index; i++) { + ret = memory_section_action(i, to_state); + if (ret) + break; + } + + if (ret) { + for (i = mem->start_phys_index; i <= mem->end_phys_index; i++) + memory_section_action(i, from_state_req); + + mem->state = from_state_req; + } else mem->state = to_state; out: @@ -268,20 +283,15 @@ store_mem_state(struct sys_device *dev, struct sysdev_attribute *attr, const char *buf, size_t count) { struct memory_block *mem; - unsigned int phys_section_nr; int ret = -EINVAL; mem = container_of(dev, struct memory_block, sysdev); - phys_section_nr = mem->start_phys_index; - - if (!present_section_nr(phys_section_nr)) - goto out; if (!strncmp(buf, "online", min((int)count, 6))) ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE); else if(!strncmp(buf, "offline", min((int)count, 7))) ret = memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE); -out: + if (ret) return ret; return count; @@ -458,12 +468,13 @@ struct memory_block *find_memory_block(s struct sys_device *sysdev; struct memory_block *mem; char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1]; + int block_id = base_memory_block_id(__section_nr(section)); /* * 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)); + sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, block_id); kobj = kset_find_obj(&memory_sysdev_class.kset, name); if (!kobj) @@ -475,24 +486,26 @@ struct memory_block *find_memory_block(s return mem; } -static int add_memory_block(int nid, struct mem_section *section, - unsigned long state, enum mem_add_context context) +static int init_memory_block(struct memory_block **memory, + struct mem_section *section, unsigned long state) { - struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL); + struct memory_block *mem; unsigned long start_pfn; int ret = 0; + mem = kzalloc(sizeof(*mem), GFP_KERNEL); if (!mem) return -ENOMEM; - mem->start_phys_index = __section_nr(section); + mem->start_phys_index = base_memory_block_id(__section_nr(section)); + mem->end_phys_index = mem->start_phys_index + sections_per_block - 1; mem->state = state; atomic_inc(&mem->section_count); mutex_init(&mem->state_mutex); start_pfn = section_nr_to_pfn(mem->start_phys_index); mem->phys_device = arch_get_memory_phys_device(start_pfn); - ret = register_memory(mem, section); + ret = register_memory(mem); if (!ret) ret = mem_create_simple_file(mem, start_phys_index); if (!ret) @@ -503,8 +516,27 @@ static int add_memory_block(int nid, str ret = mem_create_simple_file(mem, phys_device); if (!ret) ret = mem_create_simple_file(mem, removable); + + *memory = mem; + return ret; +} + +static int add_memory_section(int nid, struct mem_section *section, + unsigned long state, enum mem_add_context context) +{ + struct memory_block *mem; + int ret = 0; + + mem = find_memory_block(section); + if (mem) { + atomic_inc(&mem->section_count); + kobject_put(&mem->sysdev.kobj); + } else + ret = init_memory_block(&mem, section, state); + if (!ret) { - if (context == HOTPLUG) + if (context == HOTPLUG && + atomic_read(&mem->section_count) == sections_per_block) ret = register_mem_sect_under_node(mem, nid); } @@ -526,8 +558,9 @@ int remove_memory_block(unsigned long no mem_remove_simple_file(mem, state); mem_remove_simple_file(mem, phys_device); mem_remove_simple_file(mem, removable); - unregister_memory(mem, section); - } + unregister_memory(mem); + } else + kobject_put(&mem->sysdev.kobj); return 0; } @@ -538,7 +571,7 @@ int remove_memory_block(unsigned long no */ int register_new_memory(int nid, struct mem_section *section) { - return add_memory_block(nid, section, MEM_OFFLINE, HOTPLUG); + return add_memory_section(nid, section, MEM_OFFLINE, HOTPLUG); } int unregister_memory_section(struct mem_section *section) @@ -549,6 +582,24 @@ int unregister_memory_section(struct mem return remove_memory_block(0, section, 0); } +u32 __weak memory_block_size_bytes(void) +{ + return MIN_MEMORY_BLOCK_SIZE; +} + +static u32 get_memory_block_size(void) +{ + u32 block_sz; + + block_sz = memory_block_size_bytes(); + + /* Validate blk_sz is a power of 2 and not less than section size */ + if ((block_sz & (block_sz - 1)) || (block_sz < MIN_MEMORY_BLOCK_SIZE)) + block_sz = MIN_MEMORY_BLOCK_SIZE; + + return block_sz; +} + /* * Initialize the sysfs support for memory devices... */ @@ -557,12 +608,16 @@ int __init memory_dev_init(void) unsigned int i; int ret; int err; + int block_sz; memory_sysdev_class.kset.uevent_ops = &memory_uevent_ops; ret = sysdev_class_register(&memory_sysdev_class); if (ret) goto out; + block_sz = get_memory_block_size(); + sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE; + /* * Create entries for memory sections that were found * during boot and have been initialized @@ -570,8 +625,8 @@ int __init memory_dev_init(void) for (i = 0; i < NR_MEM_SECTIONS; i++) { if (!present_section_nr(i)) continue; - err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE, - BOOT); + err = add_memory_section(0, __nr_to_section(i), MEM_ONLINE, + BOOT); if (!ret) ret = err; } ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 4/8] v3 Allow memory_block to span multiple memory sections 2010-07-20 3:55 ` Nathan Fontenot (?) @ 2010-07-20 7:15 ` KAMEZAWA Hiroyuki -1 siblings, 0 replies; 90+ messages in thread From: KAMEZAWA Hiroyuki @ 2010-07-20 7:15 UTC (permalink / raw) To: Nathan Fontenot; +Cc: linux-mm, greg, linux-kernel, linuxppc-dev On Mon, 19 Jul 2010 22:55:08 -0500 Nathan Fontenot <nfont@austin.ibm.com> wrote: > Update the memory sysfs code that each sysfs memory directory is now > considered a memory block that can contain multiple memory sections per > memory block. The default size of each memory block is SECTION_SIZE_BITS > to maintain the current behavior of having a single memory section per > memory block (i.e. one sysfs directory per memory section). > > For architectures that want to have memory blocks span multiple > memory sections they need only define their own memory_block_size_bytes() > routine. > > Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> > --- > drivers/base/memory.c | 141 ++++++++++++++++++++++++++++++++++---------------- > 1 file changed, 98 insertions(+), 43 deletions(-) > > Index: linux-2.6/drivers/base/memory.c > =================================================================== > --- linux-2.6.orig/drivers/base/memory.c 2010-07-19 20:44:01.000000000 -0500 > +++ linux-2.6/drivers/base/memory.c 2010-07-19 21:12:22.000000000 -0500 > @@ -28,6 +28,14 @@ > #include <asm/uaccess.h> > > #define MEMORY_CLASS_NAME "memory" > +#define MIN_MEMORY_BLOCK_SIZE (1 << SECTION_SIZE_BITS) > + > +static int sections_per_block; > + > +static inline int base_memory_block_id(int section_nr) > +{ > + return (section_nr / sections_per_block) * sections_per_block; > +} > > static struct sysdev_class memory_sysdev_class = { > .name = MEMORY_CLASS_NAME, > @@ -82,22 +90,21 @@ EXPORT_SYMBOL(unregister_memory_isolate_ > * register_memory - Setup a sysfs device for a memory block > */ > static > -int register_memory(struct memory_block *memory, struct mem_section *section) > +int register_memory(struct memory_block *memory) > { > int error; > > memory->sysdev.cls = &memory_sysdev_class; > - memory->sysdev.id = __section_nr(section); > + memory->sysdev.id = memory->start_phys_index; I'm curious that this memory->start_phys_index can't overflow ? sysdev.id is 32bit. Thanks, -Kame ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 4/8] v3 Allow memory_block to span multiple memory sections @ 2010-07-20 7:15 ` KAMEZAWA Hiroyuki 0 siblings, 0 replies; 90+ messages in thread From: KAMEZAWA Hiroyuki @ 2010-07-20 7:15 UTC (permalink / raw) To: Nathan Fontenot; +Cc: linux-kernel, linux-mm, linuxppc-dev, greg On Mon, 19 Jul 2010 22:55:08 -0500 Nathan Fontenot <nfont@austin.ibm.com> wrote: > Update the memory sysfs code that each sysfs memory directory is now > considered a memory block that can contain multiple memory sections per > memory block. The default size of each memory block is SECTION_SIZE_BITS > to maintain the current behavior of having a single memory section per > memory block (i.e. one sysfs directory per memory section). > > For architectures that want to have memory blocks span multiple > memory sections they need only define their own memory_block_size_bytes() > routine. > > Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> > --- > drivers/base/memory.c | 141 ++++++++++++++++++++++++++++++++++---------------- > 1 file changed, 98 insertions(+), 43 deletions(-) > > Index: linux-2.6/drivers/base/memory.c > =================================================================== > --- linux-2.6.orig/drivers/base/memory.c 2010-07-19 20:44:01.000000000 -0500 > +++ linux-2.6/drivers/base/memory.c 2010-07-19 21:12:22.000000000 -0500 > @@ -28,6 +28,14 @@ > #include <asm/uaccess.h> > > #define MEMORY_CLASS_NAME "memory" > +#define MIN_MEMORY_BLOCK_SIZE (1 << SECTION_SIZE_BITS) > + > +static int sections_per_block; > + > +static inline int base_memory_block_id(int section_nr) > +{ > + return (section_nr / sections_per_block) * sections_per_block; > +} > > static struct sysdev_class memory_sysdev_class = { > .name = MEMORY_CLASS_NAME, > @@ -82,22 +90,21 @@ EXPORT_SYMBOL(unregister_memory_isolate_ > * register_memory - Setup a sysfs device for a memory block > */ > static > -int register_memory(struct memory_block *memory, struct mem_section *section) > +int register_memory(struct memory_block *memory) > { > int error; > > memory->sysdev.cls = &memory_sysdev_class; > - memory->sysdev.id = __section_nr(section); > + memory->sysdev.id = memory->start_phys_index; I'm curious that this memory->start_phys_index can't overflow ? sysdev.id is 32bit. Thanks, -Kame -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 4/8] v3 Allow memory_block to span multiple memory sections @ 2010-07-20 7:15 ` KAMEZAWA Hiroyuki 0 siblings, 0 replies; 90+ messages in thread From: KAMEZAWA Hiroyuki @ 2010-07-20 7:15 UTC (permalink / raw) To: Nathan Fontenot; +Cc: linux-kernel, linux-mm, linuxppc-dev, greg On Mon, 19 Jul 2010 22:55:08 -0500 Nathan Fontenot <nfont@austin.ibm.com> wrote: > Update the memory sysfs code that each sysfs memory directory is now > considered a memory block that can contain multiple memory sections per > memory block. The default size of each memory block is SECTION_SIZE_BITS > to maintain the current behavior of having a single memory section per > memory block (i.e. one sysfs directory per memory section). > > For architectures that want to have memory blocks span multiple > memory sections they need only define their own memory_block_size_bytes() > routine. > > Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> > --- > drivers/base/memory.c | 141 ++++++++++++++++++++++++++++++++++---------------- > 1 file changed, 98 insertions(+), 43 deletions(-) > > Index: linux-2.6/drivers/base/memory.c > =================================================================== > --- linux-2.6.orig/drivers/base/memory.c 2010-07-19 20:44:01.000000000 -0500 > +++ linux-2.6/drivers/base/memory.c 2010-07-19 21:12:22.000000000 -0500 > @@ -28,6 +28,14 @@ > #include <asm/uaccess.h> > > #define MEMORY_CLASS_NAME "memory" > +#define MIN_MEMORY_BLOCK_SIZE (1 << SECTION_SIZE_BITS) > + > +static int sections_per_block; > + > +static inline int base_memory_block_id(int section_nr) > +{ > + return (section_nr / sections_per_block) * sections_per_block; > +} > > static struct sysdev_class memory_sysdev_class = { > .name = MEMORY_CLASS_NAME, > @@ -82,22 +90,21 @@ EXPORT_SYMBOL(unregister_memory_isolate_ > * register_memory - Setup a sysfs device for a memory block > */ > static > -int register_memory(struct memory_block *memory, struct mem_section *section) > +int register_memory(struct memory_block *memory) > { > int error; > > memory->sysdev.cls = &memory_sysdev_class; > - memory->sysdev.id = __section_nr(section); > + memory->sysdev.id = memory->start_phys_index; I'm curious that this memory->start_phys_index can't overflow ? sysdev.id is 32bit. Thanks, -Kame ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 4/8] v3 Allow memory_block to span multiple memory sections 2010-07-20 3:55 ` Nathan Fontenot (?) @ 2010-07-20 13:28 ` Nathan Fontenot -1 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 13:28 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: greg, KAMEZAWA Hiroyuki Update the memory sysfs code that each sysfs memory directory is now considered a memory block that can contain multiple memory sections per memory block. The default size of each memory block is SECTION_SIZE_BITS to maintain the current behavior of having a single memory section per memory block (i.e. one sysfs directory per memory section). For architectures that want to have memory blocks span multiple memory sections they need only define their own memory_block_size_bytes() routine. Patch refreshed to apply cleanly with previous two patch updates. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> --- drivers/base/memory.c | 141 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 98 insertions(+), 43 deletions(-) Index: linux-2.6/drivers/base/memory.c =================================================================== --- linux-2.6.orig/drivers/base/memory.c 2010-07-20 06:43:29.000000000 -0500 +++ linux-2.6/drivers/base/memory.c 2010-07-20 06:44:30.000000000 -0500 @@ -28,6 +28,14 @@ #include <asm/uaccess.h> #define MEMORY_CLASS_NAME "memory" +#define MIN_MEMORY_BLOCK_SIZE (1 << SECTION_SIZE_BITS) + +static int sections_per_block; + +static inline int base_memory_block_id(int section_nr) +{ + return (section_nr / sections_per_block) * sections_per_block; +} static struct sysdev_class memory_sysdev_class = { .name = MEMORY_CLASS_NAME, @@ -82,22 +90,21 @@ EXPORT_SYMBOL(unregister_memory_isolate_ * register_memory - Setup a sysfs device for a memory block */ static -int register_memory(struct memory_block *memory, struct mem_section *section) +int register_memory(struct memory_block *memory) { int error; memory->sysdev.cls = &memory_sysdev_class; - memory->sysdev.id = __section_nr(section); + memory->sysdev.id = memory->start_phys_index; error = sysdev_register(&memory->sysdev); return error; } static void -unregister_memory(struct memory_block *memory, struct mem_section *section) +unregister_memory(struct memory_block *memory) { BUG_ON(memory->sysdev.cls != &memory_sysdev_class); - BUG_ON(memory->sysdev.id != __section_nr(section)); /* drop the ref. we got in remove_memory_block() */ kobject_put(&memory->sysdev.kobj); @@ -131,13 +138,16 @@ static ssize_t show_mem_end_phys_index(s static ssize_t show_mem_removable(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) { - unsigned long start_pfn; - int ret; + unsigned long i, pfn; + int ret = 1; struct memory_block *mem = container_of(dev, struct memory_block, sysdev); - start_pfn = section_nr_to_pfn(mem->start_phys_index); - ret = is_mem_section_removable(start_pfn, PAGES_PER_SECTION); + for (i = mem->start_phys_index; i <= mem->end_phys_index; i++) { + pfn = section_nr_to_pfn(i); + ret &= is_mem_section_removable(pfn, PAGES_PER_SECTION); + } + return sprintf(buf, "%d\n", ret); } @@ -190,17 +200,14 @@ int memory_isolate_notify(unsigned long * OK to have direct references to sparsemem variables in here. */ static int -memory_block_action(struct memory_block *mem, unsigned long action) +memory_section_action(unsigned long phys_index, unsigned long action) { int i; - unsigned long psection; unsigned long start_pfn, start_paddr; struct page *first_page; int ret; - int old_state = mem->state; - psection = mem->start_phys_index; - first_page = pfn_to_page(psection << PFN_SECTION_SHIFT); + first_page = pfn_to_page(phys_index << PFN_SECTION_SHIFT); /* * The probe routines leave the pages reserved, just @@ -213,8 +220,8 @@ memory_block_action(struct memory_block continue; printk(KERN_WARNING "section number %ld page number %d " - "not reserved, was it already online? \n", - psection, i); + "not reserved, was it already online?\n", + phys_index, i); return -EBUSY; } } @@ -225,18 +232,13 @@ memory_block_action(struct memory_block ret = online_pages(start_pfn, PAGES_PER_SECTION); break; case MEM_OFFLINE: - mem->state = MEM_GOING_OFFLINE; start_paddr = page_to_pfn(first_page) << PAGE_SHIFT; ret = remove_memory(start_paddr, PAGES_PER_SECTION << PAGE_SHIFT); - if (ret) { - mem->state = old_state; - break; - } break; default: - WARN(1, KERN_WARNING "%s(%p, %ld) unknown action: %ld\n", - __func__, mem, action, action); + WARN(1, KERN_WARNING "%s(%ld, %ld) unknown action: " + "%ld\n", __func__, phys_index, action, action); ret = -EINVAL; } @@ -246,7 +248,7 @@ memory_block_action(struct memory_block static int memory_block_change_state(struct memory_block *mem, unsigned long to_state, unsigned long from_state_req) { - int ret = 0; + int i, ret = 0; mutex_lock(&mem->state_mutex); if (mem->state != from_state_req) { @@ -254,8 +256,21 @@ static int memory_block_change_state(str goto out; } - ret = memory_block_action(mem, to_state); - if (!ret) + if (to_state == MEM_OFFLINE) + mem->state = MEM_GOING_OFFLINE; + + for (i = mem->start_phys_index; i <= mem->end_phys_index; i++) { + ret = memory_section_action(i, to_state); + if (ret) + break; + } + + if (ret) { + for (i = mem->start_phys_index; i <= mem->end_phys_index; i++) + memory_section_action(i, from_state_req); + + mem->state = from_state_req; + } else mem->state = to_state; out: @@ -268,20 +283,15 @@ store_mem_state(struct sys_device *dev, struct sysdev_attribute *attr, const char *buf, size_t count) { struct memory_block *mem; - unsigned int phys_section_nr; int ret = -EINVAL; mem = container_of(dev, struct memory_block, sysdev); - phys_section_nr = mem->start_phys_index; - - if (!present_section_nr(phys_section_nr)) - goto out; if (!strncmp(buf, "online", min((int)count, 6))) ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE); else if(!strncmp(buf, "offline", min((int)count, 7))) ret = memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE); -out: + if (ret) return ret; return count; @@ -458,12 +468,13 @@ struct memory_block *find_memory_block(s struct sys_device *sysdev; struct memory_block *mem; char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1]; + int block_id = base_memory_block_id(__section_nr(section)); /* * 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)); + sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, block_id); kobj = kset_find_obj(&memory_sysdev_class.kset, name); if (!kobj) @@ -475,24 +486,26 @@ struct memory_block *find_memory_block(s return mem; } -static int add_memory_block(int nid, struct mem_section *section, - unsigned long state, enum mem_add_context context) +static int init_memory_block(struct memory_block **memory, + struct mem_section *section, unsigned long state) { - struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL); + struct memory_block *mem; unsigned long start_pfn; int ret = 0; + mem = kzalloc(sizeof(*mem), GFP_KERNEL); if (!mem) return -ENOMEM; - mem->start_phys_index = __section_nr(section); + mem->start_phys_index = base_memory_block_id(__section_nr(section)); + mem->end_phys_index = mem->start_phys_index + sections_per_block - 1; mem->state = state; atomic_inc(&mem->section_count); mutex_init(&mem->state_mutex); start_pfn = section_nr_to_pfn(mem->start_phys_index); mem->phys_device = arch_get_memory_phys_device(start_pfn); - ret = register_memory(mem, section); + ret = register_memory(mem); if (!ret) ret = mem_create_simple_file(mem, phys_index); if (!ret) @@ -503,8 +516,27 @@ static int add_memory_block(int nid, str ret = mem_create_simple_file(mem, phys_device); if (!ret) ret = mem_create_simple_file(mem, removable); + + *memory = mem; + return ret; +} + +static int add_memory_section(int nid, struct mem_section *section, + unsigned long state, enum mem_add_context context) +{ + struct memory_block *mem; + int ret = 0; + + mem = find_memory_block(section); + if (mem) { + atomic_inc(&mem->section_count); + kobject_put(&mem->sysdev.kobj); + } else + ret = init_memory_block(&mem, section, state); + if (!ret) { - if (context == HOTPLUG) + if (context == HOTPLUG && + atomic_read(&mem->section_count) == sections_per_block) ret = register_mem_sect_under_node(mem, nid); } @@ -525,8 +557,9 @@ int remove_memory_block(unsigned long no mem_remove_simple_file(mem, state); mem_remove_simple_file(mem, phys_device); mem_remove_simple_file(mem, removable); - unregister_memory(mem, section); - } + unregister_memory(mem); + } else + kobject_put(&mem->sysdev.kobj); return 0; } @@ -537,7 +570,7 @@ int remove_memory_block(unsigned long no */ int register_new_memory(int nid, struct mem_section *section) { - return add_memory_block(nid, section, MEM_OFFLINE, HOTPLUG); + return add_memory_section(nid, section, MEM_OFFLINE, HOTPLUG); } int unregister_memory_section(struct mem_section *section) @@ -548,6 +581,24 @@ int unregister_memory_section(struct mem return remove_memory_block(0, section, 0); } +u32 __weak memory_block_size_bytes(void) +{ + return MIN_MEMORY_BLOCK_SIZE; +} + +static u32 get_memory_block_size(void) +{ + u32 block_sz; + + block_sz = memory_block_size_bytes(); + + /* Validate blk_sz is a power of 2 and not less than section size */ + if ((block_sz & (block_sz - 1)) || (block_sz < MIN_MEMORY_BLOCK_SIZE)) + block_sz = MIN_MEMORY_BLOCK_SIZE; + + return block_sz; +} + /* * Initialize the sysfs support for memory devices... */ @@ -556,12 +607,16 @@ int __init memory_dev_init(void) unsigned int i; int ret; int err; + int block_sz; memory_sysdev_class.kset.uevent_ops = &memory_uevent_ops; ret = sysdev_class_register(&memory_sysdev_class); if (ret) goto out; + block_sz = get_memory_block_size(); + sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE; + /* * Create entries for memory sections that were found * during boot and have been initialized @@ -569,8 +624,8 @@ int __init memory_dev_init(void) for (i = 0; i < NR_MEM_SECTIONS; i++) { if (!present_section_nr(i)) continue; - err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE, - BOOT); + err = add_memory_section(0, __nr_to_section(i), MEM_ONLINE, + BOOT); if (!ret) ret = err; } ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 4/8] v3 Allow memory_block to span multiple memory sections @ 2010-07-20 13:28 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 13:28 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: KAMEZAWA Hiroyuki, greg Update the memory sysfs code that each sysfs memory directory is now considered a memory block that can contain multiple memory sections per memory block. The default size of each memory block is SECTION_SIZE_BITS to maintain the current behavior of having a single memory section per memory block (i.e. one sysfs directory per memory section). For architectures that want to have memory blocks span multiple memory sections they need only define their own memory_block_size_bytes() routine. Patch refreshed to apply cleanly with previous two patch updates. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> --- drivers/base/memory.c | 141 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 98 insertions(+), 43 deletions(-) Index: linux-2.6/drivers/base/memory.c =================================================================== --- linux-2.6.orig/drivers/base/memory.c 2010-07-20 06:43:29.000000000 -0500 +++ linux-2.6/drivers/base/memory.c 2010-07-20 06:44:30.000000000 -0500 @@ -28,6 +28,14 @@ #include <asm/uaccess.h> #define MEMORY_CLASS_NAME "memory" +#define MIN_MEMORY_BLOCK_SIZE (1 << SECTION_SIZE_BITS) + +static int sections_per_block; + +static inline int base_memory_block_id(int section_nr) +{ + return (section_nr / sections_per_block) * sections_per_block; +} static struct sysdev_class memory_sysdev_class = { .name = MEMORY_CLASS_NAME, @@ -82,22 +90,21 @@ EXPORT_SYMBOL(unregister_memory_isolate_ * register_memory - Setup a sysfs device for a memory block */ static -int register_memory(struct memory_block *memory, struct mem_section *section) +int register_memory(struct memory_block *memory) { int error; memory->sysdev.cls = &memory_sysdev_class; - memory->sysdev.id = __section_nr(section); + memory->sysdev.id = memory->start_phys_index; error = sysdev_register(&memory->sysdev); return error; } static void -unregister_memory(struct memory_block *memory, struct mem_section *section) +unregister_memory(struct memory_block *memory) { BUG_ON(memory->sysdev.cls != &memory_sysdev_class); - BUG_ON(memory->sysdev.id != __section_nr(section)); /* drop the ref. we got in remove_memory_block() */ kobject_put(&memory->sysdev.kobj); @@ -131,13 +138,16 @@ static ssize_t show_mem_end_phys_index(s static ssize_t show_mem_removable(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) { - unsigned long start_pfn; - int ret; + unsigned long i, pfn; + int ret = 1; struct memory_block *mem = container_of(dev, struct memory_block, sysdev); - start_pfn = section_nr_to_pfn(mem->start_phys_index); - ret = is_mem_section_removable(start_pfn, PAGES_PER_SECTION); + for (i = mem->start_phys_index; i <= mem->end_phys_index; i++) { + pfn = section_nr_to_pfn(i); + ret &= is_mem_section_removable(pfn, PAGES_PER_SECTION); + } + return sprintf(buf, "%d\n", ret); } @@ -190,17 +200,14 @@ int memory_isolate_notify(unsigned long * OK to have direct references to sparsemem variables in here. */ static int -memory_block_action(struct memory_block *mem, unsigned long action) +memory_section_action(unsigned long phys_index, unsigned long action) { int i; - unsigned long psection; unsigned long start_pfn, start_paddr; struct page *first_page; int ret; - int old_state = mem->state; - psection = mem->start_phys_index; - first_page = pfn_to_page(psection << PFN_SECTION_SHIFT); + first_page = pfn_to_page(phys_index << PFN_SECTION_SHIFT); /* * The probe routines leave the pages reserved, just @@ -213,8 +220,8 @@ memory_block_action(struct memory_block continue; printk(KERN_WARNING "section number %ld page number %d " - "not reserved, was it already online? \n", - psection, i); + "not reserved, was it already online?\n", + phys_index, i); return -EBUSY; } } @@ -225,18 +232,13 @@ memory_block_action(struct memory_block ret = online_pages(start_pfn, PAGES_PER_SECTION); break; case MEM_OFFLINE: - mem->state = MEM_GOING_OFFLINE; start_paddr = page_to_pfn(first_page) << PAGE_SHIFT; ret = remove_memory(start_paddr, PAGES_PER_SECTION << PAGE_SHIFT); - if (ret) { - mem->state = old_state; - break; - } break; default: - WARN(1, KERN_WARNING "%s(%p, %ld) unknown action: %ld\n", - __func__, mem, action, action); + WARN(1, KERN_WARNING "%s(%ld, %ld) unknown action: " + "%ld\n", __func__, phys_index, action, action); ret = -EINVAL; } @@ -246,7 +248,7 @@ memory_block_action(struct memory_block static int memory_block_change_state(struct memory_block *mem, unsigned long to_state, unsigned long from_state_req) { - int ret = 0; + int i, ret = 0; mutex_lock(&mem->state_mutex); if (mem->state != from_state_req) { @@ -254,8 +256,21 @@ static int memory_block_change_state(str goto out; } - ret = memory_block_action(mem, to_state); - if (!ret) + if (to_state == MEM_OFFLINE) + mem->state = MEM_GOING_OFFLINE; + + for (i = mem->start_phys_index; i <= mem->end_phys_index; i++) { + ret = memory_section_action(i, to_state); + if (ret) + break; + } + + if (ret) { + for (i = mem->start_phys_index; i <= mem->end_phys_index; i++) + memory_section_action(i, from_state_req); + + mem->state = from_state_req; + } else mem->state = to_state; out: @@ -268,20 +283,15 @@ store_mem_state(struct sys_device *dev, struct sysdev_attribute *attr, const char *buf, size_t count) { struct memory_block *mem; - unsigned int phys_section_nr; int ret = -EINVAL; mem = container_of(dev, struct memory_block, sysdev); - phys_section_nr = mem->start_phys_index; - - if (!present_section_nr(phys_section_nr)) - goto out; if (!strncmp(buf, "online", min((int)count, 6))) ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE); else if(!strncmp(buf, "offline", min((int)count, 7))) ret = memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE); -out: + if (ret) return ret; return count; @@ -458,12 +468,13 @@ struct memory_block *find_memory_block(s struct sys_device *sysdev; struct memory_block *mem; char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1]; + int block_id = base_memory_block_id(__section_nr(section)); /* * 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)); + sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, block_id); kobj = kset_find_obj(&memory_sysdev_class.kset, name); if (!kobj) @@ -475,24 +486,26 @@ struct memory_block *find_memory_block(s return mem; } -static int add_memory_block(int nid, struct mem_section *section, - unsigned long state, enum mem_add_context context) +static int init_memory_block(struct memory_block **memory, + struct mem_section *section, unsigned long state) { - struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL); + struct memory_block *mem; unsigned long start_pfn; int ret = 0; + mem = kzalloc(sizeof(*mem), GFP_KERNEL); if (!mem) return -ENOMEM; - mem->start_phys_index = __section_nr(section); + mem->start_phys_index = base_memory_block_id(__section_nr(section)); + mem->end_phys_index = mem->start_phys_index + sections_per_block - 1; mem->state = state; atomic_inc(&mem->section_count); mutex_init(&mem->state_mutex); start_pfn = section_nr_to_pfn(mem->start_phys_index); mem->phys_device = arch_get_memory_phys_device(start_pfn); - ret = register_memory(mem, section); + ret = register_memory(mem); if (!ret) ret = mem_create_simple_file(mem, phys_index); if (!ret) @@ -503,8 +516,27 @@ static int add_memory_block(int nid, str ret = mem_create_simple_file(mem, phys_device); if (!ret) ret = mem_create_simple_file(mem, removable); + + *memory = mem; + return ret; +} + +static int add_memory_section(int nid, struct mem_section *section, + unsigned long state, enum mem_add_context context) +{ + struct memory_block *mem; + int ret = 0; + + mem = find_memory_block(section); + if (mem) { + atomic_inc(&mem->section_count); + kobject_put(&mem->sysdev.kobj); + } else + ret = init_memory_block(&mem, section, state); + if (!ret) { - if (context == HOTPLUG) + if (context == HOTPLUG && + atomic_read(&mem->section_count) == sections_per_block) ret = register_mem_sect_under_node(mem, nid); } @@ -525,8 +557,9 @@ int remove_memory_block(unsigned long no mem_remove_simple_file(mem, state); mem_remove_simple_file(mem, phys_device); mem_remove_simple_file(mem, removable); - unregister_memory(mem, section); - } + unregister_memory(mem); + } else + kobject_put(&mem->sysdev.kobj); return 0; } @@ -537,7 +570,7 @@ int remove_memory_block(unsigned long no */ int register_new_memory(int nid, struct mem_section *section) { - return add_memory_block(nid, section, MEM_OFFLINE, HOTPLUG); + return add_memory_section(nid, section, MEM_OFFLINE, HOTPLUG); } int unregister_memory_section(struct mem_section *section) @@ -548,6 +581,24 @@ int unregister_memory_section(struct mem return remove_memory_block(0, section, 0); } +u32 __weak memory_block_size_bytes(void) +{ + return MIN_MEMORY_BLOCK_SIZE; +} + +static u32 get_memory_block_size(void) +{ + u32 block_sz; + + block_sz = memory_block_size_bytes(); + + /* Validate blk_sz is a power of 2 and not less than section size */ + if ((block_sz & (block_sz - 1)) || (block_sz < MIN_MEMORY_BLOCK_SIZE)) + block_sz = MIN_MEMORY_BLOCK_SIZE; + + return block_sz; +} + /* * Initialize the sysfs support for memory devices... */ @@ -556,12 +607,16 @@ int __init memory_dev_init(void) unsigned int i; int ret; int err; + int block_sz; memory_sysdev_class.kset.uevent_ops = &memory_uevent_ops; ret = sysdev_class_register(&memory_sysdev_class); if (ret) goto out; + block_sz = get_memory_block_size(); + sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE; + /* * Create entries for memory sections that were found * during boot and have been initialized @@ -569,8 +624,8 @@ int __init memory_dev_init(void) for (i = 0; i < NR_MEM_SECTIONS; i++) { if (!present_section_nr(i)) continue; - err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE, - BOOT); + err = add_memory_section(0, __nr_to_section(i), MEM_ONLINE, + BOOT); if (!ret) ret = err; } -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 4/8] v3 Allow memory_block to span multiple memory sections @ 2010-07-20 13:28 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 13:28 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: KAMEZAWA Hiroyuki, greg Update the memory sysfs code that each sysfs memory directory is now considered a memory block that can contain multiple memory sections per memory block. The default size of each memory block is SECTION_SIZE_BITS to maintain the current behavior of having a single memory section per memory block (i.e. one sysfs directory per memory section). For architectures that want to have memory blocks span multiple memory sections they need only define their own memory_block_size_bytes() routine. Patch refreshed to apply cleanly with previous two patch updates. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> --- drivers/base/memory.c | 141 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 98 insertions(+), 43 deletions(-) Index: linux-2.6/drivers/base/memory.c =================================================================== --- linux-2.6.orig/drivers/base/memory.c 2010-07-20 06:43:29.000000000 -0500 +++ linux-2.6/drivers/base/memory.c 2010-07-20 06:44:30.000000000 -0500 @@ -28,6 +28,14 @@ #include <asm/uaccess.h> #define MEMORY_CLASS_NAME "memory" +#define MIN_MEMORY_BLOCK_SIZE (1 << SECTION_SIZE_BITS) + +static int sections_per_block; + +static inline int base_memory_block_id(int section_nr) +{ + return (section_nr / sections_per_block) * sections_per_block; +} static struct sysdev_class memory_sysdev_class = { .name = MEMORY_CLASS_NAME, @@ -82,22 +90,21 @@ EXPORT_SYMBOL(unregister_memory_isolate_ * register_memory - Setup a sysfs device for a memory block */ static -int register_memory(struct memory_block *memory, struct mem_section *section) +int register_memory(struct memory_block *memory) { int error; memory->sysdev.cls = &memory_sysdev_class; - memory->sysdev.id = __section_nr(section); + memory->sysdev.id = memory->start_phys_index; error = sysdev_register(&memory->sysdev); return error; } static void -unregister_memory(struct memory_block *memory, struct mem_section *section) +unregister_memory(struct memory_block *memory) { BUG_ON(memory->sysdev.cls != &memory_sysdev_class); - BUG_ON(memory->sysdev.id != __section_nr(section)); /* drop the ref. we got in remove_memory_block() */ kobject_put(&memory->sysdev.kobj); @@ -131,13 +138,16 @@ static ssize_t show_mem_end_phys_index(s static ssize_t show_mem_removable(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) { - unsigned long start_pfn; - int ret; + unsigned long i, pfn; + int ret = 1; struct memory_block *mem = container_of(dev, struct memory_block, sysdev); - start_pfn = section_nr_to_pfn(mem->start_phys_index); - ret = is_mem_section_removable(start_pfn, PAGES_PER_SECTION); + for (i = mem->start_phys_index; i <= mem->end_phys_index; i++) { + pfn = section_nr_to_pfn(i); + ret &= is_mem_section_removable(pfn, PAGES_PER_SECTION); + } + return sprintf(buf, "%d\n", ret); } @@ -190,17 +200,14 @@ int memory_isolate_notify(unsigned long * OK to have direct references to sparsemem variables in here. */ static int -memory_block_action(struct memory_block *mem, unsigned long action) +memory_section_action(unsigned long phys_index, unsigned long action) { int i; - unsigned long psection; unsigned long start_pfn, start_paddr; struct page *first_page; int ret; - int old_state = mem->state; - psection = mem->start_phys_index; - first_page = pfn_to_page(psection << PFN_SECTION_SHIFT); + first_page = pfn_to_page(phys_index << PFN_SECTION_SHIFT); /* * The probe routines leave the pages reserved, just @@ -213,8 +220,8 @@ memory_block_action(struct memory_block continue; printk(KERN_WARNING "section number %ld page number %d " - "not reserved, was it already online? \n", - psection, i); + "not reserved, was it already online?\n", + phys_index, i); return -EBUSY; } } @@ -225,18 +232,13 @@ memory_block_action(struct memory_block ret = online_pages(start_pfn, PAGES_PER_SECTION); break; case MEM_OFFLINE: - mem->state = MEM_GOING_OFFLINE; start_paddr = page_to_pfn(first_page) << PAGE_SHIFT; ret = remove_memory(start_paddr, PAGES_PER_SECTION << PAGE_SHIFT); - if (ret) { - mem->state = old_state; - break; - } break; default: - WARN(1, KERN_WARNING "%s(%p, %ld) unknown action: %ld\n", - __func__, mem, action, action); + WARN(1, KERN_WARNING "%s(%ld, %ld) unknown action: " + "%ld\n", __func__, phys_index, action, action); ret = -EINVAL; } @@ -246,7 +248,7 @@ memory_block_action(struct memory_block static int memory_block_change_state(struct memory_block *mem, unsigned long to_state, unsigned long from_state_req) { - int ret = 0; + int i, ret = 0; mutex_lock(&mem->state_mutex); if (mem->state != from_state_req) { @@ -254,8 +256,21 @@ static int memory_block_change_state(str goto out; } - ret = memory_block_action(mem, to_state); - if (!ret) + if (to_state == MEM_OFFLINE) + mem->state = MEM_GOING_OFFLINE; + + for (i = mem->start_phys_index; i <= mem->end_phys_index; i++) { + ret = memory_section_action(i, to_state); + if (ret) + break; + } + + if (ret) { + for (i = mem->start_phys_index; i <= mem->end_phys_index; i++) + memory_section_action(i, from_state_req); + + mem->state = from_state_req; + } else mem->state = to_state; out: @@ -268,20 +283,15 @@ store_mem_state(struct sys_device *dev, struct sysdev_attribute *attr, const char *buf, size_t count) { struct memory_block *mem; - unsigned int phys_section_nr; int ret = -EINVAL; mem = container_of(dev, struct memory_block, sysdev); - phys_section_nr = mem->start_phys_index; - - if (!present_section_nr(phys_section_nr)) - goto out; if (!strncmp(buf, "online", min((int)count, 6))) ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE); else if(!strncmp(buf, "offline", min((int)count, 7))) ret = memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE); -out: + if (ret) return ret; return count; @@ -458,12 +468,13 @@ struct memory_block *find_memory_block(s struct sys_device *sysdev; struct memory_block *mem; char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1]; + int block_id = base_memory_block_id(__section_nr(section)); /* * 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)); + sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, block_id); kobj = kset_find_obj(&memory_sysdev_class.kset, name); if (!kobj) @@ -475,24 +486,26 @@ struct memory_block *find_memory_block(s return mem; } -static int add_memory_block(int nid, struct mem_section *section, - unsigned long state, enum mem_add_context context) +static int init_memory_block(struct memory_block **memory, + struct mem_section *section, unsigned long state) { - struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL); + struct memory_block *mem; unsigned long start_pfn; int ret = 0; + mem = kzalloc(sizeof(*mem), GFP_KERNEL); if (!mem) return -ENOMEM; - mem->start_phys_index = __section_nr(section); + mem->start_phys_index = base_memory_block_id(__section_nr(section)); + mem->end_phys_index = mem->start_phys_index + sections_per_block - 1; mem->state = state; atomic_inc(&mem->section_count); mutex_init(&mem->state_mutex); start_pfn = section_nr_to_pfn(mem->start_phys_index); mem->phys_device = arch_get_memory_phys_device(start_pfn); - ret = register_memory(mem, section); + ret = register_memory(mem); if (!ret) ret = mem_create_simple_file(mem, phys_index); if (!ret) @@ -503,8 +516,27 @@ static int add_memory_block(int nid, str ret = mem_create_simple_file(mem, phys_device); if (!ret) ret = mem_create_simple_file(mem, removable); + + *memory = mem; + return ret; +} + +static int add_memory_section(int nid, struct mem_section *section, + unsigned long state, enum mem_add_context context) +{ + struct memory_block *mem; + int ret = 0; + + mem = find_memory_block(section); + if (mem) { + atomic_inc(&mem->section_count); + kobject_put(&mem->sysdev.kobj); + } else + ret = init_memory_block(&mem, section, state); + if (!ret) { - if (context == HOTPLUG) + if (context == HOTPLUG && + atomic_read(&mem->section_count) == sections_per_block) ret = register_mem_sect_under_node(mem, nid); } @@ -525,8 +557,9 @@ int remove_memory_block(unsigned long no mem_remove_simple_file(mem, state); mem_remove_simple_file(mem, phys_device); mem_remove_simple_file(mem, removable); - unregister_memory(mem, section); - } + unregister_memory(mem); + } else + kobject_put(&mem->sysdev.kobj); return 0; } @@ -537,7 +570,7 @@ int remove_memory_block(unsigned long no */ int register_new_memory(int nid, struct mem_section *section) { - return add_memory_block(nid, section, MEM_OFFLINE, HOTPLUG); + return add_memory_section(nid, section, MEM_OFFLINE, HOTPLUG); } int unregister_memory_section(struct mem_section *section) @@ -548,6 +581,24 @@ int unregister_memory_section(struct mem return remove_memory_block(0, section, 0); } +u32 __weak memory_block_size_bytes(void) +{ + return MIN_MEMORY_BLOCK_SIZE; +} + +static u32 get_memory_block_size(void) +{ + u32 block_sz; + + block_sz = memory_block_size_bytes(); + + /* Validate blk_sz is a power of 2 and not less than section size */ + if ((block_sz & (block_sz - 1)) || (block_sz < MIN_MEMORY_BLOCK_SIZE)) + block_sz = MIN_MEMORY_BLOCK_SIZE; + + return block_sz; +} + /* * Initialize the sysfs support for memory devices... */ @@ -556,12 +607,16 @@ int __init memory_dev_init(void) unsigned int i; int ret; int err; + int block_sz; memory_sysdev_class.kset.uevent_ops = &memory_uevent_ops; ret = sysdev_class_register(&memory_sysdev_class); if (ret) goto out; + block_sz = get_memory_block_size(); + sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE; + /* * Create entries for memory sections that were found * during boot and have been initialized @@ -569,8 +624,8 @@ int __init memory_dev_init(void) for (i = 0; i < NR_MEM_SECTIONS; i++) { if (!present_section_nr(i)) continue; - err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE, - BOOT); + err = add_memory_section(0, __nr_to_section(i), MEM_ONLINE, + BOOT); if (!ret) ret = err; } ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 4/8] v3 Allow memory_block to span multiple memory sections 2010-07-20 3:55 ` Nathan Fontenot (?) @ 2010-07-20 19:18 ` Dave Hansen -1 siblings, 0 replies; 90+ messages in thread From: Dave Hansen @ 2010-07-20 19:18 UTC (permalink / raw) To: Nathan Fontenot Cc: linux-mm, greg, linux-kernel, KAMEZAWA Hiroyuki, linuxppc-dev On Mon, 2010-07-19 at 22:55 -0500, Nathan Fontenot wrote: > +static int add_memory_section(int nid, struct mem_section *section, > + unsigned long state, enum mem_add_context context) > +{ > + struct memory_block *mem; > + int ret = 0; > + > + mem = find_memory_block(section); > + if (mem) { > + atomic_inc(&mem->section_count); > + kobject_put(&mem->sysdev.kobj); > + } else > + ret = init_memory_block(&mem, section, state); > + > if (!ret) { > - if (context == HOTPLUG) > + if (context == HOTPLUG && > + atomic_read(&mem->section_count) == sections_per_block) > ret = register_mem_sect_under_node(mem, nid); > } I think the atomic_inc() can race with the atomic_dec_and_test() in remove_memory_block(). Thread 1 does: mem = find_memory_block(section); Thread 2 does atomic_dec_and_test(&mem->section_count); and destroys the memory block, Thread 1 runs again: if (mem) { atomic_inc(&mem->section_count); kobject_put(&mem->sysdev.kobj); } else but now mem got destroyed by Thread 2. You probably need to change find_memory_block() to itself take a reference, and to use atomic_inc_unless(). -- Dave ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 4/8] v3 Allow memory_block to span multiple memory sections @ 2010-07-20 19:18 ` Dave Hansen 0 siblings, 0 replies; 90+ messages in thread From: Dave Hansen @ 2010-07-20 19:18 UTC (permalink / raw) To: Nathan Fontenot Cc: linux-kernel, linux-mm, linuxppc-dev, KAMEZAWA Hiroyuki, greg On Mon, 2010-07-19 at 22:55 -0500, Nathan Fontenot wrote: > +static int add_memory_section(int nid, struct mem_section *section, > + unsigned long state, enum mem_add_context context) > +{ > + struct memory_block *mem; > + int ret = 0; > + > + mem = find_memory_block(section); > + if (mem) { > + atomic_inc(&mem->section_count); > + kobject_put(&mem->sysdev.kobj); > + } else > + ret = init_memory_block(&mem, section, state); > + > if (!ret) { > - if (context == HOTPLUG) > + if (context == HOTPLUG && > + atomic_read(&mem->section_count) == sections_per_block) > ret = register_mem_sect_under_node(mem, nid); > } I think the atomic_inc() can race with the atomic_dec_and_test() in remove_memory_block(). Thread 1 does: mem = find_memory_block(section); Thread 2 does atomic_dec_and_test(&mem->section_count); and destroys the memory block, Thread 1 runs again: if (mem) { atomic_inc(&mem->section_count); kobject_put(&mem->sysdev.kobj); } else but now mem got destroyed by Thread 2. You probably need to change find_memory_block() to itself take a reference, and to use atomic_inc_unless(). -- Dave -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 4/8] v3 Allow memory_block to span multiple memory sections @ 2010-07-20 19:18 ` Dave Hansen 0 siblings, 0 replies; 90+ messages in thread From: Dave Hansen @ 2010-07-20 19:18 UTC (permalink / raw) To: Nathan Fontenot Cc: linux-kernel, linux-mm, linuxppc-dev, KAMEZAWA Hiroyuki, greg On Mon, 2010-07-19 at 22:55 -0500, Nathan Fontenot wrote: > +static int add_memory_section(int nid, struct mem_section *section, > + unsigned long state, enum mem_add_context context) > +{ > + struct memory_block *mem; > + int ret = 0; > + > + mem = find_memory_block(section); > + if (mem) { > + atomic_inc(&mem->section_count); > + kobject_put(&mem->sysdev.kobj); > + } else > + ret = init_memory_block(&mem, section, state); > + > if (!ret) { > - if (context == HOTPLUG) > + if (context == HOTPLUG && > + atomic_read(&mem->section_count) == sections_per_block) > ret = register_mem_sect_under_node(mem, nid); > } I think the atomic_inc() can race with the atomic_dec_and_test() in remove_memory_block(). Thread 1 does: mem = find_memory_block(section); Thread 2 does atomic_dec_and_test(&mem->section_count); and destroys the memory block, Thread 1 runs again: if (mem) { atomic_inc(&mem->section_count); kobject_put(&mem->sysdev.kobj); } else but now mem got destroyed by Thread 2. You probably need to change find_memory_block() to itself take a reference, and to use atomic_inc_unless(). -- Dave ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 4/8] v3 Allow memory_block to span multiple memory sections 2010-07-20 19:18 ` Dave Hansen (?) @ 2010-07-24 3:09 ` Nathan Fontenot -1 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-24 3:09 UTC (permalink / raw) To: Dave Hansen; +Cc: linux-mm, greg, linux-kernel, KAMEZAWA Hiroyuki, linuxppc-dev On 07/20/2010 02:18 PM, Dave Hansen wrote: > On Mon, 2010-07-19 at 22:55 -0500, Nathan Fontenot wrote: >> +static int add_memory_section(int nid, struct mem_section *section, >> + unsigned long state, enum mem_add_context context) >> +{ >> + struct memory_block *mem; >> + int ret = 0; >> + >> + mem = find_memory_block(section); >> + if (mem) { >> + atomic_inc(&mem->section_count); >> + kobject_put(&mem->sysdev.kobj); >> + } else >> + ret = init_memory_block(&mem, section, state); >> + >> if (!ret) { >> - if (context == HOTPLUG) >> + if (context == HOTPLUG && >> + atomic_read(&mem->section_count) == sections_per_block) >> ret = register_mem_sect_under_node(mem, nid); >> } > > I think the atomic_inc() can race with the atomic_dec_and_test() in > remove_memory_block(). > > Thread 1 does: > > mem = find_memory_block(section); > > Thread 2 does > > atomic_dec_and_test(&mem->section_count); > > and destroys the memory block, Thread 1 runs again: > > if (mem) { > atomic_inc(&mem->section_count); > kobject_put(&mem->sysdev.kobj); > } else > > but now mem got destroyed by Thread 2. You probably need to change > find_memory_block() to itself take a reference, and to use > atomic_inc_unless(). > You're right but I think the fix you suggested will narrow the window for the race condition, not eliminate it. We could still take a time splice in find_memory_block prior to the container_of() calls to get the memory block pointer and end up de-referencing a invalid kobject o sysdev pointer. I think if we want to eliminate this we may need to have lock that protects access to any of the memory_block structures. This would need to be taken any time find_memory_block is called and released when use of the memory_block returned is finished. If we're going to fix this we should eliminate the window completely instead of just closing it further. If we add a lock should I submit it as part of this patchset? or submit it as a follow-on? -Nathan ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 4/8] v3 Allow memory_block to span multiple memory sections @ 2010-07-24 3:09 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-24 3:09 UTC (permalink / raw) To: Dave Hansen; +Cc: linux-kernel, linux-mm, linuxppc-dev, KAMEZAWA Hiroyuki, greg On 07/20/2010 02:18 PM, Dave Hansen wrote: > On Mon, 2010-07-19 at 22:55 -0500, Nathan Fontenot wrote: >> +static int add_memory_section(int nid, struct mem_section *section, >> + unsigned long state, enum mem_add_context context) >> +{ >> + struct memory_block *mem; >> + int ret = 0; >> + >> + mem = find_memory_block(section); >> + if (mem) { >> + atomic_inc(&mem->section_count); >> + kobject_put(&mem->sysdev.kobj); >> + } else >> + ret = init_memory_block(&mem, section, state); >> + >> if (!ret) { >> - if (context == HOTPLUG) >> + if (context == HOTPLUG && >> + atomic_read(&mem->section_count) == sections_per_block) >> ret = register_mem_sect_under_node(mem, nid); >> } > > I think the atomic_inc() can race with the atomic_dec_and_test() in > remove_memory_block(). > > Thread 1 does: > > mem = find_memory_block(section); > > Thread 2 does > > atomic_dec_and_test(&mem->section_count); > > and destroys the memory block, Thread 1 runs again: > > if (mem) { > atomic_inc(&mem->section_count); > kobject_put(&mem->sysdev.kobj); > } else > > but now mem got destroyed by Thread 2. You probably need to change > find_memory_block() to itself take a reference, and to use > atomic_inc_unless(). > You're right but I think the fix you suggested will narrow the window for the race condition, not eliminate it. We could still take a time splice in find_memory_block prior to the container_of() calls to get the memory block pointer and end up de-referencing a invalid kobject o sysdev pointer. I think if we want to eliminate this we may need to have lock that protects access to any of the memory_block structures. This would need to be taken any time find_memory_block is called and released when use of the memory_block returned is finished. If we're going to fix this we should eliminate the window completely instead of just closing it further. If we add a lock should I submit it as part of this patchset? or submit it as a follow-on? -Nathan -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 4/8] v3 Allow memory_block to span multiple memory sections @ 2010-07-24 3:09 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-24 3:09 UTC (permalink / raw) To: Dave Hansen; +Cc: linux-kernel, linux-mm, linuxppc-dev, KAMEZAWA Hiroyuki, greg On 07/20/2010 02:18 PM, Dave Hansen wrote: > On Mon, 2010-07-19 at 22:55 -0500, Nathan Fontenot wrote: >> +static int add_memory_section(int nid, struct mem_section *section, >> + unsigned long state, enum mem_add_context context) >> +{ >> + struct memory_block *mem; >> + int ret = 0; >> + >> + mem = find_memory_block(section); >> + if (mem) { >> + atomic_inc(&mem->section_count); >> + kobject_put(&mem->sysdev.kobj); >> + } else >> + ret = init_memory_block(&mem, section, state); >> + >> if (!ret) { >> - if (context == HOTPLUG) >> + if (context == HOTPLUG && >> + atomic_read(&mem->section_count) == sections_per_block) >> ret = register_mem_sect_under_node(mem, nid); >> } > > I think the atomic_inc() can race with the atomic_dec_and_test() in > remove_memory_block(). > > Thread 1 does: > > mem = find_memory_block(section); > > Thread 2 does > > atomic_dec_and_test(&mem->section_count); > > and destroys the memory block, Thread 1 runs again: > > if (mem) { > atomic_inc(&mem->section_count); > kobject_put(&mem->sysdev.kobj); > } else > > but now mem got destroyed by Thread 2. You probably need to change > find_memory_block() to itself take a reference, and to use > atomic_inc_unless(). > You're right but I think the fix you suggested will narrow the window for the race condition, not eliminate it. We could still take a time splice in find_memory_block prior to the container_of() calls to get the memory block pointer and end up de-referencing a invalid kobject o sysdev pointer. I think if we want to eliminate this we may need to have lock that protects access to any of the memory_block structures. This would need to be taken any time find_memory_block is called and released when use of the memory_block returned is finished. If we're going to fix this we should eliminate the window completely instead of just closing it further. If we add a lock should I submit it as part of this patchset? or submit it as a follow-on? -Nathan ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 4/8] v3 Allow memory_block to span multiple memory sections 2010-07-24 3:09 ` Nathan Fontenot (?) @ 2010-07-27 2:36 ` Dave Hansen -1 siblings, 0 replies; 90+ messages in thread From: Dave Hansen @ 2010-07-27 2:36 UTC (permalink / raw) To: Nathan Fontenot Cc: linux-mm, greg, linux-kernel, KAMEZAWA Hiroyuki, linuxppc-dev On Fri, 2010-07-23 at 22:09 -0500, Nathan Fontenot wrote: > If we add a lock should I submit it as part of this patchset? or > submit it > as a follow-on? It should probably be at the beginning of the patch set. We don't want to have a case where your set introduces races that we _need_ a later patch to fix. -- Dave ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 4/8] v3 Allow memory_block to span multiple memory sections @ 2010-07-27 2:36 ` Dave Hansen 0 siblings, 0 replies; 90+ messages in thread From: Dave Hansen @ 2010-07-27 2:36 UTC (permalink / raw) To: Nathan Fontenot Cc: linux-kernel, linux-mm, linuxppc-dev, KAMEZAWA Hiroyuki, greg On Fri, 2010-07-23 at 22:09 -0500, Nathan Fontenot wrote: > If we add a lock should I submit it as part of this patchset? or > submit it > as a follow-on? It should probably be at the beginning of the patch set. We don't want to have a case where your set introduces races that we _need_ a later patch to fix. -- Dave -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 4/8] v3 Allow memory_block to span multiple memory sections @ 2010-07-27 2:36 ` Dave Hansen 0 siblings, 0 replies; 90+ messages in thread From: Dave Hansen @ 2010-07-27 2:36 UTC (permalink / raw) To: Nathan Fontenot Cc: linux-kernel, linux-mm, linuxppc-dev, KAMEZAWA Hiroyuki, greg On Fri, 2010-07-23 at 22:09 -0500, Nathan Fontenot wrote: > If we add a lock should I submit it as part of this patchset? or > submit it > as a follow-on? It should probably be at the beginning of the patch set. We don't want to have a case where your set introduces races that we _need_ a later patch to fix. -- Dave ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 4/8] v3 Allow memory_block to span multiple memory sections 2010-07-20 19:18 ` Dave Hansen (?) @ 2010-07-26 19:10 ` Nathan Fontenot -1 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-26 19:10 UTC (permalink / raw) To: Dave Hansen; +Cc: linux-mm, greg, linux-kernel, KAMEZAWA Hiroyuki, linuxppc-dev On 07/20/2010 02:18 PM, Dave Hansen wrote: > On Mon, 2010-07-19 at 22:55 -0500, Nathan Fontenot wrote: >> +static int add_memory_section(int nid, struct mem_section *section, >> + unsigned long state, enum mem_add_context context) >> +{ >> + struct memory_block *mem; >> + int ret = 0; >> + >> + mem = find_memory_block(section); >> + if (mem) { >> + atomic_inc(&mem->section_count); >> + kobject_put(&mem->sysdev.kobj); >> + } else >> + ret = init_memory_block(&mem, section, state); >> + >> if (!ret) { >> - if (context == HOTPLUG) >> + if (context == HOTPLUG && >> + atomic_read(&mem->section_count) == sections_per_block) >> ret = register_mem_sect_under_node(mem, nid); >> } > > I think the atomic_inc() can race with the atomic_dec_and_test() in > remove_memory_block(). > > Thread 1 does: > > mem = find_memory_block(section); > > Thread 2 does > > atomic_dec_and_test(&mem->section_count); > > and destroys the memory block, Thread 1 runs again: > > if (mem) { > atomic_inc(&mem->section_count); > kobject_put(&mem->sysdev.kobj); > } else > > but now mem got destroyed by Thread 2. You probably need to change > find_memory_block() to itself take a reference, and to use > atomic_inc_unless(). > I'm not sure I like that for a couple of reasons. I think there may still be a path through the find_memory_block() code that this race condition can occur. We could take a time sslice after the kobject_get and before getting the memory_block pointer. The second reason is that the node sysfs code calls find_memory_block() and it may be a bit kludgy to have callers of find_memory_block have to reduce the section_count after using it. With the way the memory_block structs are kept, retrieved via a kobject_get() call instead maintained on a local list, there may not be a solution that is foolproof without changing this. -Nathan > -- Dave > ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 4/8] v3 Allow memory_block to span multiple memory sections @ 2010-07-26 19:10 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-26 19:10 UTC (permalink / raw) To: Dave Hansen; +Cc: linux-kernel, linux-mm, linuxppc-dev, KAMEZAWA Hiroyuki, greg On 07/20/2010 02:18 PM, Dave Hansen wrote: > On Mon, 2010-07-19 at 22:55 -0500, Nathan Fontenot wrote: >> +static int add_memory_section(int nid, struct mem_section *section, >> + unsigned long state, enum mem_add_context context) >> +{ >> + struct memory_block *mem; >> + int ret = 0; >> + >> + mem = find_memory_block(section); >> + if (mem) { >> + atomic_inc(&mem->section_count); >> + kobject_put(&mem->sysdev.kobj); >> + } else >> + ret = init_memory_block(&mem, section, state); >> + >> if (!ret) { >> - if (context == HOTPLUG) >> + if (context == HOTPLUG && >> + atomic_read(&mem->section_count) == sections_per_block) >> ret = register_mem_sect_under_node(mem, nid); >> } > > I think the atomic_inc() can race with the atomic_dec_and_test() in > remove_memory_block(). > > Thread 1 does: > > mem = find_memory_block(section); > > Thread 2 does > > atomic_dec_and_test(&mem->section_count); > > and destroys the memory block, Thread 1 runs again: > > if (mem) { > atomic_inc(&mem->section_count); > kobject_put(&mem->sysdev.kobj); > } else > > but now mem got destroyed by Thread 2. You probably need to change > find_memory_block() to itself take a reference, and to use > atomic_inc_unless(). > I'm not sure I like that for a couple of reasons. I think there may still be a path through the find_memory_block() code that this race condition can occur. We could take a time sslice after the kobject_get and before getting the memory_block pointer. The second reason is that the node sysfs code calls find_memory_block() and it may be a bit kludgy to have callers of find_memory_block have to reduce the section_count after using it. With the way the memory_block structs are kept, retrieved via a kobject_get() call instead maintained on a local list, there may not be a solution that is foolproof without changing this. -Nathan > -- Dave > -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 4/8] v3 Allow memory_block to span multiple memory sections @ 2010-07-26 19:10 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-26 19:10 UTC (permalink / raw) To: Dave Hansen; +Cc: linux-kernel, linux-mm, linuxppc-dev, KAMEZAWA Hiroyuki, greg On 07/20/2010 02:18 PM, Dave Hansen wrote: > On Mon, 2010-07-19 at 22:55 -0500, Nathan Fontenot wrote: >> +static int add_memory_section(int nid, struct mem_section *section, >> + unsigned long state, enum mem_add_context context) >> +{ >> + struct memory_block *mem; >> + int ret = 0; >> + >> + mem = find_memory_block(section); >> + if (mem) { >> + atomic_inc(&mem->section_count); >> + kobject_put(&mem->sysdev.kobj); >> + } else >> + ret = init_memory_block(&mem, section, state); >> + >> if (!ret) { >> - if (context == HOTPLUG) >> + if (context == HOTPLUG && >> + atomic_read(&mem->section_count) == sections_per_block) >> ret = register_mem_sect_under_node(mem, nid); >> } > > I think the atomic_inc() can race with the atomic_dec_and_test() in > remove_memory_block(). > > Thread 1 does: > > mem = find_memory_block(section); > > Thread 2 does > > atomic_dec_and_test(&mem->section_count); > > and destroys the memory block, Thread 1 runs again: > > if (mem) { > atomic_inc(&mem->section_count); > kobject_put(&mem->sysdev.kobj); > } else > > but now mem got destroyed by Thread 2. You probably need to change > find_memory_block() to itself take a reference, and to use > atomic_inc_unless(). > I'm not sure I like that for a couple of reasons. I think there may still be a path through the find_memory_block() code that this race condition can occur. We could take a time sslice after the kobject_get and before getting the memory_block pointer. The second reason is that the node sysfs code calls find_memory_block() and it may be a bit kludgy to have callers of find_memory_block have to reduce the section_count after using it. With the way the memory_block structs are kept, retrieved via a kobject_get() call instead maintained on a local list, there may not be a solution that is foolproof without changing this. -Nathan > -- Dave > ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 4/8] v3 Allow memory_block to span multiple memory sections 2010-07-20 3:55 ` Nathan Fontenot (?) @ 2010-07-20 19:21 ` Dave Hansen -1 siblings, 0 replies; 90+ messages in thread From: Dave Hansen @ 2010-07-20 19:21 UTC (permalink / raw) To: Nathan Fontenot Cc: linux-mm, greg, linux-kernel, KAMEZAWA Hiroyuki, linuxppc-dev On Mon, 2010-07-19 at 22:55 -0500, Nathan Fontenot wrote: > +static u32 get_memory_block_size(void) > +{ > + u32 block_sz; > + > + block_sz = memory_block_size_bytes(); > + > + /* Validate blk_sz is a power of 2 and not less than section size */ > + if ((block_sz & (block_sz - 1)) || (block_sz < MIN_MEMORY_BLOCK_SIZE)) > + block_sz = MIN_MEMORY_BLOCK_SIZE; Is this worth a WARN_ON()? Seems pretty bogus if someone is returning funky block sizes. -- Dave ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 4/8] v3 Allow memory_block to span multiple memory sections @ 2010-07-20 19:21 ` Dave Hansen 0 siblings, 0 replies; 90+ messages in thread From: Dave Hansen @ 2010-07-20 19:21 UTC (permalink / raw) To: Nathan Fontenot Cc: linux-kernel, linux-mm, linuxppc-dev, KAMEZAWA Hiroyuki, greg On Mon, 2010-07-19 at 22:55 -0500, Nathan Fontenot wrote: > +static u32 get_memory_block_size(void) > +{ > + u32 block_sz; > + > + block_sz = memory_block_size_bytes(); > + > + /* Validate blk_sz is a power of 2 and not less than section size */ > + if ((block_sz & (block_sz - 1)) || (block_sz < MIN_MEMORY_BLOCK_SIZE)) > + block_sz = MIN_MEMORY_BLOCK_SIZE; Is this worth a WARN_ON()? Seems pretty bogus if someone is returning funky block sizes. -- Dave -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 4/8] v3 Allow memory_block to span multiple memory sections @ 2010-07-20 19:21 ` Dave Hansen 0 siblings, 0 replies; 90+ messages in thread From: Dave Hansen @ 2010-07-20 19:21 UTC (permalink / raw) To: Nathan Fontenot Cc: linux-kernel, linux-mm, linuxppc-dev, KAMEZAWA Hiroyuki, greg On Mon, 2010-07-19 at 22:55 -0500, Nathan Fontenot wrote: > +static u32 get_memory_block_size(void) > +{ > + u32 block_sz; > + > + block_sz = memory_block_size_bytes(); > + > + /* Validate blk_sz is a power of 2 and not less than section size */ > + if ((block_sz & (block_sz - 1)) || (block_sz < MIN_MEMORY_BLOCK_SIZE)) > + block_sz = MIN_MEMORY_BLOCK_SIZE; Is this worth a WARN_ON()? Seems pretty bogus if someone is returning funky block sizes. -- Dave ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 5/8] v3 Update the find_memory_block declaration 2010-07-20 3:45 ` Nathan Fontenot (?) @ 2010-07-20 3:56 ` Nathan Fontenot -1 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:56 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: greg, KAMEZAWA Hiroyuki Update the find_memory_block declaration to to take a struct mem_section * so that it matches the definition. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> --- include/linux/memory.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Index: linux-2.6/include/linux/memory.h =================================================================== --- linux-2.6.orig/include/linux/memory.h 2010-07-19 21:10:28.000000000 -0500 +++ linux-2.6/include/linux/memory.h 2010-07-19 21:12:46.000000000 -0500 @@ -116,7 +116,7 @@ extern int memory_dev_init(void); extern int remove_memory_block(unsigned long, struct mem_section *, int); extern int memory_notify(unsigned long val, void *v); extern int memory_isolate_notify(unsigned long val, void *v); -extern struct memory_block *find_memory_block(unsigned long); +extern struct memory_block *find_memory_block(struct mem_section *); extern int memory_is_hidden(struct mem_section *); #define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT) enum mem_add_context { BOOT, HOTPLUG }; ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 5/8] v3 Update the find_memory_block declaration @ 2010-07-20 3:56 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:56 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: KAMEZAWA Hiroyuki, greg Update the find_memory_block declaration to to take a struct mem_section * so that it matches the definition. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> --- include/linux/memory.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Index: linux-2.6/include/linux/memory.h =================================================================== --- linux-2.6.orig/include/linux/memory.h 2010-07-19 21:10:28.000000000 -0500 +++ linux-2.6/include/linux/memory.h 2010-07-19 21:12:46.000000000 -0500 @@ -116,7 +116,7 @@ extern int memory_dev_init(void); extern int remove_memory_block(unsigned long, struct mem_section *, int); extern int memory_notify(unsigned long val, void *v); extern int memory_isolate_notify(unsigned long val, void *v); -extern struct memory_block *find_memory_block(unsigned long); +extern struct memory_block *find_memory_block(struct mem_section *); extern int memory_is_hidden(struct mem_section *); #define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT) enum mem_add_context { BOOT, HOTPLUG }; -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 5/8] v3 Update the find_memory_block declaration @ 2010-07-20 3:56 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:56 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: KAMEZAWA Hiroyuki, greg Update the find_memory_block declaration to to take a struct mem_section * so that it matches the definition. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> --- include/linux/memory.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Index: linux-2.6/include/linux/memory.h =================================================================== --- linux-2.6.orig/include/linux/memory.h 2010-07-19 21:10:28.000000000 -0500 +++ linux-2.6/include/linux/memory.h 2010-07-19 21:12:46.000000000 -0500 @@ -116,7 +116,7 @@ extern int memory_dev_init(void); extern int remove_memory_block(unsigned long, struct mem_section *, int); extern int memory_notify(unsigned long val, void *v); extern int memory_isolate_notify(unsigned long val, void *v); -extern struct memory_block *find_memory_block(unsigned long); +extern struct memory_block *find_memory_block(struct mem_section *); extern int memory_is_hidden(struct mem_section *); #define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT) enum mem_add_context { BOOT, HOTPLUG }; ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 5/8] v3 Update the find_memory_block declaration 2010-07-20 3:56 ` Nathan Fontenot (?) @ 2010-07-20 7:16 ` KAMEZAWA Hiroyuki -1 siblings, 0 replies; 90+ messages in thread From: KAMEZAWA Hiroyuki @ 2010-07-20 7:16 UTC (permalink / raw) To: Nathan Fontenot; +Cc: linux-mm, greg, linux-kernel, linuxppc-dev On Mon, 19 Jul 2010 22:56:16 -0500 Nathan Fontenot <nfont@austin.ibm.com> wrote: > Update the find_memory_block declaration to to take a struct mem_section * > so that it matches the definition. > > Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> Reviewd-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 5/8] v3 Update the find_memory_block declaration @ 2010-07-20 7:16 ` KAMEZAWA Hiroyuki 0 siblings, 0 replies; 90+ messages in thread From: KAMEZAWA Hiroyuki @ 2010-07-20 7:16 UTC (permalink / raw) To: Nathan Fontenot; +Cc: linux-kernel, linux-mm, linuxppc-dev, greg On Mon, 19 Jul 2010 22:56:16 -0500 Nathan Fontenot <nfont@austin.ibm.com> wrote: > Update the find_memory_block declaration to to take a struct mem_section * > so that it matches the definition. > > Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> Reviewd-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 5/8] v3 Update the find_memory_block declaration @ 2010-07-20 7:16 ` KAMEZAWA Hiroyuki 0 siblings, 0 replies; 90+ messages in thread From: KAMEZAWA Hiroyuki @ 2010-07-20 7:16 UTC (permalink / raw) To: Nathan Fontenot; +Cc: linux-kernel, linux-mm, linuxppc-dev, greg On Mon, 19 Jul 2010 22:56:16 -0500 Nathan Fontenot <nfont@austin.ibm.com> wrote: > Update the find_memory_block declaration to to take a struct mem_section * > so that it matches the definition. > > Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> Reviewd-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 6/8] v3 Update the node sysfs code 2010-07-20 3:45 ` Nathan Fontenot (?) @ 2010-07-20 3:57 ` Nathan Fontenot -1 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:57 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: greg, KAMEZAWA Hiroyuki Update the node sysfs code to be aware of the new capability for a memory block to contain multiple memory sections. This requires an additional parameter to unregister_mem_sect_under_nodes so that we know which memory section of the memory block to unregister. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> --- drivers/base/memory.c | 2 +- drivers/base/node.c | 12 ++++++++---- include/linux/node.h | 3 ++- 3 files changed, 11 insertions(+), 6 deletions(-) Index: linux-2.6/drivers/base/node.c =================================================================== --- linux-2.6.orig/drivers/base/node.c 2010-07-19 21:10:25.000000000 -0500 +++ linux-2.6/drivers/base/node.c 2010-07-19 21:13:11.000000000 -0500 @@ -346,8 +346,10 @@ int register_mem_sect_under_node(struct return -EFAULT; if (!node_online(nid)) return 0; - sect_start_pfn = section_nr_to_pfn(mem_blk->phys_index); - sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1; + + sect_start_pfn = section_nr_to_pfn(mem_blk->start_phys_index); + sect_end_pfn = section_nr_to_pfn(mem_blk->end_phys_index); + sect_end_pfn += PAGES_PER_SECTION - 1; for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) { int page_nid; @@ -371,7 +373,8 @@ int register_mem_sect_under_node(struct } /* unregister memory section under all nodes that it spans */ -int unregister_mem_sect_under_nodes(struct memory_block *mem_blk) +int unregister_mem_sect_under_nodes(struct memory_block *mem_blk, + unsigned long phys_index) { NODEMASK_ALLOC(nodemask_t, unlinked_nodes, GFP_KERNEL); unsigned long pfn, sect_start_pfn, sect_end_pfn; @@ -383,7 +386,8 @@ int unregister_mem_sect_under_nodes(stru if (!unlinked_nodes) return -ENOMEM; nodes_clear(*unlinked_nodes); - sect_start_pfn = section_nr_to_pfn(mem_blk->phys_index); + + sect_start_pfn = section_nr_to_pfn(phys_index); sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1; for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) { int nid; Index: linux-2.6/drivers/base/memory.c =================================================================== --- linux-2.6.orig/drivers/base/memory.c 2010-07-19 21:12:22.000000000 -0500 +++ linux-2.6/drivers/base/memory.c 2010-07-19 21:13:11.000000000 -0500 @@ -550,9 +550,9 @@ int remove_memory_block(unsigned long no mem = find_memory_block(section); atomic_dec(&mem->section_count); + unregister_mem_sect_under_nodes(mem, __section_nr(section)); if (atomic_read(&mem->section_count) == 0) { - unregister_mem_sect_under_nodes(mem); mem_remove_simple_file(mem, start_phys_index); mem_remove_simple_file(mem, end_phys_index); mem_remove_simple_file(mem, state); Index: linux-2.6/include/linux/node.h =================================================================== --- linux-2.6.orig/include/linux/node.h 2010-07-19 21:10:25.000000000 -0500 +++ linux-2.6/include/linux/node.h 2010-07-19 21:13:11.000000000 -0500 @@ -44,7 +44,8 @@ extern int register_cpu_under_node(unsig extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid); extern int register_mem_sect_under_node(struct memory_block *mem_blk, int nid); -extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk); +extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk, + unsigned long phys_index); #ifdef CONFIG_HUGETLBFS extern void register_hugetlbfs_with_node(node_registration_func_t doregister, ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 6/8] v3 Update the node sysfs code @ 2010-07-20 3:57 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:57 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: KAMEZAWA Hiroyuki, greg Update the node sysfs code to be aware of the new capability for a memory block to contain multiple memory sections. This requires an additional parameter to unregister_mem_sect_under_nodes so that we know which memory section of the memory block to unregister. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> --- drivers/base/memory.c | 2 +- drivers/base/node.c | 12 ++++++++---- include/linux/node.h | 3 ++- 3 files changed, 11 insertions(+), 6 deletions(-) Index: linux-2.6/drivers/base/node.c =================================================================== --- linux-2.6.orig/drivers/base/node.c 2010-07-19 21:10:25.000000000 -0500 +++ linux-2.6/drivers/base/node.c 2010-07-19 21:13:11.000000000 -0500 @@ -346,8 +346,10 @@ int register_mem_sect_under_node(struct return -EFAULT; if (!node_online(nid)) return 0; - sect_start_pfn = section_nr_to_pfn(mem_blk->phys_index); - sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1; + + sect_start_pfn = section_nr_to_pfn(mem_blk->start_phys_index); + sect_end_pfn = section_nr_to_pfn(mem_blk->end_phys_index); + sect_end_pfn += PAGES_PER_SECTION - 1; for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) { int page_nid; @@ -371,7 +373,8 @@ int register_mem_sect_under_node(struct } /* unregister memory section under all nodes that it spans */ -int unregister_mem_sect_under_nodes(struct memory_block *mem_blk) +int unregister_mem_sect_under_nodes(struct memory_block *mem_blk, + unsigned long phys_index) { NODEMASK_ALLOC(nodemask_t, unlinked_nodes, GFP_KERNEL); unsigned long pfn, sect_start_pfn, sect_end_pfn; @@ -383,7 +386,8 @@ int unregister_mem_sect_under_nodes(stru if (!unlinked_nodes) return -ENOMEM; nodes_clear(*unlinked_nodes); - sect_start_pfn = section_nr_to_pfn(mem_blk->phys_index); + + sect_start_pfn = section_nr_to_pfn(phys_index); sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1; for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) { int nid; Index: linux-2.6/drivers/base/memory.c =================================================================== --- linux-2.6.orig/drivers/base/memory.c 2010-07-19 21:12:22.000000000 -0500 +++ linux-2.6/drivers/base/memory.c 2010-07-19 21:13:11.000000000 -0500 @@ -550,9 +550,9 @@ int remove_memory_block(unsigned long no mem = find_memory_block(section); atomic_dec(&mem->section_count); + unregister_mem_sect_under_nodes(mem, __section_nr(section)); if (atomic_read(&mem->section_count) == 0) { - unregister_mem_sect_under_nodes(mem); mem_remove_simple_file(mem, start_phys_index); mem_remove_simple_file(mem, end_phys_index); mem_remove_simple_file(mem, state); Index: linux-2.6/include/linux/node.h =================================================================== --- linux-2.6.orig/include/linux/node.h 2010-07-19 21:10:25.000000000 -0500 +++ linux-2.6/include/linux/node.h 2010-07-19 21:13:11.000000000 -0500 @@ -44,7 +44,8 @@ extern int register_cpu_under_node(unsig extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid); extern int register_mem_sect_under_node(struct memory_block *mem_blk, int nid); -extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk); +extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk, + unsigned long phys_index); #ifdef CONFIG_HUGETLBFS extern void register_hugetlbfs_with_node(node_registration_func_t doregister, -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 6/8] v3 Update the node sysfs code @ 2010-07-20 3:57 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:57 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: KAMEZAWA Hiroyuki, greg Update the node sysfs code to be aware of the new capability for a memory block to contain multiple memory sections. This requires an additional parameter to unregister_mem_sect_under_nodes so that we know which memory section of the memory block to unregister. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> --- drivers/base/memory.c | 2 +- drivers/base/node.c | 12 ++++++++---- include/linux/node.h | 3 ++- 3 files changed, 11 insertions(+), 6 deletions(-) Index: linux-2.6/drivers/base/node.c =================================================================== --- linux-2.6.orig/drivers/base/node.c 2010-07-19 21:10:25.000000000 -0500 +++ linux-2.6/drivers/base/node.c 2010-07-19 21:13:11.000000000 -0500 @@ -346,8 +346,10 @@ int register_mem_sect_under_node(struct return -EFAULT; if (!node_online(nid)) return 0; - sect_start_pfn = section_nr_to_pfn(mem_blk->phys_index); - sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1; + + sect_start_pfn = section_nr_to_pfn(mem_blk->start_phys_index); + sect_end_pfn = section_nr_to_pfn(mem_blk->end_phys_index); + sect_end_pfn += PAGES_PER_SECTION - 1; for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) { int page_nid; @@ -371,7 +373,8 @@ int register_mem_sect_under_node(struct } /* unregister memory section under all nodes that it spans */ -int unregister_mem_sect_under_nodes(struct memory_block *mem_blk) +int unregister_mem_sect_under_nodes(struct memory_block *mem_blk, + unsigned long phys_index) { NODEMASK_ALLOC(nodemask_t, unlinked_nodes, GFP_KERNEL); unsigned long pfn, sect_start_pfn, sect_end_pfn; @@ -383,7 +386,8 @@ int unregister_mem_sect_under_nodes(stru if (!unlinked_nodes) return -ENOMEM; nodes_clear(*unlinked_nodes); - sect_start_pfn = section_nr_to_pfn(mem_blk->phys_index); + + sect_start_pfn = section_nr_to_pfn(phys_index); sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1; for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) { int nid; Index: linux-2.6/drivers/base/memory.c =================================================================== --- linux-2.6.orig/drivers/base/memory.c 2010-07-19 21:12:22.000000000 -0500 +++ linux-2.6/drivers/base/memory.c 2010-07-19 21:13:11.000000000 -0500 @@ -550,9 +550,9 @@ int remove_memory_block(unsigned long no mem = find_memory_block(section); atomic_dec(&mem->section_count); + unregister_mem_sect_under_nodes(mem, __section_nr(section)); if (atomic_read(&mem->section_count) == 0) { - unregister_mem_sect_under_nodes(mem); mem_remove_simple_file(mem, start_phys_index); mem_remove_simple_file(mem, end_phys_index); mem_remove_simple_file(mem, state); Index: linux-2.6/include/linux/node.h =================================================================== --- linux-2.6.orig/include/linux/node.h 2010-07-19 21:10:25.000000000 -0500 +++ linux-2.6/include/linux/node.h 2010-07-19 21:13:11.000000000 -0500 @@ -44,7 +44,8 @@ extern int register_cpu_under_node(unsig extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid); extern int register_mem_sect_under_node(struct memory_block *mem_blk, int nid); -extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk); +extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk, + unsigned long phys_index); #ifdef CONFIG_HUGETLBFS extern void register_hugetlbfs_with_node(node_registration_func_t doregister, ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 6/8] v3 Update the node sysfs code 2010-07-20 3:57 ` Nathan Fontenot (?) @ 2010-07-20 7:17 ` KAMEZAWA Hiroyuki -1 siblings, 0 replies; 90+ messages in thread From: KAMEZAWA Hiroyuki @ 2010-07-20 7:17 UTC (permalink / raw) To: Nathan Fontenot; +Cc: linux-mm, greg, linux-kernel, linuxppc-dev On Mon, 19 Jul 2010 22:57:35 -0500 Nathan Fontenot <nfont@austin.ibm.com> wrote: > Update the node sysfs code to be aware of the new capability for a memory > block to contain multiple memory sections. This requires an additional > parameter to unregister_mem_sect_under_nodes so that we know which memory > section of the memory block to unregister. > > Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 6/8] v3 Update the node sysfs code @ 2010-07-20 7:17 ` KAMEZAWA Hiroyuki 0 siblings, 0 replies; 90+ messages in thread From: KAMEZAWA Hiroyuki @ 2010-07-20 7:17 UTC (permalink / raw) To: Nathan Fontenot; +Cc: linux-kernel, linux-mm, linuxppc-dev, greg On Mon, 19 Jul 2010 22:57:35 -0500 Nathan Fontenot <nfont@austin.ibm.com> wrote: > Update the node sysfs code to be aware of the new capability for a memory > block to contain multiple memory sections. This requires an additional > parameter to unregister_mem_sect_under_nodes so that we know which memory > section of the memory block to unregister. > > Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 6/8] v3 Update the node sysfs code @ 2010-07-20 7:17 ` KAMEZAWA Hiroyuki 0 siblings, 0 replies; 90+ messages in thread From: KAMEZAWA Hiroyuki @ 2010-07-20 7:17 UTC (permalink / raw) To: Nathan Fontenot; +Cc: linux-kernel, linux-mm, linuxppc-dev, greg On Mon, 19 Jul 2010 22:57:35 -0500 Nathan Fontenot <nfont@austin.ibm.com> wrote: > Update the node sysfs code to be aware of the new capability for a memory > block to contain multiple memory sections. This requires an additional > parameter to unregister_mem_sect_under_nodes so that we know which memory > section of the memory block to unregister. > > Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 6/8] v3 Update the node sysfs code 2010-07-20 3:57 ` Nathan Fontenot (?) @ 2010-07-28 13:50 ` Brian King -1 siblings, 0 replies; 90+ messages in thread From: Brian King @ 2010-07-28 13:50 UTC (permalink / raw) To: Nathan Fontenot Cc: linux-mm, greg, linux-kernel, KAMEZAWA Hiroyuki, linuxppc-dev On 07/19/2010 10:57 PM, Nathan Fontenot wrote: > Index: linux-2.6/include/linux/node.h > =================================================================== > --- linux-2.6.orig/include/linux/node.h 2010-07-19 21:10:25.000000000 -0500 > +++ linux-2.6/include/linux/node.h 2010-07-19 21:13:11.000000000 -0500 > @@ -44,7 +44,8 @@ extern int register_cpu_under_node(unsig > extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid); > extern int register_mem_sect_under_node(struct memory_block *mem_blk, > int nid); > -extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk); > +extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk, > + unsigned long phys_index); You also need to update the inline definition of unregister_mem_sect_under_nodes for the !CONFIG_NUMA case. -Brian -- Brian King Linux on Power Virtualization IBM Linux Technology Center ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 6/8] v3 Update the node sysfs code @ 2010-07-28 13:50 ` Brian King 0 siblings, 0 replies; 90+ messages in thread From: Brian King @ 2010-07-28 13:50 UTC (permalink / raw) To: Nathan Fontenot Cc: linux-kernel, linux-mm, linuxppc-dev, greg, KAMEZAWA Hiroyuki On 07/19/2010 10:57 PM, Nathan Fontenot wrote: > Index: linux-2.6/include/linux/node.h > =================================================================== > --- linux-2.6.orig/include/linux/node.h 2010-07-19 21:10:25.000000000 -0500 > +++ linux-2.6/include/linux/node.h 2010-07-19 21:13:11.000000000 -0500 > @@ -44,7 +44,8 @@ extern int register_cpu_under_node(unsig > extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid); > extern int register_mem_sect_under_node(struct memory_block *mem_blk, > int nid); > -extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk); > +extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk, > + unsigned long phys_index); You also need to update the inline definition of unregister_mem_sect_under_nodes for the !CONFIG_NUMA case. -Brian -- Brian King Linux on Power Virtualization IBM Linux Technology Center -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 6/8] v3 Update the node sysfs code @ 2010-07-28 13:50 ` Brian King 0 siblings, 0 replies; 90+ messages in thread From: Brian King @ 2010-07-28 13:50 UTC (permalink / raw) To: Nathan Fontenot Cc: linux-kernel, linux-mm, linuxppc-dev, greg, KAMEZAWA Hiroyuki On 07/19/2010 10:57 PM, Nathan Fontenot wrote: > Index: linux-2.6/include/linux/node.h > =================================================================== > --- linux-2.6.orig/include/linux/node.h 2010-07-19 21:10:25.000000000 -0500 > +++ linux-2.6/include/linux/node.h 2010-07-19 21:13:11.000000000 -0500 > @@ -44,7 +44,8 @@ extern int register_cpu_under_node(unsig > extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid); > extern int register_mem_sect_under_node(struct memory_block *mem_blk, > int nid); > -extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk); > +extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk, > + unsigned long phys_index); You also need to update the inline definition of unregister_mem_sect_under_nodes for the !CONFIG_NUMA case. -Brian -- Brian King Linux on Power Virtualization IBM Linux Technology Center ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 7/8] v3 Define memory_block_size_bytes() for ppc/pseries 2010-07-20 3:45 ` Nathan Fontenot (?) @ 2010-07-20 3:59 ` Nathan Fontenot -1 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:59 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: greg, KAMEZAWA Hiroyuki Define a version of memory_block_size_bytes() for powerpc/pseries such that a memory block spans an entire lmb. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> --- arch/powerpc/platforms/pseries/hotplug-memory.c | 66 +++++++++++++++++++----- 1 file changed, 53 insertions(+), 13 deletions(-) Index: linux-2.6/arch/powerpc/platforms/pseries/hotplug-memory.c =================================================================== --- linux-2.6.orig/arch/powerpc/platforms/pseries/hotplug-memory.c 2010-07-19 21:10:24.000000000 -0500 +++ linux-2.6/arch/powerpc/platforms/pseries/hotplug-memory.c 2010-07-19 21:13:32.000000000 -0500 @@ -17,6 +17,54 @@ #include <asm/pSeries_reconfig.h> #include <asm/sparsemem.h> +static u32 get_memblock_size(void) +{ + struct device_node *np; + unsigned int memblock_size = 0; + + np = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); + if (np) { + const unsigned int *size; + + size = of_get_property(np, "ibm,lmb-size", NULL); + memblock_size = size ? *size : 0; + + of_node_put(np); + } else { + unsigned int memzero_size = 0; + const unsigned int *regs; + + np = of_find_node_by_path("/memory@0"); + if (np) { + regs = of_get_property(np, "reg", NULL); + memzero_size = regs ? regs[3] : 0; + of_node_put(np); + } + + if (memzero_size) { + /* We now know the size of memory@0, use this to find + * the first memoryblock and get its size. + */ + char buf[64]; + + sprintf(buf, "/memory@%x", memzero_size); + np = of_find_node_by_path(buf); + if (np) { + regs = of_get_property(np, "reg", NULL); + memblock_size = regs ? regs[3] : 0; + of_node_put(np); + } + } + } + + return memblock_size; +} + +u32 memory_block_size_bytes(void) +{ + return get_memblock_size(); +} + static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size) { unsigned long start, start_pfn; @@ -127,30 +175,22 @@ static int pseries_add_memory(struct dev static int pseries_drconf_memory(unsigned long *base, unsigned int action) { - struct device_node *np; - const unsigned long *memblock_size; + unsigned long memblock_size; int rc; - np = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); - if (!np) + memblock_size = get_memblock_size(); + if (!memblock_size) return -EINVAL; - memblock_size = of_get_property(np, "ibm,memblock-size", NULL); - if (!memblock_size) { - of_node_put(np); - return -EINVAL; - } - if (action == PSERIES_DRCONF_MEM_ADD) { - rc = memblock_add(*base, *memblock_size); + rc = memblock_add(*base, memblock_size); rc = (rc < 0) ? -EINVAL : 0; } else if (action == PSERIES_DRCONF_MEM_REMOVE) { - rc = pseries_remove_memblock(*base, *memblock_size); + rc = pseries_remove_memblock(*base, memblock_size); } else { rc = -EINVAL; } - of_node_put(np); return rc; } ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 7/8] v3 Define memory_block_size_bytes() for ppc/pseries @ 2010-07-20 3:59 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:59 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: KAMEZAWA Hiroyuki, greg Define a version of memory_block_size_bytes() for powerpc/pseries such that a memory block spans an entire lmb. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> --- arch/powerpc/platforms/pseries/hotplug-memory.c | 66 +++++++++++++++++++----- 1 file changed, 53 insertions(+), 13 deletions(-) Index: linux-2.6/arch/powerpc/platforms/pseries/hotplug-memory.c =================================================================== --- linux-2.6.orig/arch/powerpc/platforms/pseries/hotplug-memory.c 2010-07-19 21:10:24.000000000 -0500 +++ linux-2.6/arch/powerpc/platforms/pseries/hotplug-memory.c 2010-07-19 21:13:32.000000000 -0500 @@ -17,6 +17,54 @@ #include <asm/pSeries_reconfig.h> #include <asm/sparsemem.h> +static u32 get_memblock_size(void) +{ + struct device_node *np; + unsigned int memblock_size = 0; + + np = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); + if (np) { + const unsigned int *size; + + size = of_get_property(np, "ibm,lmb-size", NULL); + memblock_size = size ? *size : 0; + + of_node_put(np); + } else { + unsigned int memzero_size = 0; + const unsigned int *regs; + + np = of_find_node_by_path("/memory@0"); + if (np) { + regs = of_get_property(np, "reg", NULL); + memzero_size = regs ? regs[3] : 0; + of_node_put(np); + } + + if (memzero_size) { + /* We now know the size of memory@0, use this to find + * the first memoryblock and get its size. + */ + char buf[64]; + + sprintf(buf, "/memory@%x", memzero_size); + np = of_find_node_by_path(buf); + if (np) { + regs = of_get_property(np, "reg", NULL); + memblock_size = regs ? regs[3] : 0; + of_node_put(np); + } + } + } + + return memblock_size; +} + +u32 memory_block_size_bytes(void) +{ + return get_memblock_size(); +} + static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size) { unsigned long start, start_pfn; @@ -127,30 +175,22 @@ static int pseries_add_memory(struct dev static int pseries_drconf_memory(unsigned long *base, unsigned int action) { - struct device_node *np; - const unsigned long *memblock_size; + unsigned long memblock_size; int rc; - np = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); - if (!np) + memblock_size = get_memblock_size(); + if (!memblock_size) return -EINVAL; - memblock_size = of_get_property(np, "ibm,memblock-size", NULL); - if (!memblock_size) { - of_node_put(np); - return -EINVAL; - } - if (action == PSERIES_DRCONF_MEM_ADD) { - rc = memblock_add(*base, *memblock_size); + rc = memblock_add(*base, memblock_size); rc = (rc < 0) ? -EINVAL : 0; } else if (action == PSERIES_DRCONF_MEM_REMOVE) { - rc = pseries_remove_memblock(*base, *memblock_size); + rc = pseries_remove_memblock(*base, memblock_size); } else { rc = -EINVAL; } - of_node_put(np); return rc; } -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 7/8] v3 Define memory_block_size_bytes() for ppc/pseries @ 2010-07-20 3:59 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:59 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: KAMEZAWA Hiroyuki, greg Define a version of memory_block_size_bytes() for powerpc/pseries such that a memory block spans an entire lmb. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> --- arch/powerpc/platforms/pseries/hotplug-memory.c | 66 +++++++++++++++++++----- 1 file changed, 53 insertions(+), 13 deletions(-) Index: linux-2.6/arch/powerpc/platforms/pseries/hotplug-memory.c =================================================================== --- linux-2.6.orig/arch/powerpc/platforms/pseries/hotplug-memory.c 2010-07-19 21:10:24.000000000 -0500 +++ linux-2.6/arch/powerpc/platforms/pseries/hotplug-memory.c 2010-07-19 21:13:32.000000000 -0500 @@ -17,6 +17,54 @@ #include <asm/pSeries_reconfig.h> #include <asm/sparsemem.h> +static u32 get_memblock_size(void) +{ + struct device_node *np; + unsigned int memblock_size = 0; + + np = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); + if (np) { + const unsigned int *size; + + size = of_get_property(np, "ibm,lmb-size", NULL); + memblock_size = size ? *size : 0; + + of_node_put(np); + } else { + unsigned int memzero_size = 0; + const unsigned int *regs; + + np = of_find_node_by_path("/memory@0"); + if (np) { + regs = of_get_property(np, "reg", NULL); + memzero_size = regs ? regs[3] : 0; + of_node_put(np); + } + + if (memzero_size) { + /* We now know the size of memory@0, use this to find + * the first memoryblock and get its size. + */ + char buf[64]; + + sprintf(buf, "/memory@%x", memzero_size); + np = of_find_node_by_path(buf); + if (np) { + regs = of_get_property(np, "reg", NULL); + memblock_size = regs ? regs[3] : 0; + of_node_put(np); + } + } + } + + return memblock_size; +} + +u32 memory_block_size_bytes(void) +{ + return get_memblock_size(); +} + static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size) { unsigned long start, start_pfn; @@ -127,30 +175,22 @@ static int pseries_add_memory(struct dev static int pseries_drconf_memory(unsigned long *base, unsigned int action) { - struct device_node *np; - const unsigned long *memblock_size; + unsigned long memblock_size; int rc; - np = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); - if (!np) + memblock_size = get_memblock_size(); + if (!memblock_size) return -EINVAL; - memblock_size = of_get_property(np, "ibm,memblock-size", NULL); - if (!memblock_size) { - of_node_put(np); - return -EINVAL; - } - if (action == PSERIES_DRCONF_MEM_ADD) { - rc = memblock_add(*base, *memblock_size); + rc = memblock_add(*base, memblock_size); rc = (rc < 0) ? -EINVAL : 0; } else if (action == PSERIES_DRCONF_MEM_REMOVE) { - rc = pseries_remove_memblock(*base, *memblock_size); + rc = pseries_remove_memblock(*base, memblock_size); } else { rc = -EINVAL; } - of_node_put(np); return rc; } ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 7/8] v3 Define memory_block_size_bytes() for ppc/pseries 2010-07-20 3:59 ` Nathan Fontenot (?) @ 2010-07-21 20:27 ` Brian King -1 siblings, 0 replies; 90+ messages in thread From: Brian King @ 2010-07-21 20:27 UTC (permalink / raw) To: Nathan Fontenot Cc: linux-mm, greg, linux-kernel, KAMEZAWA Hiroyuki, linuxppc-dev On 07/19/2010 10:59 PM, Nathan Fontenot wrote: > > +static u32 get_memblock_size(void) > +{ > + struct device_node *np; > + unsigned int memblock_size = 0; > + > + np = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); > + if (np) { > + const unsigned int *size; This needs to be an unsigned long, otherwise I always get zero on my p6. > + > + size = of_get_property(np, "ibm,lmb-size", NULL); > + memblock_size = size ? *size : 0; > + > + of_node_put(np); -- Brian King Linux on Power Virtualization IBM Linux Technology Center ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 7/8] v3 Define memory_block_size_bytes() for ppc/pseries @ 2010-07-21 20:27 ` Brian King 0 siblings, 0 replies; 90+ messages in thread From: Brian King @ 2010-07-21 20:27 UTC (permalink / raw) To: Nathan Fontenot Cc: linux-kernel, linux-mm, linuxppc-dev, greg, KAMEZAWA Hiroyuki On 07/19/2010 10:59 PM, Nathan Fontenot wrote: > > +static u32 get_memblock_size(void) > +{ > + struct device_node *np; > + unsigned int memblock_size = 0; > + > + np = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); > + if (np) { > + const unsigned int *size; This needs to be an unsigned long, otherwise I always get zero on my p6. > + > + size = of_get_property(np, "ibm,lmb-size", NULL); > + memblock_size = size ? *size : 0; > + > + of_node_put(np); -- Brian King Linux on Power Virtualization IBM Linux Technology Center -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 7/8] v3 Define memory_block_size_bytes() for ppc/pseries @ 2010-07-21 20:27 ` Brian King 0 siblings, 0 replies; 90+ messages in thread From: Brian King @ 2010-07-21 20:27 UTC (permalink / raw) To: Nathan Fontenot Cc: linux-kernel, linux-mm, linuxppc-dev, greg, KAMEZAWA Hiroyuki On 07/19/2010 10:59 PM, Nathan Fontenot wrote: > > +static u32 get_memblock_size(void) > +{ > + struct device_node *np; > + unsigned int memblock_size = 0; > + > + np = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); > + if (np) { > + const unsigned int *size; This needs to be an unsigned long, otherwise I always get zero on my p6. > + > + size = of_get_property(np, "ibm,lmb-size", NULL); > + memblock_size = size ? *size : 0; > + > + of_node_put(np); -- Brian King Linux on Power Virtualization IBM Linux Technology Center ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 8/8] v3 Update memory-hotplug documentation 2010-07-20 3:45 ` Nathan Fontenot (?) @ 2010-07-20 3:59 ` Nathan Fontenot -1 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:59 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: greg, KAMEZAWA Hiroyuki Update the memory hotplug documentation to reflect the new behaviors of memory blocks reflected in sysfs. Signed-off-by: Nathan Fontent <nfont@austin.ibm.com> --- Documentation/memory-hotplug.txt | 40 +++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) Index: linux-2.6/Documentation/memory-hotplug.txt =================================================================== --- linux-2.6.orig/Documentation/memory-hotplug.txt 2010-06-23 15:06:53.000000000 -0500 +++ linux-2.6/Documentation/memory-hotplug.txt 2010-07-19 21:00:11.000000000 -0500 @@ -126,36 +126,44 @@ config options. -------------------------------- 4 sysfs files for memory hotplug -------------------------------- -All sections have their device information under /sys/devices/system/memory as +All sections have their device information in sysfs. Each section is part of +a memory block under /sys/devices/system/memory as /sys/devices/system/memory/memoryXXX -(XXX is section id.) +(XXX is the section id.) -Now, XXX is defined as start_address_of_section / section_size. +Now, XXX is defined as (start_address_of_section / section_size) of the first +section conatined in the memory block. For example, assume 1GiB section size. A device for a memory starting at 0x100000000 is /sys/device/system/memory/memory4 (0x100000000 / 1Gib = 4) This device covers address range [0x100000000 ... 0x140000000) -Under each section, you can see 4 files. +Under each section, you can see 5 files. -/sys/devices/system/memory/memoryXXX/phys_index +/sys/devices/system/memory/memoryXXX/start_phys_index +/sys/devices/system/memory/memoryXXX/end_phys_index /sys/devices/system/memory/memoryXXX/phys_device /sys/devices/system/memory/memoryXXX/state /sys/devices/system/memory/memoryXXX/removable -'phys_index' : read-only and contains section id, same as XXX. -'state' : read-write - at read: contains online/offline state of memory. - at write: user can specify "online", "offline" command -'phys_device': read-only: designed to show the name of physical memory device. - This is not well implemented now. -'removable' : read-only: contains an integer value indicating - whether the memory section is removable or not - removable. A value of 1 indicates that the memory - section is removable and a value of 0 indicates that - it is not removable. +'start_phys_index' : read-only and contains section id of the first section + in the memory block, same as XXX. +'end_phys_index' : read-only and contains section id of the last section + in the memory block. +'state' : read-write + at read: contains online/offline state of memory. + at write: user can specify "online", "offline" command + which will be performed on al sections in the block. +'phys_device' : read-only: designed to show the name of physical memory + device. This is not well implemented now. +'removable' : read-only: contains an integer value indicating + whether the memory block is removable or not + removable. A value of 1 indicates that the memory + block is removable and a value of 0 indicates that + it is not removable. A memory block is removable only if + every section in the block is removable. NOTE: These directories/files appear after physical memory hotplug phase. ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 8/8] v3 Update memory-hotplug documentation @ 2010-07-20 3:59 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:59 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: KAMEZAWA Hiroyuki, greg Update the memory hotplug documentation to reflect the new behaviors of memory blocks reflected in sysfs. Signed-off-by: Nathan Fontent <nfont@austin.ibm.com> --- Documentation/memory-hotplug.txt | 40 +++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) Index: linux-2.6/Documentation/memory-hotplug.txt =================================================================== --- linux-2.6.orig/Documentation/memory-hotplug.txt 2010-06-23 15:06:53.000000000 -0500 +++ linux-2.6/Documentation/memory-hotplug.txt 2010-07-19 21:00:11.000000000 -0500 @@ -126,36 +126,44 @@ config options. -------------------------------- 4 sysfs files for memory hotplug -------------------------------- -All sections have their device information under /sys/devices/system/memory as +All sections have their device information in sysfs. Each section is part of +a memory block under /sys/devices/system/memory as /sys/devices/system/memory/memoryXXX -(XXX is section id.) +(XXX is the section id.) -Now, XXX is defined as start_address_of_section / section_size. +Now, XXX is defined as (start_address_of_section / section_size) of the first +section conatined in the memory block. For example, assume 1GiB section size. A device for a memory starting at 0x100000000 is /sys/device/system/memory/memory4 (0x100000000 / 1Gib = 4) This device covers address range [0x100000000 ... 0x140000000) -Under each section, you can see 4 files. +Under each section, you can see 5 files. -/sys/devices/system/memory/memoryXXX/phys_index +/sys/devices/system/memory/memoryXXX/start_phys_index +/sys/devices/system/memory/memoryXXX/end_phys_index /sys/devices/system/memory/memoryXXX/phys_device /sys/devices/system/memory/memoryXXX/state /sys/devices/system/memory/memoryXXX/removable -'phys_index' : read-only and contains section id, same as XXX. -'state' : read-write - at read: contains online/offline state of memory. - at write: user can specify "online", "offline" command -'phys_device': read-only: designed to show the name of physical memory device. - This is not well implemented now. -'removable' : read-only: contains an integer value indicating - whether the memory section is removable or not - removable. A value of 1 indicates that the memory - section is removable and a value of 0 indicates that - it is not removable. +'start_phys_index' : read-only and contains section id of the first section + in the memory block, same as XXX. +'end_phys_index' : read-only and contains section id of the last section + in the memory block. +'state' : read-write + at read: contains online/offline state of memory. + at write: user can specify "online", "offline" command + which will be performed on al sections in the block. +'phys_device' : read-only: designed to show the name of physical memory + device. This is not well implemented now. +'removable' : read-only: contains an integer value indicating + whether the memory block is removable or not + removable. A value of 1 indicates that the memory + block is removable and a value of 0 indicates that + it is not removable. A memory block is removable only if + every section in the block is removable. NOTE: These directories/files appear after physical memory hotplug phase. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH 8/8] v3 Update memory-hotplug documentation @ 2010-07-20 3:59 ` Nathan Fontenot 0 siblings, 0 replies; 90+ messages in thread From: Nathan Fontenot @ 2010-07-20 3:59 UTC (permalink / raw) To: linux-kernel, linux-mm, linuxppc-dev; +Cc: KAMEZAWA Hiroyuki, greg Update the memory hotplug documentation to reflect the new behaviors of memory blocks reflected in sysfs. Signed-off-by: Nathan Fontent <nfont@austin.ibm.com> --- Documentation/memory-hotplug.txt | 40 +++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) Index: linux-2.6/Documentation/memory-hotplug.txt =================================================================== --- linux-2.6.orig/Documentation/memory-hotplug.txt 2010-06-23 15:06:53.000000000 -0500 +++ linux-2.6/Documentation/memory-hotplug.txt 2010-07-19 21:00:11.000000000 -0500 @@ -126,36 +126,44 @@ config options. -------------------------------- 4 sysfs files for memory hotplug -------------------------------- -All sections have their device information under /sys/devices/system/memory as +All sections have their device information in sysfs. Each section is part of +a memory block under /sys/devices/system/memory as /sys/devices/system/memory/memoryXXX -(XXX is section id.) +(XXX is the section id.) -Now, XXX is defined as start_address_of_section / section_size. +Now, XXX is defined as (start_address_of_section / section_size) of the first +section conatined in the memory block. For example, assume 1GiB section size. A device for a memory starting at 0x100000000 is /sys/device/system/memory/memory4 (0x100000000 / 1Gib = 4) This device covers address range [0x100000000 ... 0x140000000) -Under each section, you can see 4 files. +Under each section, you can see 5 files. -/sys/devices/system/memory/memoryXXX/phys_index +/sys/devices/system/memory/memoryXXX/start_phys_index +/sys/devices/system/memory/memoryXXX/end_phys_index /sys/devices/system/memory/memoryXXX/phys_device /sys/devices/system/memory/memoryXXX/state /sys/devices/system/memory/memoryXXX/removable -'phys_index' : read-only and contains section id, same as XXX. -'state' : read-write - at read: contains online/offline state of memory. - at write: user can specify "online", "offline" command -'phys_device': read-only: designed to show the name of physical memory device. - This is not well implemented now. -'removable' : read-only: contains an integer value indicating - whether the memory section is removable or not - removable. A value of 1 indicates that the memory - section is removable and a value of 0 indicates that - it is not removable. +'start_phys_index' : read-only and contains section id of the first section + in the memory block, same as XXX. +'end_phys_index' : read-only and contains section id of the last section + in the memory block. +'state' : read-write + at read: contains online/offline state of memory. + at write: user can specify "online", "offline" command + which will be performed on al sections in the block. +'phys_device' : read-only: designed to show the name of physical memory + device. This is not well implemented now. +'removable' : read-only: contains an integer value indicating + whether the memory block is removable or not + removable. A value of 1 indicates that the memory + block is removable and a value of 0 indicates that + it is not removable. A memory block is removable only if + every section in the block is removable. NOTE: These directories/files appear after physical memory hotplug phase. ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 8/8] v3 Update memory-hotplug documentation 2010-07-20 3:59 ` Nathan Fontenot (?) @ 2010-07-20 19:23 ` Dave Hansen -1 siblings, 0 replies; 90+ messages in thread From: Dave Hansen @ 2010-07-20 19:23 UTC (permalink / raw) To: Nathan Fontenot Cc: linux-mm, greg, linux-kernel, KAMEZAWA Hiroyuki, linuxppc-dev On Mon, 2010-07-19 at 22:59 -0500, Nathan Fontenot wrote: > > > -Now, XXX is defined as start_address_of_section / section_size. > +Now, XXX is defined as (start_address_of_section / section_size) of > the first > +section conatined in the memory block. > > For example, assume 1GiB section size. A device for a memory starting > at > 0x100000000 is /sys/device/system/memory/memory4 > (0x100000000 / 1Gib = 4) > This device covers address range [0x100000000 ... 0x140000000) > > -Under each section, you can see 4 files. > +Under each section, you can see 5 files. > > -/sys/devices/system/memory/memoryXXX/phys_index > +/sys/devices/system/memory/memoryXXX/start_phys_index > +/sys/devices/system/memory/memoryXXX/end_phys_index Just wanted to make sure you didn't forget to update this after KAME's comments on the first couple of patches. -- Dave ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 8/8] v3 Update memory-hotplug documentation @ 2010-07-20 19:23 ` Dave Hansen 0 siblings, 0 replies; 90+ messages in thread From: Dave Hansen @ 2010-07-20 19:23 UTC (permalink / raw) To: Nathan Fontenot Cc: linux-kernel, linux-mm, linuxppc-dev, KAMEZAWA Hiroyuki, greg On Mon, 2010-07-19 at 22:59 -0500, Nathan Fontenot wrote: > > > -Now, XXX is defined as start_address_of_section / section_size. > +Now, XXX is defined as (start_address_of_section / section_size) of > the first > +section conatined in the memory block. > > For example, assume 1GiB section size. A device for a memory starting > at > 0x100000000 is /sys/device/system/memory/memory4 > (0x100000000 / 1Gib = 4) > This device covers address range [0x100000000 ... 0x140000000) > > -Under each section, you can see 4 files. > +Under each section, you can see 5 files. > > -/sys/devices/system/memory/memoryXXX/phys_index > +/sys/devices/system/memory/memoryXXX/start_phys_index > +/sys/devices/system/memory/memoryXXX/end_phys_index Just wanted to make sure you didn't forget to update this after KAME's comments on the first couple of patches. -- Dave -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 8/8] v3 Update memory-hotplug documentation @ 2010-07-20 19:23 ` Dave Hansen 0 siblings, 0 replies; 90+ messages in thread From: Dave Hansen @ 2010-07-20 19:23 UTC (permalink / raw) To: Nathan Fontenot Cc: linux-kernel, linux-mm, linuxppc-dev, KAMEZAWA Hiroyuki, greg On Mon, 2010-07-19 at 22:59 -0500, Nathan Fontenot wrote: > > > -Now, XXX is defined as start_address_of_section / section_size. > +Now, XXX is defined as (start_address_of_section / section_size) of > the first > +section conatined in the memory block. > > For example, assume 1GiB section size. A device for a memory starting > at > 0x100000000 is /sys/device/system/memory/memory4 > (0x100000000 / 1Gib = 4) > This device covers address range [0x100000000 ... 0x140000000) > > -Under each section, you can see 4 files. > +Under each section, you can see 5 files. > > -/sys/devices/system/memory/memoryXXX/phys_index > +/sys/devices/system/memory/memoryXXX/start_phys_index > +/sys/devices/system/memory/memoryXXX/end_phys_index Just wanted to make sure you didn't forget to update this after KAME's comments on the first couple of patches. -- Dave ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 0/8] v3 De-couple sysfs memory directories from memory sections 2010-07-20 3:45 ` Nathan Fontenot (?) @ 2010-07-31 5:36 ` Benjamin Herrenschmidt -1 siblings, 0 replies; 90+ messages in thread From: Benjamin Herrenschmidt @ 2010-07-31 5:36 UTC (permalink / raw) To: Nathan Fontenot Cc: linux-mm, greg, linux-kernel, KAMEZAWA Hiroyuki, linuxppc-dev On Mon, 2010-07-19 at 22:45 -0500, Nathan Fontenot wrote: > This set of patches de-couples the idea that there is a single > directory in sysfs for each memory section. The intent of the > patches is to reduce the number of sysfs directories created to > resolve a boot-time performance issue. On very large systems > boot time are getting very long (as seen on powerpc hardware) > due to the enormous number of sysfs directories being created. > On a system with 1 TB of memory we create ~63,000 directories. > For even larger systems boot times are being measured in hours. Greg, Kame, how do we proceed with these ? I'm happy to put them in powerpc.git with appropriate acks or will you take them ? Cheers, Ben. ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 0/8] v3 De-couple sysfs memory directories from memory sections @ 2010-07-31 5:36 ` Benjamin Herrenschmidt 0 siblings, 0 replies; 90+ messages in thread From: Benjamin Herrenschmidt @ 2010-07-31 5:36 UTC (permalink / raw) To: Nathan Fontenot Cc: linux-kernel, linux-mm, linuxppc-dev, greg, KAMEZAWA Hiroyuki On Mon, 2010-07-19 at 22:45 -0500, Nathan Fontenot wrote: > This set of patches de-couples the idea that there is a single > directory in sysfs for each memory section. The intent of the > patches is to reduce the number of sysfs directories created to > resolve a boot-time performance issue. On very large systems > boot time are getting very long (as seen on powerpc hardware) > due to the enormous number of sysfs directories being created. > On a system with 1 TB of memory we create ~63,000 directories. > For even larger systems boot times are being measured in hours. Greg, Kame, how do we proceed with these ? I'm happy to put them in powerpc.git with appropriate acks or will you take them ? Cheers, Ben. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 0/8] v3 De-couple sysfs memory directories from memory sections @ 2010-07-31 5:36 ` Benjamin Herrenschmidt 0 siblings, 0 replies; 90+ messages in thread From: Benjamin Herrenschmidt @ 2010-07-31 5:36 UTC (permalink / raw) To: Nathan Fontenot Cc: linux-kernel, linux-mm, linuxppc-dev, greg, KAMEZAWA Hiroyuki On Mon, 2010-07-19 at 22:45 -0500, Nathan Fontenot wrote: > This set of patches de-couples the idea that there is a single > directory in sysfs for each memory section. The intent of the > patches is to reduce the number of sysfs directories created to > resolve a boot-time performance issue. On very large systems > boot time are getting very long (as seen on powerpc hardware) > due to the enormous number of sysfs directories being created. > On a system with 1 TB of memory we create ~63,000 directories. > For even larger systems boot times are being measured in hours. Greg, Kame, how do we proceed with these ? I'm happy to put them in powerpc.git with appropriate acks or will you take them ? Cheers, Ben. ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 0/8] v3 De-couple sysfs memory directories from memory sections 2010-07-31 5:36 ` Benjamin Herrenschmidt (?) @ 2010-07-31 19:55 ` Greg KH -1 siblings, 0 replies; 90+ messages in thread From: Greg KH @ 2010-07-31 19:55 UTC (permalink / raw) To: Benjamin Herrenschmidt Cc: linux-mm, linux-kernel, KAMEZAWA Hiroyuki, linuxppc-dev On Sat, Jul 31, 2010 at 03:36:24PM +1000, Benjamin Herrenschmidt wrote: > On Mon, 2010-07-19 at 22:45 -0500, Nathan Fontenot wrote: > > This set of patches de-couples the idea that there is a single > > directory in sysfs for each memory section. The intent of the > > patches is to reduce the number of sysfs directories created to > > resolve a boot-time performance issue. On very large systems > > boot time are getting very long (as seen on powerpc hardware) > > due to the enormous number of sysfs directories being created. > > On a system with 1 TB of memory we create ~63,000 directories. > > For even larger systems boot times are being measured in hours. > > Greg, Kame, how do we proceed with these ? I'm happy to put them in > powerpc.git with appropriate acks or will you take them ? I thought there would be at least one more round of these patches based on the review comments, right? I'll be glad to take them when everyone agrees with them. thanks, greg k-h ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 0/8] v3 De-couple sysfs memory directories from memory sections @ 2010-07-31 19:55 ` Greg KH 0 siblings, 0 replies; 90+ messages in thread From: Greg KH @ 2010-07-31 19:55 UTC (permalink / raw) To: Benjamin Herrenschmidt Cc: Nathan Fontenot, linux-kernel, linux-mm, linuxppc-dev, KAMEZAWA Hiroyuki On Sat, Jul 31, 2010 at 03:36:24PM +1000, Benjamin Herrenschmidt wrote: > On Mon, 2010-07-19 at 22:45 -0500, Nathan Fontenot wrote: > > This set of patches de-couples the idea that there is a single > > directory in sysfs for each memory section. The intent of the > > patches is to reduce the number of sysfs directories created to > > resolve a boot-time performance issue. On very large systems > > boot time are getting very long (as seen on powerpc hardware) > > due to the enormous number of sysfs directories being created. > > On a system with 1 TB of memory we create ~63,000 directories. > > For even larger systems boot times are being measured in hours. > > Greg, Kame, how do we proceed with these ? I'm happy to put them in > powerpc.git with appropriate acks or will you take them ? I thought there would be at least one more round of these patches based on the review comments, right? I'll be glad to take them when everyone agrees with them. thanks, greg k-h -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 0/8] v3 De-couple sysfs memory directories from memory sections @ 2010-07-31 19:55 ` Greg KH 0 siblings, 0 replies; 90+ messages in thread From: Greg KH @ 2010-07-31 19:55 UTC (permalink / raw) To: Benjamin Herrenschmidt Cc: Nathan Fontenot, linux-kernel, linux-mm, linuxppc-dev, KAMEZAWA Hiroyuki On Sat, Jul 31, 2010 at 03:36:24PM +1000, Benjamin Herrenschmidt wrote: > On Mon, 2010-07-19 at 22:45 -0500, Nathan Fontenot wrote: > > This set of patches de-couples the idea that there is a single > > directory in sysfs for each memory section. The intent of the > > patches is to reduce the number of sysfs directories created to > > resolve a boot-time performance issue. On very large systems > > boot time are getting very long (as seen on powerpc hardware) > > due to the enormous number of sysfs directories being created. > > On a system with 1 TB of memory we create ~63,000 directories. > > For even larger systems boot times are being measured in hours. > > Greg, Kame, how do we proceed with these ? I'm happy to put them in > powerpc.git with appropriate acks or will you take them ? I thought there would be at least one more round of these patches based on the review comments, right? I'll be glad to take them when everyone agrees with them. thanks, greg k-h ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 0/8] v3 De-couple sysfs memory directories from memory sections 2010-07-31 19:55 ` Greg KH (?) @ 2010-08-01 0:27 ` Benjamin Herrenschmidt -1 siblings, 0 replies; 90+ messages in thread From: Benjamin Herrenschmidt @ 2010-08-01 0:27 UTC (permalink / raw) To: Greg KH; +Cc: linux-mm, linux-kernel, KAMEZAWA Hiroyuki, linuxppc-dev On Sat, 2010-07-31 at 12:55 -0700, Greg KH wrote: > On Sat, Jul 31, 2010 at 03:36:24PM +1000, Benjamin Herrenschmidt wrote: > > On Mon, 2010-07-19 at 22:45 -0500, Nathan Fontenot wrote: > > > This set of patches de-couples the idea that there is a single > > > directory in sysfs for each memory section. The intent of the > > > patches is to reduce the number of sysfs directories created to > > > resolve a boot-time performance issue. On very large systems > > > boot time are getting very long (as seen on powerpc hardware) > > > due to the enormous number of sysfs directories being created. > > > On a system with 1 TB of memory we create ~63,000 directories. > > > For even larger systems boot times are being measured in hours. > > > > Greg, Kame, how do we proceed with these ? I'm happy to put them in > > powerpc.git with appropriate acks or will you take them ? > > I thought there would be at least one more round of these patches based > on the review comments, right? Yes, but I was nontheless inquiring whether I should pick them up after said repost :-) > I'll be glad to take them when everyone agrees with them. Ok, good, one less thing to worry about in powerpc patchwork :-) Cheers, Ben. > thanks, > > greg k-h ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 0/8] v3 De-couple sysfs memory directories from memory sections @ 2010-08-01 0:27 ` Benjamin Herrenschmidt 0 siblings, 0 replies; 90+ messages in thread From: Benjamin Herrenschmidt @ 2010-08-01 0:27 UTC (permalink / raw) To: Greg KH Cc: Nathan Fontenot, linux-kernel, linux-mm, linuxppc-dev, KAMEZAWA Hiroyuki On Sat, 2010-07-31 at 12:55 -0700, Greg KH wrote: > On Sat, Jul 31, 2010 at 03:36:24PM +1000, Benjamin Herrenschmidt wrote: > > On Mon, 2010-07-19 at 22:45 -0500, Nathan Fontenot wrote: > > > This set of patches de-couples the idea that there is a single > > > directory in sysfs for each memory section. The intent of the > > > patches is to reduce the number of sysfs directories created to > > > resolve a boot-time performance issue. On very large systems > > > boot time are getting very long (as seen on powerpc hardware) > > > due to the enormous number of sysfs directories being created. > > > On a system with 1 TB of memory we create ~63,000 directories. > > > For even larger systems boot times are being measured in hours. > > > > Greg, Kame, how do we proceed with these ? I'm happy to put them in > > powerpc.git with appropriate acks or will you take them ? > > I thought there would be at least one more round of these patches based > on the review comments, right? Yes, but I was nontheless inquiring whether I should pick them up after said repost :-) > I'll be glad to take them when everyone agrees with them. Ok, good, one less thing to worry about in powerpc patchwork :-) Cheers, Ben. > thanks, > > greg k-h -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH 0/8] v3 De-couple sysfs memory directories from memory sections @ 2010-08-01 0:27 ` Benjamin Herrenschmidt 0 siblings, 0 replies; 90+ messages in thread From: Benjamin Herrenschmidt @ 2010-08-01 0:27 UTC (permalink / raw) To: Greg KH Cc: Nathan Fontenot, linux-kernel, linux-mm, linuxppc-dev, KAMEZAWA Hiroyuki On Sat, 2010-07-31 at 12:55 -0700, Greg KH wrote: > On Sat, Jul 31, 2010 at 03:36:24PM +1000, Benjamin Herrenschmidt wrote: > > On Mon, 2010-07-19 at 22:45 -0500, Nathan Fontenot wrote: > > > This set of patches de-couples the idea that there is a single > > > directory in sysfs for each memory section. The intent of the > > > patches is to reduce the number of sysfs directories created to > > > resolve a boot-time performance issue. On very large systems > > > boot time are getting very long (as seen on powerpc hardware) > > > due to the enormous number of sysfs directories being created. > > > On a system with 1 TB of memory we create ~63,000 directories. > > > For even larger systems boot times are being measured in hours. > > > > Greg, Kame, how do we proceed with these ? I'm happy to put them in > > powerpc.git with appropriate acks or will you take them ? > > I thought there would be at least one more round of these patches based > on the review comments, right? Yes, but I was nontheless inquiring whether I should pick them up after said repost :-) > I'll be glad to take them when everyone agrees with them. Ok, good, one less thing to worry about in powerpc patchwork :-) Cheers, Ben. > thanks, > > greg k-h ^ permalink raw reply [flat|nested] 90+ messages in thread
end of thread, other threads:[~2010-08-01 0:30 UTC | newest] Thread overview: 90+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-07-20 3:45 [PATCH 0/8] v3 De-couple sysfs memory directories from memory sections Nathan Fontenot 2010-07-20 3:45 ` Nathan Fontenot 2010-07-20 3:45 ` Nathan Fontenot 2010-07-20 3:51 ` [PATCH 1/8] v3 Move the find_memory_block() routine up Nathan Fontenot 2010-07-20 3:51 ` Nathan Fontenot 2010-07-20 3:51 ` Nathan Fontenot 2010-07-20 6:55 ` KAMEZAWA Hiroyuki 2010-07-20 6:55 ` KAMEZAWA Hiroyuki 2010-07-20 6:55 ` KAMEZAWA Hiroyuki 2010-07-20 3:52 ` [PATCH 2/8] v3 Add new phys_index properties Nathan Fontenot 2010-07-20 3:52 ` Nathan Fontenot 2010-07-20 3:52 ` Nathan Fontenot 2010-07-20 6:57 ` KAMEZAWA Hiroyuki 2010-07-20 6:57 ` KAMEZAWA Hiroyuki 2010-07-20 6:57 ` KAMEZAWA Hiroyuki 2010-07-20 13:24 ` Nathan Fontenot 2010-07-20 13:24 ` Nathan Fontenot 2010-07-20 13:24 ` Nathan Fontenot 2010-07-20 19:10 ` Dave Hansen 2010-07-20 19:10 ` Dave Hansen 2010-07-20 19:10 ` Dave Hansen 2010-07-20 3:53 ` [PATCH 3/8] v3 Add section count to memory_block Nathan Fontenot 2010-07-20 3:53 ` Nathan Fontenot 2010-07-20 3:53 ` Nathan Fontenot 2010-07-20 7:01 ` KAMEZAWA Hiroyuki 2010-07-20 7:01 ` KAMEZAWA Hiroyuki 2010-07-20 7:01 ` KAMEZAWA Hiroyuki 2010-07-20 13:26 ` Nathan Fontenot 2010-07-20 13:26 ` Nathan Fontenot 2010-07-20 13:26 ` Nathan Fontenot 2010-07-20 3:55 ` [PATCH 4/8] v3 Allow memory_block to span multiple memory sections Nathan Fontenot 2010-07-20 3:55 ` Nathan Fontenot 2010-07-20 3:55 ` Nathan Fontenot 2010-07-20 7:15 ` KAMEZAWA Hiroyuki 2010-07-20 7:15 ` KAMEZAWA Hiroyuki 2010-07-20 7:15 ` KAMEZAWA Hiroyuki 2010-07-20 13:28 ` Nathan Fontenot 2010-07-20 13:28 ` Nathan Fontenot 2010-07-20 13:28 ` Nathan Fontenot 2010-07-20 19:18 ` Dave Hansen 2010-07-20 19:18 ` Dave Hansen 2010-07-20 19:18 ` Dave Hansen 2010-07-24 3:09 ` Nathan Fontenot 2010-07-24 3:09 ` Nathan Fontenot 2010-07-24 3:09 ` Nathan Fontenot 2010-07-27 2:36 ` Dave Hansen 2010-07-27 2:36 ` Dave Hansen 2010-07-27 2:36 ` Dave Hansen 2010-07-26 19:10 ` Nathan Fontenot 2010-07-26 19:10 ` Nathan Fontenot 2010-07-26 19:10 ` Nathan Fontenot 2010-07-20 19:21 ` Dave Hansen 2010-07-20 19:21 ` Dave Hansen 2010-07-20 19:21 ` Dave Hansen 2010-07-20 3:56 ` [PATCH 5/8] v3 Update the find_memory_block declaration Nathan Fontenot 2010-07-20 3:56 ` Nathan Fontenot 2010-07-20 3:56 ` Nathan Fontenot 2010-07-20 7:16 ` KAMEZAWA Hiroyuki 2010-07-20 7:16 ` KAMEZAWA Hiroyuki 2010-07-20 7:16 ` KAMEZAWA Hiroyuki 2010-07-20 3:57 ` [PATCH 6/8] v3 Update the node sysfs code Nathan Fontenot 2010-07-20 3:57 ` Nathan Fontenot 2010-07-20 3:57 ` Nathan Fontenot 2010-07-20 7:17 ` KAMEZAWA Hiroyuki 2010-07-20 7:17 ` KAMEZAWA Hiroyuki 2010-07-20 7:17 ` KAMEZAWA Hiroyuki 2010-07-28 13:50 ` Brian King 2010-07-28 13:50 ` Brian King 2010-07-28 13:50 ` Brian King 2010-07-20 3:59 ` [PATCH 7/8] v3 Define memory_block_size_bytes() for ppc/pseries Nathan Fontenot 2010-07-20 3:59 ` Nathan Fontenot 2010-07-20 3:59 ` Nathan Fontenot 2010-07-21 20:27 ` Brian King 2010-07-21 20:27 ` Brian King 2010-07-21 20:27 ` Brian King 2010-07-20 3:59 ` [PATCH 8/8] v3 Update memory-hotplug documentation Nathan Fontenot 2010-07-20 3:59 ` Nathan Fontenot 2010-07-20 3:59 ` Nathan Fontenot 2010-07-20 19:23 ` Dave Hansen 2010-07-20 19:23 ` Dave Hansen 2010-07-20 19:23 ` Dave Hansen 2010-07-31 5:36 ` [PATCH 0/8] v3 De-couple sysfs memory directories from memory sections Benjamin Herrenschmidt 2010-07-31 5:36 ` Benjamin Herrenschmidt 2010-07-31 5:36 ` Benjamin Herrenschmidt 2010-07-31 19:55 ` Greg KH 2010-07-31 19:55 ` Greg KH 2010-07-31 19:55 ` Greg KH 2010-08-01 0:27 ` Benjamin Herrenschmidt 2010-08-01 0:27 ` Benjamin Herrenschmidt 2010-08-01 0:27 ` Benjamin Herrenschmidt
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.