Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stop Linux kernel threads on rmmod?

Tags:

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?

like image 305
pradeepchhetri Avatar asked Mar 12 '11 05:03

pradeepchhetri


People also ask

How do you stop Kthreading?

You could cancel a thread in this manner: t1 = kthread_create(func, &para1, "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 .

What are Linux kernel threads?

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.

Does Linux kernel have threads?

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.

How do kernel threads work?

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.


2 Answers

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:

  1. Call do_exit() when you're done.
  2. Return a value when another thread calls kthread_stop().

Hopefully after fixing these two small problems, you'll have a functional thread creator / reaper.

like image 112
sarnold Avatar answered Sep 23 '22 18:09

sarnold


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"); 
like image 36
MSharq Avatar answered Sep 24 '22 18:09

MSharq