diff options
author | Robin Holt <holt@sgi.com> | 2010-09-29 15:00:54 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-10-22 13:16:44 -0400 |
commit | c25d1dfbd403209025df41a737f82ce8f43d93f5 (patch) | |
tree | 35110a432101ff146bae3656137d9ba6f37b38fd /lib/kobject.c | |
parent | ead454feb6cbfe0fa6a1eeb30aa9abc338dacf62 (diff) |
kobject: Introduce kset_find_obj_hinted.
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>
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'lib/kobject.c')
-rw-r--r-- | lib/kobject.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/lib/kobject.c b/lib/kobject.c index f07c57252e82..82dc34c095c2 100644 --- a/lib/kobject.c +++ b/lib/kobject.c | |||
@@ -746,17 +746,56 @@ void kset_unregister(struct kset *k) | |||
746 | */ | 746 | */ |
747 | struct kobject *kset_find_obj(struct kset *kset, const char *name) | 747 | struct kobject *kset_find_obj(struct kset *kset, const char *name) |
748 | { | 748 | { |
749 | return kset_find_obj_hinted(kset, name, NULL); | ||
750 | } | ||
751 | |||
752 | /** | ||
753 | * kset_find_obj_hinted - search for object in kset given a predecessor hint. | ||
754 | * @kset: kset we're looking in. | ||
755 | * @name: object's name. | ||
756 | * @hint: hint to possible object's predecessor. | ||
757 | * | ||
758 | * Check the hint's next object and if it is a match return it directly, | ||
759 | * otherwise, fall back to the behavior of kset_find_obj(). Either way | ||
760 | * a reference for the returned object is held and the reference on the | ||
761 | * hinted object is released. | ||
762 | */ | ||
763 | struct kobject *kset_find_obj_hinted(struct kset *kset, const char *name, | ||
764 | struct kobject *hint) | ||
765 | { | ||
749 | struct kobject *k; | 766 | struct kobject *k; |
750 | struct kobject *ret = NULL; | 767 | struct kobject *ret = NULL; |
751 | 768 | ||
752 | spin_lock(&kset->list_lock); | 769 | spin_lock(&kset->list_lock); |
770 | |||
771 | if (!hint) | ||
772 | goto slow_search; | ||
773 | |||
774 | /* end of list detection */ | ||
775 | if (hint->entry.next == kset->list.next) | ||
776 | goto slow_search; | ||
777 | |||
778 | k = container_of(hint->entry.next, struct kobject, entry); | ||
779 | if (!kobject_name(k) || strcmp(kobject_name(k), name)) | ||
780 | goto slow_search; | ||
781 | |||
782 | ret = kobject_get(k); | ||
783 | goto unlock_exit; | ||
784 | |||
785 | slow_search: | ||
753 | list_for_each_entry(k, &kset->list, entry) { | 786 | list_for_each_entry(k, &kset->list, entry) { |
754 | if (kobject_name(k) && !strcmp(kobject_name(k), name)) { | 787 | if (kobject_name(k) && !strcmp(kobject_name(k), name)) { |
755 | ret = kobject_get(k); | 788 | ret = kobject_get(k); |
756 | break; | 789 | break; |
757 | } | 790 | } |
758 | } | 791 | } |
792 | |||
793 | unlock_exit: | ||
759 | spin_unlock(&kset->list_lock); | 794 | spin_unlock(&kset->list_lock); |
795 | |||
796 | if (hint) | ||
797 | kobject_put(hint); | ||
798 | |||
760 | return ret; | 799 | return ret; |
761 | } | 800 | } |
762 | 801 | ||