Create Kthread Worker
# |
Version |
---|---|
Ubuntu |
Ubuntu 22.10 |
Kernel |
6.7.9 |
In this program, you are going to learn
How to create the kthread worker ?
What are the different ways to create kthread worker?
How to destroy the kthread worker ?
How to use Kthread APIs ?
How to use below APIs ?
Here is the function prototype of the API: kthread_create_worker
#include <linux/kthread.h>
struct kthread_worker *kthread_create_worker(unsigned int flags, const char namefmt[], ...);
where
kthread_create_worker: creates a kthread worker.
return type:
returns a pointer (i.e struct kthread_worker*) to the allocated worker on success
ERR_PTR(-ENOMEM) when the needed structures could not get allocated
ERR_PTR(-EINTR) when the caller was killed by a fatal signal.
flags: flags modifying the default behaviour of the kthread worker.
namefmt: printf-style name for the kthread worker.
Here is an example of how to use the API,
kthread_create_worker(0,"sample kthread worker");
Here is the function prototype of the API: kthread_init_worker
#include <linux/kthread.h>
#define kthread_init_worker(worker) \
do { \
static struct lock_class_key __key; \
__kthread_init_worker((worker), "("#worker")->lock", &__key); \
} while (0)
where
kthread_init_worker: initializes a kthread worker.
worker: kthread worker which needs to be initialized
Here is an example of how to use the API,
kthread_init_worker(myworker);
Here is the function prototype of the API: kthread_should_stop
#include <linux/kthread.h>
bool kthread_should_stop(void);
where
kthread_should_stop: this is used to determine whether the thread should return now. Whenever the kthread_stop() is called it will be woken and returns true.
return type: returns true when the thread is stopped, false when the thread is still in execution
Here is an example of how to use the API,
while (!kthread_should_stop())
{
//add the instructions to be performed during thread execution.
}
Here is the function prototype of the API: kthread_run
#include <linux/kthread.h>
#define kthread_run(threadfn, data, namefmt, ...)
where
kthread_run : is used to create and wake a kthread
return type: struct task_struct* (i.e) address of the kthread
threadfn: function to executed by kthread
data: data pointer for threadfn which can be used to send any possible arguments required for threadfn.
namefmt: printf-style format for the thread name which will be displayed on ps output when the thread is in execution.
Here is an example of how to use the API,
kthread_run(mythread,NULL,"sample kthread");
Here is the function prototype of the API: kthread_flush_worker
#include <linux/kthread.h>
void kthread_flush_worker(struct kthread_worker *worker);
where
kthread_flush_worker: flush all current works on kthread worker, waits until all currently executing or pending works are completed.
worker: kthread worker which needs to be flushed.
Here is the example of how to use the API,
kthread_flush_worker(myworker);
Here is the prototye of the API: kthread_destroy_worker
#include <linux/kthread.h>
void kthread_destroy_worker(struct kthread_worker *worker);
where
kthread_destroy_worker : flush and destroy the kthread worker.
worker: worker which needs to be destroyed.
Here is an example of how to use the API,
kthread_destroy_worker(myworker);
Here is the prototype of module paramter APIs
#include <linux/module.h>
#define MODULE_LICENSE(_license) MODULE_FILE MODULE_INFO(license, _license)
#define MODULE_AUTHOR(_author) MODULE_INFO(author, _author)
#define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description)
where
MODULE_LICENSE: tells the kernel what license is used by our module.
MODULE_AUTHOR: denotes the author of this kernel module.
MODULE_DESCRIPTION: gives a basic idea about what the kernel module does.
These information can be found when modinfo command is used which lists out all these above mentioned information.
Here is the example of how to use the Module parameter APIs,
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Linux Usr");
MODULE_DESCRIPTION("Sample kernel module");
Here is the prototype of the API: IS_ERR
#include <linux/err.h>
static inline bool __must_check IS_ERR(__force const void *ptr);
where
IS_ERR: Detects an error pointer
return type: return true if it’s an error pointer else return false.
ptr: pointer which needs to detected.
Here is an example of how to use the API,
if(IS_ERR(sample_ptr)) {
//instructions to be executed when error ptr is detected
} else {
//instructions to be executed when error ptr is not detected
}
Here is the example of the API: wake_up_process
#include <linux/sched.h>
extern int wake_up_process(struct task_struct *tsk);
where
wake_up_process: wake up a specific process
return type: returns 1 if the process is woken up, 0 if the process is in running state.
tsk: process to be woken up.
Here is the example of how to use the API,
wake_up_process(mythread);
Here is the prototype of the Driver entry point API’s
#include <linux/module.h>
#define module_init(x) __initcall(x);
#define module_exit(x) __exitcall(x);
where
module_init: driver initialization entry point which will be called at module insertion time.
module_exit: driver exit entry point which will be called during the removal of module.
- x:
function to be run at module insertion for module_init function.
function to be run when driver is removed for module_exit function.
Here is an example of how to use the driver entry point API’s
module_init(myinitmodule);
module_exit(myexitmodule);
In this example let’s see how to create kthread worker using kthread_create_worker and execute it.
Include the follow header files(.h) to refer the API being used for the execution.
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/delay.h>
Add the following module macros to display information about the license, author and description about the module.
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Linux Usr");
MODULE_DESCRIPTION("Example of kthread_create_worker");
Declare the thread variables which we are going to create and use in this example
static struct kthread_worker *def_worker;
static struct task_struct *def_thread;
Add the module init function which will be executed once we load the kernel module using insmod command.
static int __init kthread_create_worker_init(void)
{
pr_info("Inside kthread init function\n");
thread_start();
return 0;
}
Add the thread start function which creates kthread worker and kthread, on success creation it starts executing the task.
void thread_start(void)
{
def_worker = kthread_create_worker(0,"kthread_create_worker worker example");
if (IS_ERR(def_thread))
pr_info("Error creating in kthread worker\n");
else
pr_info("Created kthread_worker\n");
def_thread = kthread_run(def_thread_task,NULL,"kthread_create_worker thread example");
if (IS_ERR(def_thread))
pr_info("Error creating thread using kthread_run\n");
else
pr_info("Created kthread task\n");
}
Add the module exit function which will be executed once we unload the kernel module using rmmod command.
static void __exit kthread_create_worker_exit(void)
{
pr_info("Inside kthread exit function\n");
thread_stop();
}
Add the thread stop function which destroys the thread and stops the execution.
void thread_stop(void)
{
kthread_destroy_worker(def_worker);
pr_info("Destroyed kthread worker and thread\n");
}
Add the thread function API which will be called as soon as the kthread is created and is in running state.
static int def_thread_task(void *data)
{
while(!kthread_should_stop()) {
pr_info("Inside def_thread_task\n");
msleep(1000);
}
return 0;
}
Add the driver entry points which will be executed once the module is inserted or removed from the kernel.
module_init(kthread_create_worker_init);
module_exit(kthread_create_worker_exit);
1#include <linux/init.h>
2#include <linux/kernel.h>
3#include <linux/kthread.h>
4#include <linux/module.h>
5#include <linux/delay.h>
6
7MODULE_LICENSE("GPL");
8MODULE_AUTHOR("Linux Usr");
9MODULE_DESCRIPTION("Example of kthread_create_worker");
10
11static struct kthread_worker *def_worker;
12static struct task_struct *def_thread;
13
14/* def_thread_task - executes once the thread is in running state,
15 * prints a message and sleeps for 1000 ms,
16 * stops when the worker is destroyed */
17
18static int def_thread_task(void *data)
19{
20 while(!kthread_should_stop()) {
21 pr_info("Inside def_thread_task\n");
22 msleep(1000);
23 }
24 return 0;
25}
26
27/* thread_start - called from module init function,
28 * creates kthread worker and kthread,
29 * if success starts its execution */
30
31void thread_start(void)
32{
33 def_worker = kthread_create_worker(0,"kthread_create_worker worker example");
34 if (IS_ERR(def_thread))
35 pr_info("Error creating in kthread worker\n");
36 else
37 pr_info("Created kthread_worker\n");
38 def_thread = kthread_run(def_thread_task,NULL,"kthread_create_worker thread example");
39 if (IS_ERR(def_thread))
40 pr_info("Error creating thread using kthread_run\n");
41 else
42 pr_info("Created kthread task\n");
43}
44
45/* kthread_create_worker_init - calls thread_start function,
46 * executes when the module is loaded*/
47
48static int __init kthread_create_worker_init(void)
49{
50 pr_info("Inside kthread init function\n");
51 thread_start();
52 return 0;
53}
54
55/* thread_stop - called by module exit function,
56 * destroys the thread and stops its execution */
57
58void thread_stop(void)
59{
60 kthread_destroy_worker(def_worker);
61 pr_info("Destroyed kthread worker and thread\n");
62}
63
64/* kthread_create_worker_exit - calls thread_stop function,
65 * executes when the module is unloaded*/
66
67static void __exit kthread_create_worker_exit(void)
68{
69 pr_info("Inside kthread exit function\n");
70 thread_stop();
71}
72
73module_init(kthread_create_worker_init);
74module_exit(kthread_create_worker_exit);
1obj-m += kthread.o
2
3all:
4 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
5
6clean:
7 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Run make to compile the kernel source and generate the .ko image.
make -C /lib/modules/6.7.9/build M=$HOME/kthread_examples/
make[1]: Entering directory '/usr/src/linux-headers-6.7.9'
warning: the compiler differs from the one used to build the kernel
The kernel was built by: x86_64-linux-gnu-gcc (Ubuntu 12.2.0-3ubuntu1) 12.2.0
You are using: gcc (Ubuntu 12.2.0-3ubuntu1) 12.2.0
CC [M] $HOME/kthread_examples/kthread.o
MODPOST $HOME/kthread_examples/Module.symvers
CC [M] $HOME/kthread_examples/kthread.mod.o
LD [M] $HOME/kthread_examples/kthread.ko
BTF [M] $HOME/kthread_examples/kthread.ko
Skipping BTF generation for $HOME/kthread_examples/kthread.ko due to unavailability of vmlinux
make[1]: Leaving directory '/usr/src/linux-headers-6.7.9'
Check if the .ko is generated or not using ls command.
test@test-V520-15IKL:~$ ls -l
total 360
-rw-rw-r-- 1 test test 713 Mar 18 16:06 kthread.c
-rw-rw-r-- 1 test test 169784 Mar 18 16:08 kthread.ko
-rw-rw-r-- 1 test test 58 Mar 18 16:08 kthread.mod
-rw-rw-r-- 1 test test 1047 Mar 18 16:08 kthread.mod.c
-rw-rw-r-- 1 test test 96512 Mar 18 16:08 kthread.mod.o
-rw-rw-r-- 1 test test 74696 Mar 18 16:08 kthread.o
-rw-rw-r-- 1 test test 161 Mar 18 16:00 Makefile
-rw-rw-r-- 1 test test 58 Mar 18 16:08 modules.order
-rw-rw-r-- 1 test test 0 Mar 18 16:08 Module.symvers
Run modinfo command to get the information about the kernel module.
test@test-V520-15IKL:~/.../tc_1$ modinfo kthread.ko
filename: $HOME/kthread_examples/kthread.ko
description: Example of kthread_create_worker
author: Linux Usr
license: GPL
srcversion: 8D2147F67AB01CF0E482DAC
depends:
retpoline: Y
name: kthread
vermagic: 6.7.9 SMP preempt mod_unload modversions
insert the module using insmod command.
test@test-V520-15IKL:~$ sudo insmod ./kthread.ko
check if the module is loaded or not using lsmod command.
test@test-V520-15IKL:~$ sudo lsmod | grep kthread
kthread 16384 0
check if the thread is created or not using ps command.
test@test-V520-15IKL:~$ ps -N | grep kthread_create_worker
6390 ? 00:00:00 kthread_create_worker worker example
6391 ? 00:00:00 kthread_create_worker thread example
check for the kernel messages from init function and thread function once the module is loaded and thread is created.
test@test-V520-15IKL:~$ sudo dmesg
[20742.666348] Inside kthread init function
[20742.666423] Created kthread_worker
[20742.666461] Created kthread task
[20742.666481] Inside def_thread_task
[20743.688961] Inside def_thread_task
[20744.712987] Inside def_thread_task
remove the module from kernel using rmmod command.
test@test-V520-15IKL:~$ sudo rmmod kthread
check if the module is still loaded after removing the kernel module using lsmod if it is not displayed in lsmod output it is verified that the module is removed successfully.
test@test-V520-15IKL:~$ sudo lsmod | grep kthread
test@test-V520-15IKL:~$
check if the thread is destroyed using ps command if it is not displayed in ps output we can confirm that the thread is destroyed successfully.
test@test-V520-15IKL:~$ ps -N | grep kthread_create_worker
test@test-V520-15IKL:~$
Check for kernel messages from exit function using dmesg command.
test@test-V520-15IKL:~$ sudo dmesg
[20753.695905] Inside kthread exit function
[20753.696107] Destroyed kthread worker and thread
In this example let’s see how to create kthread worker using kthread_init_worker and execute it.
Include the follow header files(.h) to refer the API being used for the execution.
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/slab.h>
#include <linux/delay.h>
Add the following module macros to display information about the license, author and description about the module.
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Linux Usr");
MODULE_DESCRIPTION("Example of kthread_init_worker");
Declare the thread variables which we are going to create and use in this example
struct kthread_worker my_worker;
struct task_struct *my_thread;
Add the module init function which will be executed once we load the kernel module using insmod command.
static int __init kthread_init_worker_init(void)
{
pr_info("Inside kthread init function\n");
thread_start();
return 0;
}
Add the thread start function in which the worker and thread is created and starts its execution.
void thread_start(void)
{
kthread_init_worker(&my_worker);
pr_info("kthread worker is initialized\n");
my_thread = kthread_run(my_work_fn,NULL,"kthread_init_worker thread example");
if(IS_ERR(my_thread))
pr_info("Error creating kthread\n");
else
pr_info("Thread created successfully\n");
}
Add the module exit function which will be executed once we unload the kernel module using rmmod command.
static void __exit kthread_init_worker_exit(void)
{
pr_info("Inside kthread exit function\n");
thread_stop();
}
Add the thread stop function in which worker is destroyed and the thread stops its execution.
void thread_stop(void)
{
kthread_destroy_worker(&my_worker);
pr_info("Destroyed kthread and worker\n");
}
Add the thread function API which will be called as soon as the kthread is created and is in running state.
int my_work_fn(void *data)
{
while (!kthread_should_stop())
{
pr_info("Inside kthread work function\n");
msleep(100);
}
return 0;
}
Add the driver entry points which will be executed once the module is inserted or removed from the kernel.
module_init(kthread_init_worker_init);
module_exit(kthread_init_worker_exit);
1#include <linux/init.h>
2#include <linux/kernel.h>
3#include <linux/module.h>
4#include <linux/kthread.h>
5#include <linux/slab.h>
6#include <linux/delay.h>
7
8MODULE_LICENSE("GPL");
9MODULE_AUTHOR("Linux usr");
10MODULE_DESCRIPTION("Example of kthread_init_worker");
11
12struct kthread_worker my_worker;
13struct task_struct *my_thread;
14
15/* my_work_fn - executes when the thread starts its execution,
16 * prints a message and sleep for 100ms,
17 * stops once thread_stop() is called*/
18
19int my_work_fn(void *data)
20{
21 while (!kthread_should_stop())
22 {
23 pr_info("Inside kthread work function\n");
24 msleep(100);
25 }
26 return 0;
27}
28
29/* thread_start - creates worker and thread,
30 * on success starts its execution*/
31
32void thread_start(void)
33{
34 kthread_init_worker(&my_worker);
35 pr_info("kthread worker is initialized\n");
36 my_thread = kthread_run(my_work_fn,NULL,"kthread_init_worker thread example");
37 if(IS_ERR(my_thread))
38 pr_info("Error creating kthread\n");
39 else
40 pr_info("Thread created successfully\n");
41}
42
43/* kthread_init_worker_init - calls thread_start function,
44 * executes when the module is loaded*/
45
46static int __init kthread_init_worker_init(void)
47{
48 pr_info("Inside kthread init function\n");
49 thread_start();
50 return 0;
51}
52
53/* thread_stop - destroys worker and stops its execution*/
54
55void thread_stop(void)
56{
57 kthread_destroy_worker(&my_worker);
58 pr_info("Destroyed kthread and worker\n");
59}
60
61/* kthread_init_worker_exit - calls thread_stop,
62 * executes when the module is removed*/
63
64static void __exit kthread_init_worker_exit(void)
65{
66 pr_info("Inside kthread exit function\n");
67 thread_stop();
68}
69
70module_init(kthread_init_worker_init);
71module_exit(kthread_init_worker_exit);
1obj-m += kthread.o
2
3all:
4 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
5
6clean:
7 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Run make to compile the kernel source and generate the .ko image.
make -C /lib/modules/6.7.9/build M=$HOME/kthread_examples/
make[1]: Entering directory '/usr/src/linux-headers-6.7.9'
warning: the compiler differs from the one used to build the kernel
The kernel was built by: x86_64-linux-gnu-gcc (Ubuntu 12.2.0-3ubuntu1) 12.2.0
You are using: gcc (Ubuntu 12.2.0-3ubuntu1) 12.2.0
CC [M] $HOME/kthread_examples/kthread.o
MODPOST $HOME/kthread_examples/Module.symvers
CC [M] $HOME/kthread_examples/kthread.mod.o
LD [M] $HOME/kthread_examples/kthread.ko
BTF [M] $HOME/kthread_examples/kthread.ko
Skipping BTF generation for $HOME/kthread_examples/kthread.ko due to unavailability of vmlinux
make[1]: Leaving directory '/usr/src/linux-headers-6.7.9'
Check if the .ko is generated or not using ls command.
test@test-V520-15IKL:~$ ls -l
total 360
-rw-rw-r-- 1 test test 713 Mar 18 16:06 kthread.c
-rw-rw-r-- 1 test test 169784 Mar 18 16:08 kthread.ko
-rw-rw-r-- 1 test test 58 Mar 18 16:08 kthread.mod
-rw-rw-r-- 1 test test 1047 Mar 18 16:08 kthread.mod.c
-rw-rw-r-- 1 test test 96512 Mar 18 16:08 kthread.mod.o
-rw-rw-r-- 1 test test 74696 Mar 18 16:08 kthread.o
-rw-rw-r-- 1 test test 161 Mar 18 16:00 Makefile
-rw-rw-r-- 1 test test 58 Mar 18 16:08 modules.order
-rw-rw-r-- 1 test test 0 Mar 18 16:08 Module.symvers
Run modinfo command to get the information about the kernel module.
test@test-V520-15IKL:~/.../tc_1$ modinfo kthread.ko
filename: $HOME/kthread_examples/kthread.ko
description: Example of kthread_init_worker
author: Linux Usr
license: GPL
srcversion: 8D2147F67AB01CF0E482DAC
depends:
retpoline: Y
name: kthread
vermagic: 6.7.9 SMP preempt mod_unload modversions
insert the module using insmod command.
test@test-V520-15IKL:~$ sudo insmod ./kthread.ko
check if the module is loaded or not using lsmod command.
test@test-V520-15IKL:~$ sudo lsmod | grep kthread
kthread 16384 0
check if the thread is created or not using ps command.
test@test-V520-15IKL:~$ ps -N | grep kthread_init_worker
5241 ? 00:00:00 kthread_init_worker thread example
check for the kernel messages from init function and thread function once the module is loaded and thread is created.
test@test-V520-15IKL:~$ sudo dmesg
[ 162.737148] Inside kthread init function
[ 162.737152] kthread worker is initialized
[ 162.737179] Thread created successfully
[ 162.737181] Inside kthread work function
[ 162.844228] Inside kthread work function
[ 162.952298] Inside kthread work function
remove the module from kernel using rmmod command.
test@test-V520-15IKL:~$ sudo rmmod kthread
check if the module is still loaded after removing the kernel module using lsmod if it is not displayed in lsmod output it is verified that the module is removed successfully.
test@test-V520-15IKL:~$ sudo lsmod | grep kthread
test@test-V520-15IKL:~$
check if the thread is destroyed using ps command if it is not displayed in ps output we can confirm that the thread is destroyed successfully.
test@test-V520-15IKL:~$ ps -N | grep kthread_init_worker
test@test-V520-15IKL:~$
Check for kernel messages from exit function using dmesg command.
test@test-V520-15IKL:~$ sudo dmesg
[ 185.693286] Inside kthread exit function
[ 185.693433] Destroyed kthread and worker
In this example let’s see how to flush created worker using kthread_flush_worker.
Include the follow header files(.h) to refer the API being used for the execution.
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/delay.h>
Add the following module macros to display information about the license, author and description about the module.
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Linux Usr");
MODULE_DESCRIPTION("example of kthread_flush_worker");
Declare the thread variables which we are going to create and use in this example
static struct kthread_worker *def_worker;
static struct task_struct *def_thread;
Add the module init function which will be executed once we load the kernel module using insmod command.
static int __init kthread_flush_worker_init(void)
{
pr_info("Inside kthread init function\n");
thread_start();
return 0;
}
Add the thread start function in which the thread and worker is created and starts its execution.
void thread_start (void)
{
def_worker = kthread_create_worker(0,"kthread_flush_worker worker example");
if (IS_ERR(def_worker))
pr_info("Error creating in kthread worker\n");
else
pr_info("Created kthread_worker\n");
def_thread = kthread_run(def_thread_task,NULL,"kthread_flush_worker thread example");
if (IS_ERR(def_thread))
pr_info("Error creating thread using kthread_run\n");
else
pr_info("Created kthread task\n");
}
Add the module exit function which will be executed once we unload the kernel module using rmmod command.
static void __exit kthread_flush_worker_exit(void)
{
pr_info("Inside kthread exit function\n");
thread_stop();
}
Add the thread stop function which flushes the worker and stops the execution.
void thread_stop(void)
{
kthread_flush_worker(def_worker);
pr_info("Destroyed kthread worker and thread\n");
}
Add the thread function API which will be called as soon as the kthread is created and is in running state.
static int def_thread_task(void *data)
{
while (!kthread_should_stop()) {
pr_info("Inside def_thread_task\n");
msleep(100);
}
return 0;
}
Add the driver entry points which will be executed once the module is inserted or removed from the kernel.
module_init(kthread_flush_worker_init);
module_exit(kthread_flush_worker_exit);
1#include <linux/init.h>
2#include <linux/kernel.h>
3#include <linux/kthread.h>
4#include <linux/module.h>
5#include <linux/delay.h>
6
7MODULE_LICENSE("GPL");
8MODULE_AUTHOR("Linux Usr");
9MODULE_DESCRIPTION("Example of kthread_flush_worker");
10
11static struct kthread_worker *def_worker;
12static struct task_struct *def_thread;
13
14/* def_thread_task - executes once the thread is created,
15 * prints a message and sleeps for 100ms,
16 * stops once kthread_stop() is called*/
17
18static int def_thread_task(void *data)
19{
20 while (!kthread_should_stop()) {
21 pr_info("Inside def_thread_task\n");
22 msleep(100);
23 }
24 return 0;
25}
26
27/* thread_start - creates kthread and kthread worker,
28 * on success kthread starts its execution*/
29
30void thread_start (void)
31{
32 def_worker = kthread_create_worker(0,"kthread_flush_worker worker example");
33 if (IS_ERR(def_worker))
34 pr_info("Error creating in kthread worker\n");
35 else
36 pr_info("Created kthread_worker\n");
37 def_thread = kthread_run(def_thread_task,NULL,"kthread_flush_worker thread example");
38 if (IS_ERR(def_thread))
39 pr_info("Error creating thread using kthread_run\n");
40 else
41 pr_info("Created kthread task\n");
42}
43
44/* kthread_flush_worker_init - calls thread_start,
45 * executes when module is loaded*/
46
47static int __init kthread_flush_worker_init(void)
48{
49 pr_info("Inside kthread init function\n");
50 thread_start();
51 return 0;
52}
53
54/*thread_stop - destroys kthread and worker*/
55
56void thread_stop(void)
57{
58 kthread_flush_worker(def_worker);
59 pr_info("Destroyed kthread worker and thread\n");
60}
61
62/* kthread_flush_worker_exit - calls thread_stop,
63 * executes when the module is unloaded*/
64
65static void __exit kthread_flush_worker_exit(void)
66{
67 pr_info("Inside kthread exit function\n");
68 thread_stop();
69}
70
71module_init(kthread_flush_worker_init);
72module_exit(kthread_flush_worker_exit);
1obj-m += kthread.o
2
3all:
4 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
5
6clean:
7 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Run make to compile the kernel source and generate the .ko image.
make -C /lib/modules/6.7.9/build M=$HOME/kthread_examples/
make[1]: Entering directory '/usr/src/linux-headers-6.7.9'
warning: the compiler differs from the one used to build the kernel
The kernel was built by: x86_64-linux-gnu-gcc (Ubuntu 12.2.0-3ubuntu1) 12.2.0
You are using: gcc (Ubuntu 12.2.0-3ubuntu1) 12.2.0
CC [M] $HOME/kthread_examples/kthread.o
MODPOST $HOME/kthread_examples/Module.symvers
CC [M] $HOME/kthread_examples/kthread.mod.o
LD [M] $HOME/kthread_examples/kthread.ko
BTF [M] $HOME/kthread_examples/kthread.ko
Skipping BTF generation for $HOME/kthread_examples/kthread.ko due to unavailability of vmlinux
make[1]: Leaving directory '/usr/src/linux-headers-6.7.9'
Check if the .ko is generated or not using ls command.
test@test-V520-15IKL:~$ ls -l
total 360
-rw-rw-r-- 1 test test 713 Mar 18 16:06 kthread.c
-rw-rw-r-- 1 test test 169784 Mar 18 16:08 kthread.ko
-rw-rw-r-- 1 test test 58 Mar 18 16:08 kthread.mod
-rw-rw-r-- 1 test test 1047 Mar 18 16:08 kthread.mod.c
-rw-rw-r-- 1 test test 96512 Mar 18 16:08 kthread.mod.o
-rw-rw-r-- 1 test test 74696 Mar 18 16:08 kthread.o
-rw-rw-r-- 1 test test 161 Mar 18 16:00 Makefile
-rw-rw-r-- 1 test test 58 Mar 18 16:08 modules.order
-rw-rw-r-- 1 test test 0 Mar 18 16:08 Module.symvers
Run modinfo command to get the information about the kernel module.
test@test-V520-15IKL:~/.../tc_1$ modinfo kthread.ko
filename: $HOME/kthread_examples/kthread.ko
description: Example of kthread_flush_worker
author: Linux Usr
license: GPL
srcversion: 8D2147F67AB01CF0E482DAC
depends:
retpoline: Y
name: kthread
vermagic: 6.7.9 SMP preempt mod_unload modversions
insert the module using insmod command.
test@test-V520-15IKL:~$ sudo insmod ./kthread.ko
check if the module is loaded or not using lsmod command.
test@test-V520-15IKL:~$ sudo lsmod | grep kthread
kthread 16384 0
check if the thread is created or not using ps command.
test@test-V520-15IKL:~$ ps -N | grep kthread_flush_worker
6568 ? 00:00:00 kthread_flush_worker worker example
6569 ? 00:00:00 kthread_flush_worker thread example
check for the kernel messages from init function and thread function once the module is loaded and thread is created.
test@test-V520-15IKL:~$ sudo dmesg
[ 2395.398511] Inside kthread init function
[ 2395.398540] Created kthread_worker
[ 2395.398556] Created kthread task
[ 2395.398558] Inside def_thread_task
[ 2395.505983] Inside def_thread_task
[ 2395.614115] Inside def_thread_task
remove the module from kernel using rmmod command.
test@test-V520-15IKL:~$ sudo rmmod kthread
check if the module is still loaded after removing the kernel module using lsmod if it is not displayed in lsmod output it is verified that the module is removed successfully.
test@test-V520-15IKL:~$ sudo lsmod | grep kthread
test@test-V520-15IKL:~$
check if the thread is destroyed using ps command if it is not displayed in ps output we can confirm that the thread is destroyed successfully.
test@test-V520-15IKL:~$ ps -N | grep kthread_flush_worker
test@test-V520-15IKL:~$
Check for kernel messages from exit function using dmesg command.
test@test-V520-15IKL:~$ sudo dmesg
[ 2405.616976] Inside kthread exit function
[ 2405.617018] Destroyed kthread worker and thread
kthread API |
Learning |
---|---|
kthread_create_worker |
Create kthread worker |
kthread_init_worker |
Initialize kthread worker |
kthread_run |
Create and wake a thread |
kthread_should_stop |
To determine when thread should exit |
kthread_flush_worker |
Complete and flush kthread worker |
kthread_destroy_worker |
Destroy kthread worker |
API |
Learning |
---|---|
MODULE_LICENSE |
Used to denote the license used in the kernel module |
MODULE_AUTHOR |
Used to mention the author of the kernel module |
MODULE_DESCRIPTION |
Used to describe what the module does |
IS_ERR |
Detects an error pointer |
wake_up_process |
wake up a specific process |
msleep |
will put in sleep for a certain amount of msecs time. |
module_init |
Driver initialization entry point |
module_exit |
Driver exit entry point |
pr_info |
Print an info-level message |