I have a platform driver which creates a driver that can be accessed from multiple threads.
I added an IOCTL command that set an atomic_t
flag. The desired behavior is:
- When the flag is equal to zero, unloading the module is allowed.
- When the flag is set to one, the module cannot be unloaded (when calling
rmmod my_module
).
Using the approach bellow, the module says returning a non-zero flag. will be ignored.
int driver_remove(struct platform_device *_pdev)
{
int reg = 0;
reg = atomic_read(&_pdev->my_atomic_lock);
if (reg) {
pr_error("Cannot remove the module as it is still being used somewhere.");
return -EBUSY;
}
// REST OF THE REMOVAL ....
return 0;
}
static struct platform_driver my_driver = {
.probe = driver_probe,
.remove = driver_remove,
.driver = {
.name = MODULE_NAME,
.owner = THIS_MODULE,
.of_match_table = match_types,
},
};
module_platform_driver(my_driver);
I also tried with a spin lock that is only set in a separate function to block the behavior. Then an unblocking function release the spin lock when the operations are finished and the module can be unloaded. This doesn't work despite the fact that I checked and the spin lock was blocked.
int driver_remove(struct platform_device *_pdev)
{
// Be certain that no one has blocked the device (to prevent killing a running function)
spin_lock(&_dev->_my_lock);
// REST OF THE REMOVAL ....
return 0;
}
static struct platform_driver my_driver = {
.probe = driver_probe,
.remove = driver_remove,
.driver = {
.name = MODULE_NAME,
.owner = THIS_MODULE,
.of_match_table = match_types,
},
};
module_platform_driver(my_driver);
What did I do wrong?