I wrote the following code to create a kernel thread:
#include<linux/init.h> #include<linux/module.h> #include<linux/kernel.h> #include<linux/kthread.h> #include<linux/sched.h> struct task_struct *task; int data; int ret; int thread_function(void *data) { int var; var = 10; return var; } static int kernel_init(void) { data = 20; printk(KERN_INFO"--------------------------------------------"); task = kthread_create(&thread_function,(void *)data,"pradeep"); task = kthread_run(&thread_function,(void *)data,"pradeep"); printk(KERN_INFO"Kernel Thread : %s\n",task->comm); return 0; } static void kernel_exit(void) { ret = kthread_stop(task); } module_init(kernel_init); module_exit(kernel_exit);
On giving the insmod command, I am able to create a kernel thread named "pradeep" and I can see the new thread using the ps -ef
command as follows
root 6071 2 0 10:21 ? 00:00:00 [pradeep]
and its parent is kthreadd whose PID is 2. But I am not able to stop this thread on giving rmmod
command. It is giving the following output:
ERROR: Removing 'pradeep': Device or resource busy.
Can somebody please tell me how to kill this thread?
You could cancel a thread in this manner: t1 = kthread_create(func, ¶1, "t1"); // Oops, something went wrong(such as failing to create another kthread) ret = kthread_stop(t1); In this way, func will not be executed, and ktheard_stop will return -EINTR .
A kernel thread is a kernel entity, like processes and interrupt handlers; it is the entity handled by the system scheduler. A kernel thread runs within a process, but can be referenced by any other thread in the system.
To augment the need for running background operations, the kernel spawns threads (similar to processes). These kernel threads are similar to regular processes, in that they are represented by a task structure and assigned a PID.
Kernel threads are used to provide privileged services to applications (such as system calls ). The are also used by the kernel to keep track of what all is running on the system, how much of which resources are allocated to what process, and to do scheduling.
You should use only one of kthread_create()
or kthread_run()
:
/** * 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; \ })
So you're creating two threads and leaking one of them:
task = kthread_create(&thread_function,(void*) &data,"pradeep"); task = kthread_run(&thread_function,(void*) &data,"pradeep");
Furthermore, your thread function might be missing some details:
/** * kthread_create - create a kthread. * @threadfn: the function to run until signal_pending(current). * @data: data ptr for @threadfn. * @namefmt: printf-style name for the thread. * * Description: This helper function creates and names a kernel * thread. The thread will be stopped: use wake_up_process() to start * it. See also kthread_run(). * * When woken, the thread will run @threadfn() with @data as its * argument. @threadfn() can either call do_exit() directly if it is a * standalone thread for which noone will call kthread_stop(), or * return when 'kthread_should_stop()' is true (which means * kthread_stop() has been called). The return value should be zero * or a negative error number; it will be passed to kthread_stop(). * * Returns a task_struct or ERR_PTR(-ENOMEM). */
I think the two choices for terminating a thread are:
do_exit()
when you're done.kthread_stop()
.Hopefully after fixing these two small problems, you'll have a functional thread creator / reaper.
I hope the below program resolves your problem.... thumbs up :-)
`#include<linux/init.h> #include<linux/module.h> #include<linux/kernel.h> #include<linux/kthread.h> #include<linux/sched.h>` struct task_struct *task; int data; int ret; int thread_function(void *data) { int var; var = 10; printk(KERN_INFO "IN THREAD FUNCTION"); while(!kthread_should_stop()){ schedule(); } /*do_exit(1);*/ return var; } static int kernel_init(void) { data = 20; printk(KERN_INFO"--------------------------------------------"); /*task = kthread_create(&thread_function,(void *)data,"pradeep");*/ task = kthread_run(&thread_function,(void *)data,"pradeep"); printk(KERN_INFO"Kernel Thread : %s\n",task->comm); return 0; } static void kernel_exit(void) { kthread_stop(task); } module_init(kernel_init); module_exit(kernel_exit); MODULE_AUTHOR("SHRQ"); MODULE_LICENSE("GPL");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With