Quantcast
Channel: Active questions tagged linux-kernel - Stack Overflow
Viewing all articles
Browse latest Browse all 12322

kthread stopped without running

$
0
0

If I create a kernel thread with kthread_run then kthread_stop it immediately, the kernel thread might be stopped without running. I checked the source code of kthread_run and kthread_stop in Linux-5.4.73

/** * kthread_run - create and wake a thread. * @threadfn: the function to run until signal_pending(current). * @data: data ptr for @threadfn. * @namefmt: printf-style name for the thread. * * Description: Convenient wrapper for kthread_create() followed by * wake_up_process().  Returns the kthread or ERR_PTR(-ENOMEM). */#define kthread_run(threadfn, data, namefmt, ...)              \({                                     \    struct task_struct *__k                        \        = kthread_create(threadfn, data, namefmt, ## __VA_ARGS__); \    if (!IS_ERR(__k))                          \        wake_up_process(__k);                      \    __k;                                   \})
/** * kthread_stop - stop a thread created by kthread_create(). * @k: thread created by kthread_create(). * * Sets kthread_should_stop() for @k to return true, wakes it, and * waits for it to exit. This can also be called after kthread_create() * instead of calling wake_up_process(): the thread will exit without * calling threadfn(). * * If threadfn() may call do_exit() itself, the caller must ensure * task_struct can't go away. * * Returns the result of threadfn(), or %-EINTR if wake_up_process() * was never called. */int kthread_stop(struct task_struct *k){    struct kthread *kthread;    int ret;    trace_sched_kthread_stop(k);    get_task_struct(k);    kthread = to_kthread(k);    set_bit(KTHREAD_SHOULD_STOP, &kthread->flags);    kthread_unpark(k);    wake_up_process(k);    wait_for_completion(&kthread->exited);    ret = k->exit_code;    put_task_struct(k);    trace_sched_kthread_stop_ret(ret);    return ret;}

It seems that the kernel thread should have been waken up before kthread_stop return, but it might not. I am really confused, could anybody help me?

My test code is as follows.

test1.c

#include <linux/module.h>#include <linux/kernel.h>#include <linux/delay.h>#include <linux/kthread.h>#include <linux/sched.h>#include <linux/semaphore.h>#include <linux/spinlock.h> MODULE_LICENSE("GPL");static struct task_struct *t1;static struct task_struct *t2;static struct task_struct *t3;static int func(void *__para){    const char *msg = (const char *)__para;    printk("%s %s\n", __func__, msg);    /* Wait for kthread_stop */    set_current_state(TASK_INTERRUPTIBLE);    while (!kthread_should_stop()) {        schedule();        set_current_state(TASK_INTERRUPTIBLE);    }    set_current_state(TASK_RUNNING);    printk("%s %s return\n", __func__, msg);    return 0;}static int __init start_init(void){    printk(KERN_INFO "Thread Creating...\n");    t1 = kthread_run(func, "t1", "t1");    if (IS_ERR(t1)) {        WARN_ON(1);        return 0;    }    t2 = kthread_run(func, "t2", "t2");    if (IS_ERR(t2)) {        WARN_ON(1);        return 0;    }    printk("Stopping t2\n");    kthread_stop(t2);    printk("t2 stopped\n");    t3 = kthread_run(func, "t3", "t3");    if (IS_ERR(t3)) {        WARN_ON(1);        return 0;    }    return 0;}static void __exit end_exit(void){    printk(KERN_INFO "Cleaning Up...\n");    if (IS_ERR(t1))        return;    printk("Stopping t1\n");    kthread_stop(t1);    printk("t1 stopped\n");    printk("Stopping t3\n");    kthread_stop(t3);    printk("t3 stopped\n");}module_init(start_init)module_exit(end_exit)

Makefile

obj-m += test1.oall:    $(MAKE) -C /lib/modules/$(shell uname -r)/build M=`pwd`clean:    $(MAKE) -C /lib/modules/$(shell uname -r)/build M=`pwd` clean

The command to run

sudo insmod test1.kosudo rmmod test1

The dmesg of the first run

[10914.046211] Thread Creating...[10914.046515] func t1[10914.046530] Stopping t2[10914.046531] func t2[10914.046533] func t2 return[10914.046538] t2 stopped[10914.046555] func t3[10938.895544] Cleaning Up...[10938.895545] Stopping t1[10938.895552] func t1 return[10938.895561] t1 stopped[10938.895562] Stopping t3[10938.895566] func t3 return[10938.895587] t3 stopped

t2 has executed before stopped this time.

The dmesg of the second run

[10940.775771] Thread Creating...[10940.776109] func t1[10940.776126] Stopping t2[10940.776138] t2 stopped[10940.776162] func t3[10956.375606] Cleaning Up...[10956.375607] Stopping t1[10956.375613] func t1 return[10956.375674] t1 stopped[10956.375674] Stopping t3[10956.375678] func t3 return[10956.375697] t3 stopped

t2 stopped without running. But t1 and t3 which are not stopped immediately run before being stopped.


Viewing all articles
Browse latest Browse all 12322

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>