Issue
In Linux kernel modules, two different approaches can be followed when creating a struct cdev
, as suggested in this site and in this answer:
First approach, cdev_alloc()
struct cdev *my_dev;
...
static int __init example_module_init(void) {
...
my_dev = cdev_alloc();
if (my_dev != NULL) {
my_dev->ops = &my_fops; /* The file_operations structure */
my_dev->owner = THIS_MODULE;
}
else
...
}
Second approach, cdev_init()
static struct cdev my_cdev;
...
static int __init example_module_init(void) {
...
cdev_init(&my_cdev, my_fops);
my_cdev.owner = THIS_MODULE;
...
}
(assuming that my_fops
is a pointer to an initialized struct file_operations
).
- Is the first approach deprecated, or still in use?
- Can
cdev_init()
be used also in the first approach, withcdev_alloc()
? If no, why?
The second question is also in a comment in the linked answer.
Solution
Can
cdev_init()
be used also in the first approach, withcdev_alloc()
?
No, cdev_init
shouldn't be used for a character device, allocated with cdev_alloc
.
At some extent, cdev_alloc
is equivalent to kmalloc
plus cdev_init
. So calling cdev_init
for a character device, created with cdev_alloc
, has no sense.
Moreover, a character device allocated with cdev_alloc
contains a hint that the device should be deallocated when no longer be used. Calling cdev_init
for that device will clear that hint, so you will get a memory leakage.
Selection between cdev_init
and cdev_alloc
depends on a lifetime you want a character device to have.
Usually, one wants lifetime of a character device to be the same as lifetime of the module. In that case:
- Define a static or global variable of type
struct cdev
. - Create the character device in the module's init function using
cdev_init
. - Destroy the character device in the module's exit function using
cdev_del
. - Make sure that file operations for the character device have
.owner
field set toTHIS_MODULE
.
In complex cases, one wants to create a character device at specific point after module's initializing. E.g. a module could provide a driver for some hardware, and a character device should be bound with that hardware. In that case the character device cannot be created in the module's init function (because a hardware is not detected yet), and, more important, the character device cannot be destroyed in the module's exit function. In that case:
- Define a field inside a structure, describing a hardware, of pointer type
struct cdev*
. - Create the character device with
cdev_alloc
in the function which creates (probes) a hardware. - Destroy the character device with
cdev_del
in the function which destroys (disconnects) a hardware.
In the first case cdev_del
is called at the time, when the character device is not used by a user. This guarantee is provided by THIS_MODULE
in the file operations: a module cannot be unloaded if a file, corresponded to the character device, is opened by a user.
In the second case there is no such guarantee (because cdev_del
is called NOT in the module's exit function). So, at the time when cdev_del
returns, a character device can be still in use by a user. And here cdev_alloc
really matters: deallocation of the character device will be deferred until a user closes all file descriptors associated with the character device. Such behavior cannot be obtained without cdev_alloc
.
Answered By - Tsyvarev