0

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?

0andriy
  • 4,183
  • 1
  • 24
  • 37
PMDP3
  • 35
  • 7
  • Instead of doing something hackish, just bump or drop the reference count of the respective device / driver / module (all these have three different reference counters and respective APIs). – 0andriy Jul 17 '23 at 22:32
  • This is a great suggestion. As I am a newbie in kernel development, I do not see how I can do that? I thought that all the mechanisms used to manage these counters were not directly usable on a platform driver... – PMDP3 Jul 19 '23 at 06:13
  • `module_get()` for the module itself, `get_device()` for the device instance you want to hold, for example. – 0andriy Jul 25 '23 at 18:22

0 Answers0