Commit eee031649707db3c9920d9498f8d03819b74fc23

Authored by Jeff Mahoney
Committed by Greg Kroah-Hartman
1 parent 1296fc02c2

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_ */
... ... @@ -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.