Name: Simplified Kthread Tests Author: Rusty Russell Status: Booted on 2.6.1-rc2-bk1 Depends: D: Test code for kthread primitives. diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .1277-linux-2.6.1-rc2/kernel/kthread.c .1277-linux-2.6.1-rc2.updated/kernel/kthread.c --- .1277-linux-2.6.1-rc2/kernel/kthread.c 2004-01-06 18:59:37.000000000 +1100 +++ .1277-linux-2.6.1-rc2.updated/kernel/kthread.c 2004-01-06 18:59:59.000000000 +1100 @@ -169,3 +169,90 @@ int kthread_stop(struct task_struct *k) wait_for_completion(&stop.done); return stop.result; } + +/* Test code */ +#include + +static int threadfn_count; + +static int threadfn(void *data) +{ + BUG_ON(strcmp(current->comm, "kthreadtest1") != 0); + + if (data == do_exit) + do_exit(0); + + while (!kthread_should_stop()) { + threadfn_count++; + current->state = TASK_INTERRUPTIBLE; + schedule(); + } + + return PTR_ERR(data); +} + +static int test_kthreads(void) +{ + struct task_struct *k; + int ret; + + printk("kthread_create.\n"); + threadfn_count = 0; + k = kthread_create(threadfn, NULL, "kthreadtest%i", 1); + BUG_ON(IS_ERR(k)); + BUG_ON(threadfn_count); + + printk("kthread_start.\n"); + wake_up_process(k); + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(1); + BUG_ON(threadfn_count != 1); + + printk("kthread threadfn.\n"); + wake_up_process(k); + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(1); + BUG_ON(threadfn_count != 2); + + printk("kthread_stop.\n"); + ret = kthread_stop(k); + BUG_ON(threadfn_count != 2); + BUG_ON(ret != 0); + + printk("kthread: stopped before starting\n"); + threadfn_count = 0; + k = kthread_create(threadfn, NULL, "kthreadtest%i", 1); + BUG_ON(IS_ERR(k)); + BUG_ON(threadfn_count); + ret = kthread_stop(k); + printk("ret = %i\n", ret); + BUG_ON(ret != -EINTR); + BUG_ON(threadfn_count); + + printk("kthread: threadfn returns error.\n"); + threadfn_count = 0; + k = kthread_create(threadfn, ERR_PTR(-EINVAL), "kthreadtest%i", 1); + BUG_ON(IS_ERR(k)); + wake_up_process(k); + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(1); + BUG_ON(threadfn_count != 1); + ret = kthread_stop(k); + BUG_ON(threadfn_count != 1); + BUG_ON(ret != -EINVAL); + + printk("kthread: threadfn which exits.\n"); + k = kthread_create(threadfn, do_exit, "kthreadtest%i", 1); + BUG_ON(IS_ERR(k)); + get_task_struct(k); + wake_up_process(k); + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(1); + BUG_ON(!(k->state & (TASK_ZOMBIE|TASK_DEAD))); + put_task_struct(k); + + printk("All kthread tests passed...\n"); + return 0; +} + +module_init(test_kthreads);