Commit eee031649707db3c9920d9498f8d03819b74fc23
Committed by
Greg Kroah-Hartman
1 parent
1296fc02c2
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
kobject: introduce kobj_completion
A common way to handle kobject lifetimes in embedded in objects with different lifetime rules is to pair the kobject with a struct completion. This introduces a kobj_completion structure that can be used in place of the pairing, along with several convenience functions for initialization, release, and put-and-wait. Signed-off-by: Jeff Mahoney <jeffm@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Showing 2 changed files with 68 additions and 0 deletions Side-by-side Diff
include/linux/kobj_completion.h
1 | +#ifndef _KOBJ_COMPLETION_H_ | |
2 | +#define _KOBJ_COMPLETION_H_ | |
3 | + | |
4 | +#include <linux/kobject.h> | |
5 | +#include <linux/completion.h> | |
6 | + | |
7 | +struct kobj_completion { | |
8 | + struct kobject kc_kobj; | |
9 | + struct completion kc_unregister; | |
10 | +}; | |
11 | + | |
12 | +#define kobj_to_kobj_completion(kobj) \ | |
13 | + container_of(kobj, struct kobj_completion, kc_kobj) | |
14 | + | |
15 | +void kobj_completion_init(struct kobj_completion *kc, struct kobj_type *ktype); | |
16 | +void kobj_completion_release(struct kobject *kobj); | |
17 | +void kobj_completion_del_and_wait(struct kobj_completion *kc); | |
18 | +#endif /* _KOBJ_COMPLETION_H_ */ |
lib/kobject.c
... | ... | @@ -13,6 +13,7 @@ |
13 | 13 | */ |
14 | 14 | |
15 | 15 | #include <linux/kobject.h> |
16 | +#include <linux/kobj_completion.h> | |
16 | 17 | #include <linux/string.h> |
17 | 18 | #include <linux/export.h> |
18 | 19 | #include <linux/stat.h> |
... | ... | @@ -748,6 +749,55 @@ |
748 | 749 | .show = kobj_attr_show, |
749 | 750 | .store = kobj_attr_store, |
750 | 751 | }; |
752 | + | |
753 | +/** | |
754 | + * kobj_completion_init - initialize a kobj_completion object. | |
755 | + * @kc: kobj_completion | |
756 | + * @ktype: type of kobject to initialize | |
757 | + * | |
758 | + * kobj_completion structures can be embedded within structures with different | |
759 | + * lifetime rules. During the release of the enclosing object, we can | |
760 | + * wait on the release of the kobject so that we don't free it while it's | |
761 | + * still busy. | |
762 | + */ | |
763 | +void kobj_completion_init(struct kobj_completion *kc, struct kobj_type *ktype) | |
764 | +{ | |
765 | + init_completion(&kc->kc_unregister); | |
766 | + kobject_init(&kc->kc_kobj, ktype); | |
767 | +} | |
768 | +EXPORT_SYMBOL_GPL(kobj_completion_init); | |
769 | + | |
770 | +/** | |
771 | + * kobj_completion_release - release a kobj_completion object | |
772 | + * @kobj: kobject embedded in kobj_completion | |
773 | + * | |
774 | + * Used with kobject_release to notify waiters that the kobject has been | |
775 | + * released. | |
776 | + */ | |
777 | +void kobj_completion_release(struct kobject *kobj) | |
778 | +{ | |
779 | + struct kobj_completion *kc = kobj_to_kobj_completion(kobj); | |
780 | + complete(&kc->kc_unregister); | |
781 | +} | |
782 | +EXPORT_SYMBOL_GPL(kobj_completion_release); | |
783 | + | |
784 | +/** | |
785 | + * kobj_completion_del_and_wait - release the kobject and wait for it | |
786 | + * @kc: kobj_completion object to release | |
787 | + * | |
788 | + * Delete the kobject from sysfs and drop the reference count. Then wait | |
789 | + * until any other outstanding references are also dropped. This routine | |
790 | + * is only necessary once other references may have been taken on the | |
791 | + * kobject. Typically this happens when the kobject has been published | |
792 | + * to sysfs via kobject_add. | |
793 | + */ | |
794 | +void kobj_completion_del_and_wait(struct kobj_completion *kc) | |
795 | +{ | |
796 | + kobject_del(&kc->kc_kobj); | |
797 | + kobject_put(&kc->kc_kobj); | |
798 | + wait_for_completion(&kc->kc_unregister); | |
799 | +} | |
800 | +EXPORT_SYMBOL_GPL(kobj_completion_del_and_wait); | |
751 | 801 | |
752 | 802 | /** |
753 | 803 | * kset_register - initialize and add a kset. |