Re: [Bug? Report] kref problem

Greg KH
2006-03-16T16:53:29Z

On Thu, Mar 16, 2006 at 02:41:19PM +0300, Artem B. Bityutskiy wrote:
> struct my_obj_a
> {
> struct kobject kobj;
> } a;
>
> struct my_obj_b
> {
> struct kobject kobj;
> } b;

Don't statically create kobjects, it's not nice. But the real problem
is below...

> static __init int test_init(void)
> {
> int err;
>
> kobject_init(&a.kobj);
> a.kobj.ktype = &a_ktype;
> err = kobject_set_name(&a.kobj, "A");
> if (err)
> return err;
> printk("a inited, kref %d\n", atomic_read(&a.kobj.kref.refcount));
>
> kobject_init(&b.kobj);
> b.kobj.ktype = &b_ktype;
> b.kobj.parent = &a.kobj;
> err = kobject_set_name(&b.kobj, "B");
> if (err)
> goto out_a;
> printk("b inited, kref %d\n", atomic_read(&b.kobj.kref.refcount));
>
> err = sysfs_create_dir(&a.kobj);
> if (err)
> goto out_b;
> printk("dir A created, A kref %d, B kref %d\n",
> atomic_read(&a.kobj.kref.refcount), atomic_read(&b.kobj.kref.refcount));
>
> err = sysfs_create_dir(&b.kobj);
> if (err)
> goto out_a_dir;
> printk("dir B created, A kref %d, B kref %d\n",
> atomic_read(&a.kobj.kref.refcount), atomic_read(&b.kobj.kref.refcount));
>
> kobject_put(&b.kobj);
> printk("kobj B put, A kref %d, B kref %d\n",
> atomic_read(&a.kobj.kref.refcount), atomic_read(&b.kobj.kref.refcount));
>
> kobject_put(&a.kobj);
> printk("kobj A put, A kref %d, B kref %d\n",
> atomic_read(&a.kobj.kref.refcount), atomic_read(&b.kobj.kref.refcount));
>
> return 0;
>
> out_a_dir:
> sysfs_remove_dir(&a.kobj);
> out_b:
> kobject_put(&b.kobj);
> out_a:
> kobject_put(&a.kobj);
> return err;
> }
> module_init(test_init);
>
> static void a_release(struct kobject *kobj)
> {
> struct my_obj_a *a;
>
> printk("%s\n", __FUNCTION__);
> a = container_of(kobj, struct my_obj_a, kobj);
> sysfs_remove_dir(&a->kobj);

Woah, don't do that here, the kobject core already does this. A release
function is for you to release the memory you have created with this
kobject, not to mess with sysfs.

So, don't do this and everything should work just fine.

thanks,

greg k-h