'why struct cdev has kobject member?
It's strange that struct cdev
has struct kobject
member, do any body knows the reason?
Solution 1:[1]
When kobjects are embedded inside other structures, the structures receive the standardized functions that a kobject provides. Most importantly, the structure's embedded kobject now enables the structure to become part of an object hierarchy. For example the cdev
structure is presentable in an object hierarchy via the parent pointer cdev->kobj.parent
and the list cdev->kobj.entry
Solution 2:[2]
Sysfs
is a Virtual filesystem that describes the devices available to the system in hierarchical pattern. This is done by using struct kobj
.
struct kobject {
char *k_name;
char name[KOBJ_NAME_LEN];
struct kref kref;
struct list_head entry;
struct kobject *parent;
struct kset *kset;
struct kobj_type *ktype;
struct dentry *dentry;
};
For any driver kobj is required to export the device attributes to sysfs
if we consider like i2c_client
spi_device
(spi client). we have kobj inside member struct dev
to export the driver attributes to the user space virtual filesystem(Sysfs
). The Kobj
structure members handles all the operations including referring to the device numbers(major/minor) and file operations involved for open, read/write,close etc... of device.
In your case cdev_init
& cdev_add
will internally uses kobj to do the above operation.
Solution 3:[3]
There are two reasons:
- for reference counting, which is offered by
kref
internally.
static struct kobject *cdev_get(struct cdev *p)
{
struct module *owner = p->owner;
struct kobject *kobj;
if (owner && !try_module_get(owner))
return NULL;
kobj = kobject_get_unless_zero(&p->kobj);
if (!kobj)
module_put(owner);
return kobj;
}
void cdev_put(struct cdev *p)
{
if (p) {
struct module *owner = p->owner;
kobject_put(&p->kobj);
module_put(owner);
}
}
- for release, that's also why
kref
is not enough(kref
doesn't have a release hook).
static void cdev_default_release(struct kobject *kobj)
{
struct cdev *p = container_of(kobj, struct cdev, kobj);
struct kobject *parent = kobj->parent;
cdev_purge(p);
kobject_put(parent);
}
static void cdev_dynamic_release(struct kobject *kobj)
{
struct cdev *p = container_of(kobj, struct cdev, kobj);
struct kobject *parent = kobj->parent;
cdev_purge(p);
kfree(p);
kobject_put(parent);
}
static struct kobj_type ktype_cdev_default = {
.release = cdev_default_release,
};
static struct kobj_type ktype_cdev_dynamic = {
.release = cdev_dynamic_release,
};
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | microMolvi |
Solution 2 | kzs |
Solution 3 |