I create a kernel thread during the initialization of a kernel module like this:
static int __init module_init(module)
{
...
tdata = kmalloc(sizeof(*data));
if (!data) {
...
}
task = kthread_run(tfunc, tdata, "memtester");
if (!task) {
pr_err("memtester: Could not create new thread\n");
goto out_err
}
...
}
I unload the module like this:
static void __exit memtester_exit(void)
{
printk(KERN_INFO "memtester exiting");
if (task)
kthread_stop(task);
kfree(tdata);
}
and the thread function is like this:
int tfunc(void *data)
{
...
for (i = 0; i < some_limit; ++i) {
do_work_a();
/* Here I need to wait for delay usec */
for (j = 0; j < delay / 1000; j++) {
if (kthread_should_stop())
goto out
udelay(1000)
if (kthread_should_stop())
goto out
}
do_work_b();
}
out:
do_exit(0)
}
In the thread function I need to do something at do_work_a()
, wait for delay
usec and then do something else in do_work_b()
. My problem is that if I want to remove the module while the thread is running, the system hangs.
I expected that when I unload the module and kthread_stop()
executes then
at some point the thread will execute kthread_should_stop()
and break the loop. At the same time kthread_stop()
would block until the thread exits.
If I leave the thread to finish its loop and exit by itself everything works like a charm. If I try to unload the module though, while the thread runs the whole system hangs.
do_work_{a,b}()
is guaranteed to return.
Can anyone notice what am I missing?