diff --git a/kobject-example.c b/kobject-example.c index bb904cf..477ab9b 100644 --- a/kobject-example.c +++ b/kobject-example.c @@ -3,82 +3,72 @@ #include #include #include +#include -static int foo; -static int baz; -static int bar; +static struct kobject *example_kobj; +static struct percpu_ref global_ref; -static ssize_t foo_show(struct kobject *kobj, struct kobj_attribute *attr, +static void global_ref_release(struct percpu_ref *) +{ + printk("%s %d\n", __func__, __LINE__); +} + +static ssize_t is_percpu_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - return sysfs_emit(buf, "%d\n", foo); + unsigned long __percpu *percpu_count; + return sysfs_emit(buf, "%d\n", __ref_is_percpu(&global_ref, &percpu_count)); } +static struct kobj_attribute is_percpu_attribute = __ATTR_RO(is_percpu); -static ssize_t foo_store(struct kobject *kobj, struct kobj_attribute *attr, - const char *buf, size_t count) +static ssize_t is_dying_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) { - int ret; - - ret = kstrtoint(buf, 10, &foo); - if (ret < 0) - return ret; - - return count; + return sysfs_emit(buf, "%d\n", percpu_ref_is_dying(&global_ref)); } +static struct kobj_attribute is_dying_attribute = __ATTR_RO(is_dying); -static struct kobj_attribute foo_attribute = - __ATTR(foo, 0664, foo_show, foo_store); - -static ssize_t b_show(struct kobject *kobj, struct kobj_attribute *attr, - char *buf) +static ssize_t is_zero_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) { - int var; - - if (strcmp(attr->attr.name, "baz") == 0) - var = baz; - else - var = bar; - return sysfs_emit(buf, "%d\n", var); + return sysfs_emit(buf, "%d\n", percpu_ref_is_zero(&global_ref)); } +static struct kobj_attribute is_zero_attribute = __ATTR_RO(is_zero); -static ssize_t b_store(struct kobject *kobj, struct kobj_attribute *attr, - const char *buf, size_t count) +static ssize_t kill_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) { - int var, ret; - - ret = kstrtoint(buf, 10, &var); - if (ret < 0) - return ret; - - if (strcmp(attr->attr.name, "baz") == 0) - baz = var; - else - bar = var; - return count; + percpu_ref_kill(&global_ref); + return count; } +static struct kobj_attribute kill_attribute = __ATTR_WO(kill); -static struct kobj_attribute baz_attribute = - __ATTR(baz, 0664, b_show, b_store); -static struct kobj_attribute bar_attribute = - __ATTR(bar, 0664, b_show, b_store); +static ssize_t resurrect_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + percpu_ref_resurrect(&global_ref); + return count; +} +static struct kobj_attribute resurrect_attribute = __ATTR_WO(resurrect); static struct attribute *attrs[] = { - &foo_attribute.attr, - &baz_attribute.attr, - &bar_attribute.attr, - NULL, /* need to NULL terminate the list of attributes */ + &is_dying_attribute.attr, + &is_zero_attribute.attr, + &is_percpu_attribute.attr, + &kill_attribute.attr, + &resurrect_attribute.attr, + NULL, }; - static struct attribute_group attr_group = { .attrs = attrs, }; -static struct kobject *example_kobj; - static int __init example_init(void) { int retval; + retval = percpu_ref_init(&global_ref, global_ref_release, PERCPU_REF_INIT_ATOMIC, GFP_KERNEL); + example_kobj = kobject_create_and_add("kobject_example", kernel_kobj); if (!example_kobj) return -ENOMEM;