* [Patch 1/3] Introduce kset_find_obj_hinted.
2010-09-29 19:00 [Patch 0/3] Speed up link_mem_sections during boot Robin Holt
@ 2010-09-29 19:00 ` Robin Holt
2010-09-29 20:59 ` Dave Hansen
2010-09-30 1:59 ` KAMEZAWA Hiroyuki
2010-09-29 19:00 ` [Patch 2/3] Introduce find_memory_block_hinted which utilizes kset_find_obj_hinted Robin Holt
2010-09-29 19:00 ` [Patch 3/3] Convert link_mem_sections to use find_memory_block_hinted Robin Holt
2 siblings, 2 replies; 10+ messages in thread
From: Robin Holt @ 2010-09-29 19:00 UTC (permalink / raw)
To: lkml, Robert P. J. Day, Greg Kroah-Hartman
Cc: Badari Pulavarty, Dave Hansen, Gary Hade, Ingo Molnar,
Matt Tolentino
[-- Attachment #1: add-kset_find_obj_hinted --]
[-- Type: text/plain, Size: 3055 bytes --]
One call chain getting to kset_find_obj is:
link_mem_sections()
find_mem_section()
kset_find_obj()
This is done during boot. The memory sections were added in a linearly
increasing order and link_mem_sections tends to utilize them in that
same linear order.
Introduce a kset_find_obj_hinted which is passed the result of the
previous kset_find_obj which it uses for a quick "is the next object
our desired object" check before falling back to the old behavior.
Signed-off-by: Robin Holt <holt@sgi.com>
To: Robert P. J. Day <rpjday@crashcourse.ca>
To: Greg Kroah-Hartman <gregkh@suse.de>
Cc: lkml <linux-kernel@vger.kernel.org>
---
include/linux/kobject.h | 2 +
lib/kobject.c | 39 ++++++++++++++++++++++++++++++++++++++
2 files changed, 41 insertions(+)
Index: pv1010359/include/linux/kobject.h
===================================================================
--- pv1010359.orig/include/linux/kobject.h 2010-09-29 11:03:42.000000000 -0500
+++ pv1010359/include/linux/kobject.h 2010-09-29 11:20:09.903825173 -0500
@@ -191,6 +191,8 @@ static inline struct kobj_type *get_ktyp
}
extern struct kobject *kset_find_obj(struct kset *, const char *);
+extern struct kobject *kset_find_obj_hinted(struct kset *, const char *,
+ struct kobject *);
/* The global /sys/kernel/ kobject for people to chain off of */
extern struct kobject *kernel_kobj;
Index: pv1010359/lib/kobject.c
===================================================================
--- pv1010359.orig/lib/kobject.c 2010-09-29 11:03:42.000000000 -0500
+++ pv1010359/lib/kobject.c 2010-09-29 11:21:14.343956075 -0500
@@ -746,17 +746,56 @@ void kset_unregister(struct kset *k)
*/
struct kobject *kset_find_obj(struct kset *kset, const char *name)
{
+ return kset_find_obj_hinted(kset, name, NULL);
+}
+
+/**
+ * kset_find_obj_hinted - search for object in kset given a predecessor hint.
+ * @kset: kset we're looking in.
+ * @name: object's name.
+ * @hint: hint to possible object's predecessor.
+ *
+ * Check the hint's next object and if it is a match return it directly,
+ * otherwise, fall back to the behavior of kset_find_obj(). Either way
+ * a reference for the returned object is held and the reference on the
+ * hinted object is released.
+ */
+struct kobject *kset_find_obj_hinted(struct kset *kset, const char *name,
+ struct kobject *hint)
+{
struct kobject *k;
struct kobject *ret = NULL;
spin_lock(&kset->list_lock);
+
+ if (!hint)
+ goto slow_search;
+
+ /* end of list detection */
+ if (hint->entry.next == kset->list.next)
+ goto slow_search;
+
+ k = container_of(hint->entry.next, struct kobject, entry);
+ if (!kobject_name(k) || strcmp(kobject_name(k), name))
+ goto slow_search;
+
+ ret = kobject_get(k);
+ goto unlock_exit;
+
+slow_search:
list_for_each_entry(k, &kset->list, entry) {
if (kobject_name(k) && !strcmp(kobject_name(k), name)) {
ret = kobject_get(k);
break;
}
}
+
+unlock_exit:
spin_unlock(&kset->list_lock);
+
+ if (hint)
+ kobject_put(hint);
+
return ret;
}
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [Patch 1/3] Introduce kset_find_obj_hinted.
2010-09-29 19:00 ` [Patch 1/3] Introduce kset_find_obj_hinted Robin Holt
@ 2010-09-29 20:59 ` Dave Hansen
2010-09-29 21:44 ` Robin Holt
2010-09-30 1:59 ` KAMEZAWA Hiroyuki
1 sibling, 1 reply; 10+ messages in thread
From: Dave Hansen @ 2010-09-29 20:59 UTC (permalink / raw)
To: Robin Holt
Cc: lkml, Robert P. J. Day, Greg Kroah-Hartman, Badari Pulavarty,
Dave Hansen, Gary Hade, Ingo Molnar, Matt Tolentino
On Wed, 2010-09-29 at 14:00 -0500, Robin Holt wrote:
>
> struct kobject *kset_find_obj(struct kset *kset, const char *name)
> {
> + return kset_find_obj_hinted(kset, name, NULL);
> +}
> +
> +/**
> + * kset_find_obj_hinted - search for object in kset given a predecessor hint.
> + * @kset: kset we're looking in.
> + * @name: object's name.
> + * @hint: hint to possible object's predecessor.
> + *
> + * Check the hint's next object and if it is a match return it directly,
> + * otherwise, fall back to the behavior of kset_find_obj(). Either way
> + * a reference for the returned object is held and the reference on the
> + * hinted object is released.
> + */
> +struct kobject *kset_find_obj_hinted(struct kset *kset, const char *name,
> + struct kobject *hint)
> +{
> struct kobject *k;
> struct kobject *ret = NULL;
>
> spin_lock(&kset->list_lock);
> +
> + if (!hint)
> + goto slow_search;
> +
> + /* end of list detection */
> + if (hint->entry.next == kset->list.next)
> + goto slow_search;
> +
> + k = container_of(hint->entry.next, struct kobject, entry);
> + if (!kobject_name(k) || strcmp(kobject_name(k), name))
> + goto slow_search;
> +
> + ret = kobject_get(k);
> + goto unlock_exit;
> +
> +slow_search:
> list_for_each_entry(k, &kset->list, entry) {
> if (kobject_name(k) && !strcmp(kobject_name(k), name)) {
> ret = kobject_get(k);
> break;
> }
> }
So, the slow search ends up looking through _all_ of the sections in the
order they got registered, which _guarantees_ that we'll go all the way
through the list every time. Right?
I guess we could also add to the list using list_add_tail(), iterate
during the search using list_for_each_tail(), or even just look at the
last entry by looking at kset->list.prev directly. Those would have the
advantage of not having to have several levels in the call chain. We
also wouldn't have to change anything if and when this gets fixed
properly.
-- Dave
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [Patch 1/3] Introduce kset_find_obj_hinted.
2010-09-29 20:59 ` Dave Hansen
@ 2010-09-29 21:44 ` Robin Holt
0 siblings, 0 replies; 10+ messages in thread
From: Robin Holt @ 2010-09-29 21:44 UTC (permalink / raw)
To: Dave Hansen
Cc: Robin Holt, lkml, Robert P. J. Day, Greg Kroah-Hartman,
Badari Pulavarty, Dave Hansen, Gary Hade, Ingo Molnar,
Matt Tolentino
On Wed, Sep 29, 2010 at 01:59:16PM -0700, Dave Hansen wrote:
> On Wed, 2010-09-29 at 14:00 -0500, Robin Holt wrote:
> >
> > struct kobject *kset_find_obj(struct kset *kset, const char *name)
> > {
> > + return kset_find_obj_hinted(kset, name, NULL);
> > +}
> > +
> > +/**
> > + * kset_find_obj_hinted - search for object in kset given a predecessor hint.
> > + * @kset: kset we're looking in.
> > + * @name: object's name.
> > + * @hint: hint to possible object's predecessor.
> > + *
> > + * Check the hint's next object and if it is a match return it directly,
> > + * otherwise, fall back to the behavior of kset_find_obj(). Either way
> > + * a reference for the returned object is held and the reference on the
> > + * hinted object is released.
> > + */
> > +struct kobject *kset_find_obj_hinted(struct kset *kset, const char *name,
> > + struct kobject *hint)
> > +{
> > struct kobject *k;
> > struct kobject *ret = NULL;
> >
> > spin_lock(&kset->list_lock);
> > +
> > + if (!hint)
> > + goto slow_search;
> > +
> > + /* end of list detection */
> > + if (hint->entry.next == kset->list.next)
> > + goto slow_search;
> > +
> > + k = container_of(hint->entry.next, struct kobject, entry);
> > + if (!kobject_name(k) || strcmp(kobject_name(k), name))
> > + goto slow_search;
> > +
> > + ret = kobject_get(k);
> > + goto unlock_exit;
> > +
> > +slow_search:
> > list_for_each_entry(k, &kset->list, entry) {
> > if (kobject_name(k) && !strcmp(kobject_name(k), name)) {
> > ret = kobject_get(k);
> > break;
> > }
> > }
>
> So, the slow search ends up looking through _all_ of the sections in the
> order they got registered, which _guarantees_ that we'll go all the way
> through the list every time. Right?
>
> I guess we could also add to the list using list_add_tail(), iterate
> during the search using list_for_each_tail(), or even just look at the
> last entry by looking at kset->list.prev directly. Those would have the
> advantage of not having to have several levels in the call chain. We
> also wouldn't have to change anything if and when this gets fixed
> properly.
Except that drivers/base/memory.c's memory_dev_init registers all the
memory sections and then later, drivers/base/node.c's node_dev_init
looks for memory sections on each node and does the symlink.
Since the two are separated in time, either the head or tail based search
is going to end up with last or first part of the search sequence being
much slower.
Robin
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Patch 1/3] Introduce kset_find_obj_hinted.
2010-09-29 19:00 ` [Patch 1/3] Introduce kset_find_obj_hinted Robin Holt
2010-09-29 20:59 ` Dave Hansen
@ 2010-09-30 1:59 ` KAMEZAWA Hiroyuki
1 sibling, 0 replies; 10+ messages in thread
From: KAMEZAWA Hiroyuki @ 2010-09-30 1:59 UTC (permalink / raw)
To: Robin Holt
Cc: lkml, Robert P. J. Day, Greg Kroah-Hartman, Badari Pulavarty,
Dave Hansen, Gary Hade, Ingo Molnar, Matt Tolentino
On Wed, 29 Sep 2010 14:00:54 -0500
Robin Holt <holt@sgi.com> wrote:
> One call chain getting to kset_find_obj is:
> link_mem_sections()
> find_mem_section()
> kset_find_obj()
>
> This is done during boot. The memory sections were added in a linearly
> increasing order and link_mem_sections tends to utilize them in that
> same linear order.
>
> Introduce a kset_find_obj_hinted which is passed the result of the
> previous kset_find_obj which it uses for a quick "is the next object
> our desired object" check before falling back to the old behavior.
>
> Signed-off-by: Robin Holt <holt@sgi.com>
> To: Robert P. J. Day <rpjday@crashcourse.ca>
> To: Greg Kroah-Hartman <gregkh@suse.de>
> Cc: lkml <linux-kernel@vger.kernel.org>
>
Interesting. Thank you.
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
> ---
>
> include/linux/kobject.h | 2 +
> lib/kobject.c | 39 ++++++++++++++++++++++++++++++++++++++
> 2 files changed, 41 insertions(+)
>
> Index: pv1010359/include/linux/kobject.h
> ===================================================================
> --- pv1010359.orig/include/linux/kobject.h 2010-09-29 11:03:42.000000000 -0500
> +++ pv1010359/include/linux/kobject.h 2010-09-29 11:20:09.903825173 -0500
> @@ -191,6 +191,8 @@ static inline struct kobj_type *get_ktyp
> }
>
> extern struct kobject *kset_find_obj(struct kset *, const char *);
> +extern struct kobject *kset_find_obj_hinted(struct kset *, const char *,
> + struct kobject *);
>
> /* The global /sys/kernel/ kobject for people to chain off of */
> extern struct kobject *kernel_kobj;
> Index: pv1010359/lib/kobject.c
> ===================================================================
> --- pv1010359.orig/lib/kobject.c 2010-09-29 11:03:42.000000000 -0500
> +++ pv1010359/lib/kobject.c 2010-09-29 11:21:14.343956075 -0500
> @@ -746,17 +746,56 @@ void kset_unregister(struct kset *k)
> */
> struct kobject *kset_find_obj(struct kset *kset, const char *name)
> {
> + return kset_find_obj_hinted(kset, name, NULL);
> +}
> +
> +/**
> + * kset_find_obj_hinted - search for object in kset given a predecessor hint.
> + * @kset: kset we're looking in.
> + * @name: object's name.
> + * @hint: hint to possible object's predecessor.
> + *
> + * Check the hint's next object and if it is a match return it directly,
> + * otherwise, fall back to the behavior of kset_find_obj(). Either way
> + * a reference for the returned object is held and the reference on the
> + * hinted object is released.
> + */
> +struct kobject *kset_find_obj_hinted(struct kset *kset, const char *name,
> + struct kobject *hint)
> +{
> struct kobject *k;
> struct kobject *ret = NULL;
>
> spin_lock(&kset->list_lock);
> +
> + if (!hint)
> + goto slow_search;
> +
> + /* end of list detection */
> + if (hint->entry.next == kset->list.next)
> + goto slow_search;
> +
> + k = container_of(hint->entry.next, struct kobject, entry);
> + if (!kobject_name(k) || strcmp(kobject_name(k), name))
> + goto slow_search;
> +
> + ret = kobject_get(k);
> + goto unlock_exit;
> +
> +slow_search:
> list_for_each_entry(k, &kset->list, entry) {
> if (kobject_name(k) && !strcmp(kobject_name(k), name)) {
> ret = kobject_get(k);
> break;
> }
> }
> +
> +unlock_exit:
> spin_unlock(&kset->list_lock);
> +
> + if (hint)
> + kobject_put(hint);
> +
> return ret;
> }
>
>
> --
> 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] 10+ messages in thread
* [Patch 2/3] Introduce find_memory_block_hinted which utilizes kset_find_obj_hinted.
2010-09-29 19:00 [Patch 0/3] Speed up link_mem_sections during boot Robin Holt
2010-09-29 19:00 ` [Patch 1/3] Introduce kset_find_obj_hinted Robin Holt
@ 2010-09-29 19:00 ` Robin Holt
2010-09-30 2:00 ` KAMEZAWA Hiroyuki
2010-09-29 19:00 ` [Patch 3/3] Convert link_mem_sections to use find_memory_block_hinted Robin Holt
2 siblings, 1 reply; 10+ messages in thread
From: Robin Holt @ 2010-09-29 19:00 UTC (permalink / raw)
To: lkml, Dave Hansen, Matt Tolentino
Cc: Greg Kroah-Hartman, Badari Pulavarty, Gary Hade, Ingo Molnar,
Robert P. J. Day
[-- Attachment #1: add-find_memory_block_hinted --]
[-- Type: text/plain, Size: 3141 bytes --]
Introduce a find_memory_block_hinted() which utilizes the
recently added kset_find_obj_hinted().
Signed-off-by: Robin Holt <holt@sgi.com>
To: Dave Hansen <haveblue@us.ibm.com>
To: Matt Tolentino <matthew.e.tolentino@intel.com>
Cc: lkml <linux-kernel@vger.kernel.org>
---
drivers/base/memory.c | 28 ++++++++++++++++++----------
include/linux/memory.h | 2 ++
2 files changed, 20 insertions(+), 10 deletions(-)
Index: pv1010359/drivers/base/memory.c
===================================================================
--- pv1010359.orig/drivers/base/memory.c 2010-09-29 11:25:41.000000000 -0500
+++ pv1010359/drivers/base/memory.c 2010-09-29 11:33:49.903994093 -0500
@@ -468,28 +468,23 @@ 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 memory_block *find_memory_block_hinted(struct mem_section *section,
+ struct memory_block *hint)
{
struct kobject *kobj;
struct sys_device *sysdev;
struct memory_block *mem;
char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1];
+ kobj = hint ? &hint->sysdev.kobj : NULL;
+
/*
* This only works because we know that section == sysdev->id
* slightly redundant with sysdev_register()
*/
sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, __section_nr(section));
- kobj = kset_find_obj(&memory_sysdev_class.kset, name);
+ kobj = kset_find_obj_hinted(&memory_sysdev_class.kset, name, kobj);
if (!kobj)
return NULL;
@@ -499,6 +494,19 @@ struct memory_block *find_memory_block(s
return mem;
}
+/*
+ * For now, we have a linear search to go find the appropriate
+ * memory_block corresponding to a particular phys_index. If
+ * this gets to be a real problem, we can always use a radix
+ * tree or something here.
+ *
+ * This could be made generic for all sysdev classes.
+ */
+struct memory_block *find_memory_block(struct mem_section *section)
+{
+ return find_memory_block_hinted(section, NULL);
+}
+
int remove_memory_block(unsigned long node_id, struct mem_section *section,
int phys_device)
{
Index: pv1010359/include/linux/memory.h
===================================================================
--- pv1010359.orig/include/linux/memory.h 2010-09-29 11:25:41.000000000 -0500
+++ pv1010359/include/linux/memory.h 2010-09-29 11:25:43.289450971 -0500
@@ -113,6 +113,8 @@ 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_hinted(struct mem_section *,
+ struct memory_block *);
extern struct memory_block *find_memory_block(struct mem_section *);
#define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT)
enum mem_add_context { BOOT, HOTPLUG };
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [Patch 2/3] Introduce find_memory_block_hinted which utilizes kset_find_obj_hinted.
2010-09-29 19:00 ` [Patch 2/3] Introduce find_memory_block_hinted which utilizes kset_find_obj_hinted Robin Holt
@ 2010-09-30 2:00 ` KAMEZAWA Hiroyuki
0 siblings, 0 replies; 10+ messages in thread
From: KAMEZAWA Hiroyuki @ 2010-09-30 2:00 UTC (permalink / raw)
To: Robin Holt
Cc: lkml, Dave Hansen, Matt Tolentino, Greg Kroah-Hartman,
Badari Pulavarty, Gary Hade, Ingo Molnar, Robert P. J. Day
On Wed, 29 Sep 2010 14:00:55 -0500
Robin Holt <holt@sgi.com> wrote:
>
> Introduce a find_memory_block_hinted() which utilizes the
> recently added kset_find_obj_hinted().
>
> Signed-off-by: Robin Holt <holt@sgi.com>
> To: Dave Hansen <haveblue@us.ibm.com>
> To: Matt Tolentino <matthew.e.tolentino@intel.com>
> Cc: lkml <linux-kernel@vger.kernel.org>
>
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Patch 3/3] Convert link_mem_sections to use find_memory_block_hinted.
2010-09-29 19:00 [Patch 0/3] Speed up link_mem_sections during boot Robin Holt
2010-09-29 19:00 ` [Patch 1/3] Introduce kset_find_obj_hinted Robin Holt
2010-09-29 19:00 ` [Patch 2/3] Introduce find_memory_block_hinted which utilizes kset_find_obj_hinted Robin Holt
@ 2010-09-29 19:00 ` Robin Holt
2010-09-30 2:01 ` KAMEZAWA Hiroyuki
2010-10-05 23:18 ` patch "driver core: Convert link_mem_sections to use find_memory_block_hinted." added to gregkh-2.6 tree gregkh
2 siblings, 2 replies; 10+ messages in thread
From: Robin Holt @ 2010-09-29 19:00 UTC (permalink / raw)
To: lkml, Gary Hade, Badari Pulavarty, Ingo Molnar
Cc: Greg Kroah-Hartman, Dave Hansen, Matt Tolentino, Robert P. J. Day
[-- Attachment #1: link_mem_sections-hints --]
[-- Type: text/plain, Size: 1826 bytes --]
Modify link_mem_sections() to pass in the previous mem_block as a hint to
locating the next mem_block. Since they are typically added in order this
results in a massive saving in time during boot of a very large system.
For example, on a 16TB x86_64 machine, it reduced the total time spent
linking all node's memory sections from 1 hour, 27 minutes to 46 seconds.
Signed-off-by: Robin Holt <holt@sgi.com>
To: Gary Hade <garyhade@us.ibm.com>
To: Badari Pulavarty <pbadari@us.ibm.com>
To: Ingo Molnar <mingo@elte.hu>
Cc: lkml <linux-kernel@vger.kernel.org>
---
drivers/base/node.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
Index: pv1010359/drivers/base/node.c
===================================================================
--- pv1010359.orig/drivers/base/node.c 2010-09-29 11:03:14.076094048 -0500
+++ pv1010359/drivers/base/node.c 2010-09-29 11:03:44.739949033 -0500
@@ -409,25 +409,27 @@ static int link_mem_sections(int nid)
unsigned long start_pfn = NODE_DATA(nid)->node_start_pfn;
unsigned long end_pfn = start_pfn + NODE_DATA(nid)->node_spanned_pages;
unsigned long pfn;
+ struct memory_block *mem_blk = NULL;
int err = 0;
for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) {
unsigned long section_nr = pfn_to_section_nr(pfn);
struct mem_section *mem_sect;
- struct memory_block *mem_blk;
int ret;
if (!present_section_nr(section_nr))
continue;
mem_sect = __nr_to_section(section_nr);
- mem_blk = find_memory_block(mem_sect);
+ mem_blk = find_memory_block_hinted(mem_sect, mem_blk);
ret = register_mem_sect_under_node(mem_blk, nid);
if (!err)
err = ret;
/* discard ref obtained in find_memory_block() */
- kobject_put(&mem_blk->sysdev.kobj);
}
+
+ if (mem_blk)
+ kobject_put(&mem_blk->sysdev.kobj);
return err;
}
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [Patch 3/3] Convert link_mem_sections to use find_memory_block_hinted.
2010-09-29 19:00 ` [Patch 3/3] Convert link_mem_sections to use find_memory_block_hinted Robin Holt
@ 2010-09-30 2:01 ` KAMEZAWA Hiroyuki
2010-10-05 23:18 ` patch "driver core: Convert link_mem_sections to use find_memory_block_hinted." added to gregkh-2.6 tree gregkh
1 sibling, 0 replies; 10+ messages in thread
From: KAMEZAWA Hiroyuki @ 2010-09-30 2:01 UTC (permalink / raw)
To: Robin Holt
Cc: lkml, Gary Hade, Badari Pulavarty, Ingo Molnar,
Greg Kroah-Hartman, Dave Hansen, Matt Tolentino, Robert P. J. Day
On Wed, 29 Sep 2010 14:00:56 -0500
Robin Holt <holt@sgi.com> wrote:
>
> Modify link_mem_sections() to pass in the previous mem_block as a hint to
> locating the next mem_block. Since they are typically added in order this
> results in a massive saving in time during boot of a very large system.
> For example, on a 16TB x86_64 machine, it reduced the total time spent
> linking all node's memory sections from 1 hour, 27 minutes to 46 seconds.
>
> Signed-off-by: Robin Holt <holt@sgi.com>
> To: Gary Hade <garyhade@us.ibm.com>
> To: Badari Pulavarty <pbadari@us.ibm.com>
> To: Ingo Molnar <mingo@elte.hu>
> Cc: lkml <linux-kernel@vger.kernel.org>
>
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
^ permalink raw reply [flat|nested] 10+ messages in thread
* patch "driver core: Convert link_mem_sections to use find_memory_block_hinted." added to gregkh-2.6 tree
2010-09-29 19:00 ` [Patch 3/3] Convert link_mem_sections to use find_memory_block_hinted Robin Holt
2010-09-30 2:01 ` KAMEZAWA Hiroyuki
@ 2010-10-05 23:18 ` gregkh
1 sibling, 0 replies; 10+ messages in thread
From: gregkh @ 2010-10-05 23:18 UTC (permalink / raw)
To: holt, garyhade, gregkh, haveblue, kamezawa.hiroyu, linux-kernel,
matthew.e.tolentino, mingo, pbadari, rpjday
This is a note to let you know that I've just added the patch titled
driver core: Convert link_mem_sections to use find_memory_block_hinted.
to my gregkh-2.6 tree which can be found in directory form at:
http://www.kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/patches/
and in git form at:
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/patches.git
The filename of this patch is:
driver-core-convert-link_mem_sections-to-use-find_memory_block_hinted.patch
The patch will show up in the next release of the linux-next tree
(usually sometime within the next 24 hours during the week.)
If this patch meets the merge guidelines for a bugfix, it should be
merged into Linus's tree before the next major kernel release.
If not, it will be merged into Linus's tree during the next merge window.
Either way, you will probably be copied on the patch when it gets sent
to Linus for merging so that others can see what is happening in kernel
development.
If you have any questions about this process, please let me know.
>From holt@sgi.com Tue Oct 5 15:51:00 2010
Message-Id: <20100929190115.766603780@gulag1.americas.sgi.com>
Date: Wed, 29 Sep 2010 14:00:56 -0500
From: Robin Holt <holt@sgi.com>
To: lkml <linux-kernel@vger.kernel.org>,
Gary Hade <garyhade@us.ibm.com>,
Badari Pulavarty <pbadari@us.ibm.com>, Ingo Molnar <mingo@elte.hu>
Cc: Greg Kroah-Hartman <gregkh@suse.de>,
Dave Hansen <haveblue@us.ibm.com>,
Matt Tolentino <matthew.e.tolentino@intel.com>,
"Robert P. J. Day" <rpjday@crashcourse.ca>
Subject: driver core: Convert link_mem_sections to use find_memory_block_hinted.
Modify link_mem_sections() to pass in the previous mem_block as a hint to
locating the next mem_block. Since they are typically added in order this
results in a massive saving in time during boot of a very large system.
For example, on a 16TB x86_64 machine, it reduced the total time spent
linking all node's memory sections from 1 hour, 27 minutes to 46 seconds.
Signed-off-by: Robin Holt <holt@sgi.com>
To: Gary Hade <garyhade@us.ibm.com>
To: Badari Pulavarty <pbadari@us.ibm.com>
To: Ingo Molnar <mingo@elte.hu>
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/base/node.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -409,25 +409,27 @@ static int link_mem_sections(int nid)
unsigned long start_pfn = NODE_DATA(nid)->node_start_pfn;
unsigned long end_pfn = start_pfn + NODE_DATA(nid)->node_spanned_pages;
unsigned long pfn;
+ struct memory_block *mem_blk = NULL;
int err = 0;
for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) {
unsigned long section_nr = pfn_to_section_nr(pfn);
struct mem_section *mem_sect;
- struct memory_block *mem_blk;
int ret;
if (!present_section_nr(section_nr))
continue;
mem_sect = __nr_to_section(section_nr);
- mem_blk = find_memory_block(mem_sect);
+ mem_blk = find_memory_block_hinted(mem_sect, mem_blk);
ret = register_mem_sect_under_node(mem_blk, nid);
if (!err)
err = ret;
/* discard ref obtained in find_memory_block() */
- kobject_put(&mem_blk->sysdev.kobj);
}
+
+ if (mem_blk)
+ kobject_put(&mem_blk->sysdev.kobj);
return err;
}
^ permalink raw reply [flat|nested] 10+ messages in thread