2013-09-11 17:00:38

by Jeff Mahoney

[permalink] [raw]
Subject: [PATCH] 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 <[email protected]>
---
include/linux/kobj_completion.h | 18 ++++++++++++++
lib/kobject.c | 50 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 68 insertions(+)

--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/include/linux/kobj_completion.h 2013-09-10 12:58:03.530554144 -0400
@@ -0,0 +1,18 @@
+#ifndef _KOBJ_COMPLETION_H_
+#define _KOBJ_COMPLETION_H_
+
+#include <linux/kobject.h>
+#include <linux/completion.h>
+
+struct kobj_completion {
+ struct kobject kc_kobj;
+ struct completion kc_unregister;
+};
+
+#define kobj_to_kobj_completion(kobj) \
+ container_of(kobj, struct kobj_completion, kc_kobj)
+
+void kobj_completion_init(struct kobj_completion *kc, struct kobj_type *ktype);
+void kobj_completion_release(struct kobject *kobj);
+void kobj_completion_del_and_wait(struct kobj_completion *kc);
+#endif /* _KOBJ_COMPLETION_H_ */
--- a/lib/kobject.c 2013-09-10 12:57:54.198666613 -0400
+++ b/lib/kobject.c 2013-09-10 15:22:15.122724060 -0400
@@ -13,6 +13,7 @@
*/

#include <linux/kobject.h>
+#include <linux/kobj_completion.h>
#include <linux/string.h>
#include <linux/export.h>
#include <linux/stat.h>
@@ -711,6 +712,55 @@ const struct sysfs_ops kobj_sysfs_ops =
};

/**
+ * kobj_completion_init - initialize a kobj_completion object.
+ * @kc: kobj_completion
+ * @ktype: type of kobject to initialize
+ *
+ * kobj_completion structures can be embedded within structures with different
+ * lifetime rules. During the release of the enclosing object, we can
+ * wait on the release of the kobject so that we don't free it while it's
+ * still busy.
+ */
+void kobj_completion_init(struct kobj_completion *kc, struct kobj_type *ktype)
+{
+ init_completion(&kc->kc_unregister);
+ kobject_init(&kc->kc_kobj, ktype);
+}
+EXPORT_SYMBOL_GPL(kobj_completion_init);
+
+/**
+ * kobj_completion_release - release a kobj_completion object
+ * @kobj: kobject embedded in kobj_completion
+ *
+ * Used with kobject_release to notify waiters that the kobject has been
+ * released.
+ */
+void kobj_completion_release(struct kobject *kobj)
+{
+ struct kobj_completion *kc = kobj_to_kobj_completion(kobj);
+ complete(&kc->kc_unregister);
+}
+EXPORT_SYMBOL_GPL(kobj_completion_release);
+
+/**
+ * kobj_completion_del_and_wait - release the kobject and wait for it
+ * @kc: kobj_completion object to release
+ *
+ * Delete the kobject from sysfs and drop the reference count. Then wait
+ * until any other outstanding references are also dropped. This routine
+ * is only necessary once other references may have been taken on the
+ * kobject. Typically this happens when the kobject has been published
+ * to sysfs via kobject_add.
+ */
+void kobj_completion_del_and_wait(struct kobj_completion *kc)
+{
+ kobject_del(&kc->kc_kobj);
+ kobject_put(&kc->kc_kobj);
+ wait_for_completion(&kc->kc_unregister);
+}
+EXPORT_SYMBOL_GPL(kobj_completion_del_and_wait);
+
+/**
* kset_register - initialize and add a kset.
* @k: kset.
*/


2013-09-11 17:15:15

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] kobject: introduce kobj_completion

On Wed, Sep 11, 2013 at 01:00:30PM -0400, Jeff Mahoney wrote:
> 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 <[email protected]>
> ---
> include/linux/kobj_completion.h | 18 ++++++++++++++

Does this really need a new .h file, or can we just cram it into
kobject.h? It's only 13 more lines to add to that file.

thanks,

greg k-h

2013-09-11 17:28:19

by Al Viro

[permalink] [raw]
Subject: Re: [PATCH] kobject: introduce kobj_completion

On Wed, Sep 11, 2013 at 01:00:30PM -0400, Jeff Mahoney wrote:
> 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.

That's very easy to misuse, leading to deadlocks...

2013-09-11 18:35:08

by Jeff Mahoney

[permalink] [raw]
Subject: Re: [PATCH] kobject: introduce kobj_completion

On 9/11/13 1:28 PM, Al Viro wrote:
> On Wed, Sep 11, 2013 at 01:00:30PM -0400, Jeff Mahoney wrote:
>> 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.
>
> That's very easy to misuse, leading to deadlocks...

Misuse how? If you're using it any time other than shutting down an
object, you're shooting yourself in the foot.

-Jeff

--
Jeff Mahoney
SUSE Labs


Attachments:
signature.asc (841.00 B)
OpenPGP digital signature

2013-09-11 18:37:33

by Jeff Mahoney

[permalink] [raw]
Subject: Re: [PATCH] kobject: introduce kobj_completion

On 9/11/13 1:15 PM, Greg KH wrote:
> On Wed, Sep 11, 2013 at 01:00:30PM -0400, Jeff Mahoney wrote:
>> 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 <[email protected]>
>> ---
>> include/linux/kobj_completion.h | 18 ++++++++++++++
>
> Does this really need a new .h file, or can we just cram it into
> kobject.h? It's only 13 more lines to add to that file.

It doesn't need to be, but it avoids everywhere that already uses a
kobject having to include <linux/completion.h> indirectly.

-Jeff

--
Jeff Mahoney
SUSE Labs


Attachments:
signature.asc (841.00 B)
OpenPGP digital signature