Messages in this thread | | | Subject | Re: Module/kthread/printk question/problem | From | Eric Dumazet <> | Date | Thu, 02 Feb 2012 10:15:58 +0100 |
| |
Le jeudi 02 février 2012 à 10:13 +0400, Dmitry Antipov a écrit : > On 02/01/2012 09:16 PM, Eric Dumazet wrote: > > >> I realize this, but there was a second part of the question: what's the > >> better way to ensure that all test/X threads are really gone at some point of > >> testmod_exit()? > >> > > > > You could use kthread_stop() > > > > This way you can control all your kernel threads really exited before > > module cleanup. > > Hm... if I try something like: > > static void __exit testmod_exit(void) > { > int i; > > wait_for_completion(&done); > for (i = 0; i < nrthreads; i++) > kthread_stop(threads[i]); > kfree(threads); > }
Try following code :
#include <linux/kernel.h> #include <linux/sched.h> #include <linux/kthread.h> #include <linux/module.h> #include <linux/slab.h>
MODULE_LICENSE("GPL");
static int nrthreads = 128; module_param(nrthreads, int, 0644);
static int loopcount = 1024; module_param(loopcount, int, 0644);
static int usehrtime = 0; module_param(usehrtime, int, 0644);
static int slack = 50000; module_param(slack, int, 0644);
static int msecs = 1; module_param(msecs, int, 0644);
static struct task_struct **threads;
static int test(void *unused) { int i; ktime_t expires = ktime_set(0, msecs * NSEC_PER_MSEC);
for (i = 0; !kthread_should_stop() && i < loopcount; i++) { if (usehrtime) { set_current_state(TASK_UNINTERRUPTIBLE); schedule_hrtimeout_range(&expires, slack, HRTIMER_MODE_REL); } else schedule_timeout_uninterruptible(msecs_to_jiffies(msecs)); }
return 0; }
static int __init testmod_init(void) { int i;
printk("test begin\n");
threads = kmalloc(nrthreads * sizeof(struct task_struct *), GFP_KERNEL); if (!threads) return -ENOMEM;
for (i = 0; i < nrthreads; i++) { threads[i] = kthread_create(test, NULL, "test/%d", i); if (IS_ERR(threads[i])) { int j, err = PTR_ERR(threads[i]);
for (j = 0; j < i; j++) kthread_stop(threads[j]); kfree(threads); return err; } } for (i = 0; i < nrthreads; i++) { get_task_struct(threads[i]); wake_up_process(threads[i]); } return 0; }
static void __exit testmod_exit(void) { int i;
for (i = 0; i < nrthreads; i++) { kthread_stop(threads[i]); put_task_struct(threads[i]); } kfree(threads); }
module_init(testmod_init); module_exit(testmod_exit);
-- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |