lkml.org 
[lkml]   [2006]   [Mar]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Subject[Bug? Report] kref problem
    From
    Date
    Hello Greg,

    I've hit on a kref problem Please, glance at the attached test module.

    The idea of the test is to create 2 kobjects (a and b), create dir A
    with kobject A, and dir B with kobject B, so that A is B's parent. E.g.,
    we'll have /sys/A/B.

    I see the following output of the test:

    a inited, kref 1
    b inited, kref 1
    dir A created, A kref 1, B kref 1
    dir B created, A kref 1, B kref 1
    b_release
    a_release
    kobj B put, A kref 0, B kref 0
    kobj A put, A kref -1, B kref 0


    So what I don't like is this "A kref -1". Why when I remove directory B,
    kobj a is released? For me it looks like a bug.

    The kernel is 2.6.16-rc6.

    Thanks.

    --
    Best Regards,
    Artem B. Bityuckiy,
    St.-Petersburg, Russia.
    #include <linux/kernel.h>
    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/kobject.h>
    #include <linux/stat.h>

    static void a_release(struct kobject *kobj);

    static struct kobj_type a_ktype = {
    .release = a_release
    };

    static void b_release(struct kobject *kobj);

    static struct kobj_type b_ktype = {
    .release = b_release
    };

    struct my_obj_a
    {
    struct kobject kobj;
    } a;

    struct my_obj_b
    {
    struct kobject kobj;
    } b;

    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);
    }

    static void b_release(struct kobject *kobj)
    {
    struct my_obj_b *b;

    printk("%s\n", __FUNCTION__);
    b = container_of(kobj, struct my_obj_b, kobj);
    sysfs_remove_dir(&b->kobj);
    }

    static __exit void test_exit(void)
    {
    }
    module_exit(test_exit);

    MODULE_VERSION("1");
    MODULE_DESCRIPTION("kref test");
    MODULE_AUTHOR("Artem B. Bityutskiy");
    MODULE_LICENSE("GPL");
    \
     
     \ /
      Last update: 2006-03-16 12:43    [W:0.024 / U:0.220 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site