Re: [PATCH RFD] alternative kobject release wait mechanism

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 18 Apr 2007 10:53:55 -0400 (EDT),
Alan Stern <[email protected]> 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 [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux