0

I am working on an embedded Linux (kernel-5.10.24).
I hit an error when I tried to unload RTC driver module, it was:

# lsmod
rtc_test 6490 1 - Live 0xc02f5000
# modprobe -r rtc_test
modprobe: remove 'rtc_test': Resource temporarily unavailable

I think it is from the module->refcnt is 1, but I don't know why the refcnt is 1. What I got here is the calling trace to increase the reference count, as follows,

[   34.016653] Call Trace:
[   34.019181] [<80020318>] show_stack+0x94/0x12c
[   34.023772] [<808536e0>] dump_stack+0xac/0xe8
[   34.028271] [<800d8f30>] try_module_get.part.65+0xf8/0x100
[   34.033938] [<800c7040>] alarmtimer_rtc_add_device+0x13c/0x188
[   34.039958] [<80380370>] device_add+0x578/0x810
[   34.044631] [<80141c58>] cdev_device_add+0x54/0xb0
[   34.049575] [<8048750c>] __rtc_register_device+0x108/0x3c8
[   34.055234] [<80488000>] devm_rtc_device_register+0x3c/0x5c
[   34.060997] [<c02f5914>] test_rtc_probe+0x190/0x5d4 [rtc_test]
[   34.067561] [<803886e0>] platform_drv_probe+0x58/0xbc
[   34.072777] [<80385a98>] really_probe+0x14c/0x578
[   34.077629] [<803860e4>] driver_probe_device+0x80/0x25c
[   34.083022] [<8038659c>] device_driver_attach+0x7c/0xa8
[   34.088412] [<803866ac>] __driver_attach+0xe4/0x188
[   34.093448] [<803835fc>] bus_for_each_dev+0x78/0xd0
[   34.098480] [<80384b50>] bus_add_driver+0x1a4/0x230
[   34.103514] [<80387080>] driver_register+0x84/0x154
[   34.108544] [<80388e50>] __platform_driver_probe+0x74/0x150
[   34.114294] [<800106d8>] do_one_initcall+0x50/0x1d8
[   34.119328] [<80852d48>] do_init_module+0x70/0x208
[   34.124272] [<800dc3c4>] load_module+0x219c/0x259c
[   34.129214] [<800dca30>] sys_finit_module+0xd4/0x130
[   34.134335] [<8002b798>] syscall_common+0x34/0x58

The basic logics of the rtc_test.ko is as follows,

int test_rtc_probe(....)
{
devm_clk_get(...);
platform_get_irq(...);
platform_get_resource(pdev, IORESOURCE_MEM, 0);
request_mem_region(....);
ioremap(...);
devm_rtc_device_register(...);
request_irq(...);
}

static struct platform_driver test_rtc_driver = {
    .driver = {
        .name = "rtc_test",
        .of_match_table = dummy_rtc_of_ids,
    },
    .remove     = __exit_p(test_rtc_remove),
    .suspend    = NULL,
    .resume     = NULL,
};

The devm_rtc_device_register() triggered above calling stack, which increased the module->refcnt (it added as alarmtimer device).

The increment of refcnt failed module unloading.
I checked other RTC drivers in Linux kernel, I did NOT find any big difference which can help solve the problem.

Testing rtc_test2.ko

I tried another RTC kernel module, https://codebrowser.dev/linux/linux/drivers/rtc/rtc-test.c.html
And I found its reference count is 0 from lsmod as follows,

# lsmod
rtc_test2 2159 0 - Live 0xc0191000 (O)

And sysfs shows the followings,

# ls /sys/class/rtc/rtc0/
date           hctosys        power          time
dev            max_user_freq  since_epoch    uevent
device         name           subsystem

But I got the difference of sysfs for the first module as follows,

# ls /sys/class/rtc/rtc1/
alarmtimer.0.auto  hctosys            since_epoch        wakealarm
date               max_user_freq      subsystem
dev                name               time
device             power              uevent

There are 2 more items for rtc1 (the module unable to be unloaded). So suspect the increasing of refcnt is from alarmtimer, I am verifying it.

I checked the codes, and did NOT find the registering of alarmtimer, how is it registered. By using dump_stack(), I can find that devm_rtc_device_register() triggers alarmtimer_rtc_add_device() which increases the refcnt.
If I can disable the adding of alarmtimer the module might be unloaded.?

wangt13
  • 959
  • 7
  • 17

0 Answers0