Re: [PATCH RFD] alternative kobject release wait mechanism
- From: Cornelia Huck <cornelia.huck@xxxxxxxxxx>
- Date: Wed, 18 Apr 2007 17:26:26 +0200
On Wed, 18 Apr 2007 10:53:55 -0400 (EDT),
Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> wrote:
Many drivers, especially those for hot-pluggable buses, register and
unregister devices dynamically. These events can occur in time-critical
situations, where the driver cannot afford to wait for all the references
to be dropped when unregistering a device. It's okay to wait in a module
exit routine, but to make things work the routine would have to wait for
references to _all_ unregistered objects to go away, not just the
references for the objects it unregisters at exit time.
Uh, yes, didn't think of that. I'd even say that's the majority of
devices allocated in a driver.
BTW, Cornelia, there's a small problem with your patch set. You have
kobject_init() try to grab a reference to kobj->owner, but it's quite
possible for kobj->owner to contain uninitialized garbage since the rest
of the kernel is still unaware of its existence. There's a patch below to
fix things up. I've got a second patch which makes device_initialize()
pass an owner to the embedded kobject, but I want to try it out a little
before posting it. :-)
I was relying on the object being zeroed after allocation (and the
caller of kobject_initialize already setting ->owner), but passing an
owner via the initializing routine sounds saner. Thanks for looking at
that.
Index: usb-2.6/include/linux/kobject.h
===================================================================
--- usb-2.6.orig/include/linux/kobject.h
+++ usb-2.6/include/linux/kobject.h
@@ -71,7 +71,8 @@ static inline const char * kobject_name(
return kobj->k_name;
}
-extern void kobject_init(struct kobject *);
+extern void kobject_init_owner(struct kobject *, struct module *owner);
+#define kobject_init(kobj) kobject_init_owner(kobj, THIS_MODULE)
extern void kobject_cleanup(struct kobject *);
extern int __must_check kobject_add(struct kobject *);
@@ -84,7 +85,9 @@ extern int __must_check kobject_shadow_r
const char *new_name);
extern int __must_check kobject_move(struct kobject *, struct kobject *);
-extern int __must_check kobject_register(struct kobject *);
+extern int __must_check kobject_register_owner(struct kobject *,
+ struct module *owner);
+#define kobject_register(kobj) kobject_register_owner(kobj, THIS_MODULE)
extern void kobject_unregister(struct kobject *);
extern struct kobject * kobject_get(struct kobject *);
Index: usb-2.6/lib/kobject.c
===================================================================
--- usb-2.6.orig/lib/kobject.c
+++ usb-2.6/lib/kobject.c
@@ -164,10 +164,11 @@ static void verify_dynamic_kobject_alloc
#endif
/**
- * kobject_init - initialize object.
+ * kobject_init_onwer - initialize object.
* @kobj: object in question.
+ * @owner: module owning @kobj.
*/
-void kobject_init(struct kobject * kobj)
+void kobject_init_owner(struct kobject * kobj, struct module *owner)
{
if (!kobj)
return;
@@ -178,6 +179,7 @@ void kobject_init(struct kobject * kobj)
init_waitqueue_head(&kobj->poll);
kobj->kset = kset_get(kobj->kset);
/* Attempt to grab reference of owning module's kobject. */
+ kobj->owner = owner;
mod_kobject_get(kobj->owner);
}
@@ -272,15 +274,16 @@ int kobject_add(struct kobject * kobj)
/**
- * kobject_register - initialize and add an object.
+ * kobject_register_owner - initialize and add an object.
* @kobj: object in question.
+ * @owner: module owning @kobj.
*/
-int kobject_register(struct kobject * kobj)
+int kobject_register_owner(struct kobject * kobj, struct module *owner)
{
int error = -EINVAL;
if (kobj) {
- kobject_init(kobj);
+ kobject_init_owner(kobj, owner);
error = kobject_add(kobj);
if (!error)
kobject_uevent(kobj, KOBJ_ADD);
@@ -750,8 +753,8 @@ void subsys_remove_file(struct subsystem
}
#endif /* 0 */
-EXPORT_SYMBOL(kobject_init);
-EXPORT_SYMBOL(kobject_register);
+EXPORT_SYMBOL(kobject_init_owner);
+EXPORT_SYMBOL(kobject_register_owner);
EXPORT_SYMBOL(kobject_unregister);
EXPORT_SYMBOL(kobject_get);
EXPORT_SYMBOL(kobject_put);
Hm, this means we always have an owner (until we explicitely call
kobject_{init,register}_owner(kobj, NULL)) - which may be unneeded in
some cases. But better to err on the safe side, I suppose.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
- References:
- [PATCH RFD] alternative kobject release wait mechanism
- From: Tejun Heo
- Re: [PATCH RFD] alternative kobject release wait mechanism
- From: Alan Stern
- [PATCH RFD] alternative kobject release wait mechanism
- Prev by Date: Re: [Patch -mm 3/3] RFC: Introduce kobject->owner for refcounting.
- Next by Date: Re: Loud "pop" coming from hard drive on reboot
- Previous by thread: Re: [PATCH RFD] alternative kobject release wait mechanism
- Next by thread: Re: [PATCH RFD] alternative kobject release wait mechanism
- Index(es):
Relevant Pages
|