Kernel module/kthread question

Daniel Lezcano daniel.lezcano at linaro.org
Wed Feb 1 11:49:58 UTC 2012


On 02/01/2012 12:28 PM, Dmitry Antipov wrote:
> I'm writing a kernel module which creates a substantial amount of
> kernel threads. After dropping the real stuff, the module skeleton is:
>
> #include <linux/kernel.h>
> #include <linux/sched.h>
> #include <linux/kthread.h>
> #include <linux/module.h>
> #include <linux/slab.h>
> #include <linux/ktime.h>
>
> MODULE_LICENSE("GPL");
>
> static int nrthreads = 128;
> module_param(nrthreads, int, 0644);
>
> static int loopcount = 1024;
> module_param(loopcount, int, 0644);
>
> static struct task_struct **threads;
> static struct completion done;
> static atomic_t nrunning;
>
> static int test(void *unused)
> {
> int i;
> ktime_t expires = ktime_set(0, NSEC_PER_MSEC);
>
> for (i = 0; !kthread_should_stop() && i < loopcount; i++)
> schedule_hrtimeout_range(&expires, 50000, HRTIMER_MODE_REL);
>
> if (atomic_dec_and_test(&nrunning))
> complete(&done);
> return 0;
> }
>
> static int __init testmod_init(void)
> {
> int i, j, err = 0;
>
> atomic_set(&nrunning, 0);
> init_completion(&done);
>
> threads = kmalloc(nrthreads * sizeof(struct task_struct *), GFP_KERNEL);
> if (!threads)
> return -ENOMEM;
>
> for (i = 0; i < nrthreads; i++) {
> threads[i] = kthread_run(test, NULL, "test/%d", i);
> if (IS_ERR(threads[i])) {
> err = PTR_ERR(threads[i]);
> for (j = 0; j < i; j++)
> kthread_stop(threads[j]);
> kfree(threads);
> return err;
> }
> atomic_inc(&nrunning);
> }
> return 0;
> }
>
> static void __exit testmod_exit(void)
> {
> wait_for_completion(&done);
> kfree(threads);
> }
>
> module_init(testmod_init);
> module_exit(testmod_exit);
>
> For the most of the cases, it works as expected, at least from 8 to 128
> threads.
> But if I try 'insmod testmod.ko && rmmod testmod', it's possible to catch a
> very rare crash:

IMO, you have a race condition with nrunning. What guarantee do you have 
atomic_dec_and_test is called after atomic_inc ?

Maybe you can try by removing atomic_inc and do atomic_set(&nrunning, 
nrthreads) ?




More information about the linaro-dev mailing list