Schedule Work
Topics in this section,
# |
Version |
---|---|
Ubuntu |
Ubuntu 22.10 |
Kernel |
6.8.0 |
In this program, you are going to learn
How to create workqueue ?
How to allocate the work to the queue ?
How to use Workqueue APIs ?
How to use below APIs ?
Here is the function prototype of the API: INIT_WORK
#include <linux/workqueue.h>
#define INIT_WORK(_work, _func)
Here is an example of how to use the API,
INIT_WORK(&my_work_1,workqueue_func_1);
Here is the function prototype of the API: schedule_work_on
#include <linux/workqueue.h>
static inline bool schedule_work_on(int cpu, struct work_struct *work);
Here is an example of how to use the API,
schedule_work_on(0,&my_work_1);
Here is the function prototype of the API: cancel_work_sync
#include <linux/workqueue.h>
extern bool cancel_work_sync(struct work_struct *work);
Here is an example of how to use the API,
cancel_work_sync(&my_work_1);
Here is the function prototype of the API: INIT_DELAYED_WORK
#include <linux/workqueue.h>
#define INIT_DELAYED_WORK(_work, _func)
Here is an example of how to use the API,
INIT_DELAYED_WORK(&my_work_1,workqueue_func_1);
Here is the function prototype of the API: schedule_delayed_work_on
#include <linux/workqueue.h>
static inline bool schedule_delayed_work_on(int cpu, struct delayed_work *dwork, unsigned long delay);
Here is an example of how to use the API,
schedule_delayed_work_on(0,&my_work_1,msecs_to_jiffies(100));
Here is the function prototype of the API: cancel_delayed_work_sync
#include <linux/workqueue.h>
extern bool cancel_delayed_work_sync(struct delayed_work *dwork);
Here is an example of how to use the API,
cancel_delayed_work_sync(&my_work_1);
Here is the function prototype of the API: work_on_cpu
#include <linux/workqueue.h>
static inline long work_on_cpu(int cpu, long (*fn)(void *), void *arg);
Here is an example of how to use the API,
work_on_cpu(0,workqueue_func_1,NULL);
work_on_cpu(0,workqueue_func_2,NULL);
Here is the function prototype of the API: work_on_cpu_safe
#include <linux/workqueue.h>
static inline long work_on_cpu_safe(int cpu, long (*fn)(void *), void *arg);
Here is an example of how to use the API,
work_on_cpu_safe(0,workqueue_func_1,NULL);
work_on_cpu_safe(0,workqueue_func_2,NULL);
In this example let’s see how to schedule workqueue 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/workqueue.h>
#include <linux/delay.h>
#include <linux/jiffies.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 schedule_work_on");
Initialize the work which we are going to use in this example
INIT_WORK(&my_work_1,workqueue_func_1);
This function executes when work is queued to workqueue.
void workqueue_func_1(struct work_struct *work)
{
int i = 0;
while (i < 10) {
pr_info("Inside workqueue_func_1\n");
i++;
msleep(500);
}
}
This function executes during execution of queue_start, creates workqueue, intiializes work and queues to the workqueue.
void queue_start(void)
{
INIT_WORK(&my_work_1,workqueue_func_1);
schedule_work_on(0,&my_work_1);
}
This function executes when module is loaded.
static int __init queue_init(void)
{
pr_info("Inside queue_init function\n");
queue_start();
return 0;
}
This function executes during execution of queue_exit, waits until the completion and destroys workqueue.
void queue_stop(void)
{
pr_info("Destroying workqueue\n");
cancel_work_sync(&my_work_1);
}
This function executes when module is unloaded.
static void __exit queue_exit(void)
{
pr_info("Inside queue_exit function\n");
queue_stop();
return;
}
Add the driver entry points which will be executed once the module is inserted or removed from the kernel.
module_init(queue_init);
module_exit(queue_exit);
1#include <linux/init.h>
2#include <linux/kernel.h>
3#include <linux/module.h>
4#include <linux/workqueue.h>
5#include <linux/delay.h>
6#include <linux/jiffies.h>
7
8MODULE_LICENSE("GPL");
9MODULE_AUTHOR("Linux_usr");
10MODULE_DESCRIPTION("Example of schedule_work_on");
11
12struct work_struct my_work_1;
13void workqueue_func_1(struct work_struct *work);
14void queue_start(void);
15void queue_stop(void);
16
17/* workqueue_func_1 - executes when work is queued to workqueue,
18 * prints a statement and sleeps for 1000ms,
19 * stops when i value is greater than 10 */
20
21void workqueue_func_1(struct work_struct *work)
22{
23 int i = 0;
24 while (i < 10) {
25 pr_info("Inside workqueue_func_1\n");
26 i++;
27 msleep(500);
28 }
29}
30
31/* queue_start - executes during execution of queue_start,
32 * creates workqueue,
33 * intiializes work and queues to the workqueue */
34
35void queue_start(void)
36{
37 INIT_WORK(&my_work_1,workqueue_func_1);
38 schedule_work_on(0,&my_work_1);
39}
40
41/* queue_init - executes when module is loaded,
42 * calls queue_start */
43
44static int __init queue_init(void)
45{
46 pr_info("Inside queue_init function\n");
47 queue_start();
48 return 0;
49}
50
51/* queue_stop - executes during execution of queue_exit,
52 * waits until the completion and destroys workqueue */
53
54void queue_stop(void)
55{
56 pr_info("Destroying workqueue\n");
57 cancel_work_sync(&my_work_1);
58}
59
60/* queue_exit - executes when module is unloaded,
61 * calls queue_stop */
62
63static void __exit queue_exit(void)
64{
65 pr_info("Inside queue_exit function\n");
66 queue_stop();
67 return;
68}
69
70module_init(queue_init);
71module_exit(queue_exit);
1obj-m += tc1.o
2all:
3 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
4clean:
5 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Run make to load the kernel module.
$ make
Check if work_queue.ko is generated or not using ls command.
$ ls -l
total 376
-rw-rw-r-- 1 test test 151 Aug 2 11:42 Makefile
-rw-rw-r-- 1 test test 77 Aug 2 13:00 modules.order
-rw-rw-r-- 1 test test 0 Aug 2 13:00 Module.symvers
-rw-rw-r-- 1 test test 1604 Aug 2 11:42 tc1.c
-rw-rw-r-- 1 test test 179336 Aug 2 13:00 tc1.ko
-rw-rw-r-- 1 test test 77 Aug 2 13:00 tc1.mod
-rw-rw-r-- 1 test test 1095 Aug 2 13:00 tc1.mod.c
-rw-rw-r-- 1 test test 149280 Aug 2 13:00 tc1.mod.o
-rw-rw-r-- 1 test test 31528 Aug 2 13:00 tc1.o
Load the module to kernel using insmod command.
$ sudo insmod ./tc1.ko
Check kernel messages to verify if the module is loaded or not.
$ dmesg
[ 2501.281318] Inside queue_init function
[ 2501.281378] Inside workqueue_func_1
[ 2501.786594] Inside workqueue_func_1
[ 2502.298749] Inside workqueue_func_1
[ 2502.810724] Inside workqueue_func_1
[ 2503.322661] Inside workqueue_func_1
[ 2503.834783] Inside workqueue_func_1
[ 2504.346752] Inside workqueue_func_1
[ 2504.858631] Inside workqueue_func_1
[ 2505.370734] Inside workqueue_func_1
[ 2505.882749] Inside workqueue_func_1
Unload the module using rmmod command.
$ sudo rmmod tc1
Check kernel messages to see if the module is unloaded or not.
$ dmesg
[ 2531.335261] Inside queue_exit function
[ 2531.335267] Destroying workqueue
In this example let’s see how to schedule workqueue 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/workqueue.h>
#include <linux/delay.h>
#include <linux/jiffies.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 schedule_delayed_work_on");
Initialize the work which we are going to use in this example
INIT_WORK(&my_work_1,workqueue_func_1);
This function executes when work is queued to workqueue.
void workqueue_func_1(struct work_struct *work)
{
int i = 0;
while (i < 10) {
pr_info("Inside workqueue_func_1\n");
i++;
msleep(500);
}
}
This function executes during execution of queue_start, creates workqueue, intiializes work and queues to the workqueue.
void queue_start(void)
{
INIT_WORK(&my_work_1,workqueue_func_1);
schedule_delayed_work_on(0,&my_work_1,msecs_to_jiffies(100));
}
This function executes when module is loaded.
static int __init queue_init(void)
{
pr_info("Inside queue_init function\n");
queue_start();
return 0;
}
This function executes during execution of queue_exit, waits until the completion and destroys workqueue.
void queue_stop(void)
{
pr_info("Destroying workqueue\n");
cancel_delayed_work_sync(&my_work_1);
}
This function executes when module is unloaded.
static void __exit queue_exit(void)
{
pr_info("Inside queue_exit function\n");
queue_stop();
return;
}
Add the driver entry points which will be executed once the module is inserted or removed from the kernel.
module_init(queue_init);
module_exit(queue_exit);
1#include <linux/init.h>
2#include <linux/kernel.h>
3#include <linux/module.h>
4#include <linux/workqueue.h>
5#include <linux/delay.h>
6#include <linux/jiffies.h>
7
8MODULE_LICENSE("GPL");
9MODULE_AUTHOR("Linux_usr");
10MODULE_DESCRIPTION("Example of schedule_delayed_work_on");
11
12struct delayed_work my_work_1;
13void workqueue_func_1(struct work_struct *work);
14void queue_start(void);
15void queue_stop(void);
16
17/* workqueue_func_1 - executes when work is queued to workqueue,
18 * prints a statement and sleeps for 1000ms,
19 * stops when i value is greater than 10 */
20
21void workqueue_func_1(struct work_struct *work)
22{
23 int i = 0;
24 while (i < 10) {
25 pr_info("Inside workqueue_func_1\n");
26 i++;
27 msleep(500);
28 }
29}
30
31/* queue_start - executes during execution of queue_start,
32 * creates workqueue,
33 * intiializes work and queues to the workqueue */
34
35void queue_start(void)
36{
37 INIT_DELAYED_WORK(&my_work_1,workqueue_func_1);
38 schedule_delayed_work_on(0,&my_work_1,msecs_to_jiffies(100));
39}
40
41/* queue_init - executes when module is loaded,
42 * calls queue_start */
43
44static int __init queue_init(void)
45{
46 pr_info("Inside queue_init function\n");
47 queue_start();
48 return 0;
49}
50
51/* queue_stop - executes during execution of queue_exit,
52 * waits until the completion and destroys workqueue */
53
54void queue_stop(void)
55{
56 pr_info("Destroying workqueue\n");
57 cancel_delayed_work_sync(&my_work_1);
58}
59
60/* queue_exit - executes when module is unloaded,
61 * calls queue_stop */
62
63static void __exit queue_exit(void)
64{
65 pr_info("Inside queue_exit function\n");
66 queue_stop();
67 return;
68}
69
70module_init(queue_init);
71module_exit(queue_exit);
1obj-m += tc22.o
2all:
3 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
4clean:
5 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Run make to load the kernel module.
$ make
Check if work_queue.ko is generated or not using ls command.
$ ls -l
total 376
-rw-rw-r-- 1 test test 151 Aug 2 12:58 Makefile
-rw-rw-r-- 1 test test 85 Aug 2 12:58 modules.order
-rw-rw-r-- 1 test test 0 Aug 2 12:58 Module.symvers
-rw-rw-r-- 1 test test 1659 Aug 2 11:42 tc2.c
-rw-rw-r-- 1 test test 179712 Aug 2 12:58 tc2.ko
-rw-rw-r-- 1 test test 85 Aug 2 12:58 tc2.mod
-rw-rw-r-- 1 test test 1189 Aug 2 12:58 tc2.mod.c
-rw-rw-r-- 1 test test 149424 Aug 2 12:58 tc2.mod.o
-rw-rw-r-- 1 test test 31728 Aug 2 12:58 tc2.o
Load the module to kernel using insmod command.
$ sudo insmod ./tc2.ko
Check kernel messages to verify if the module is loaded or not.
$ dmesg
[ 2358.328633] Inside queue_init function
[ 2358.430764] Inside workqueue_func_1
[ 2358.938739] Inside workqueue_func_1
[ 2359.450680] Inside workqueue_func_1
[ 2359.962748] Inside workqueue_func_1
[ 2360.474731] Inside workqueue_func_1
[ 2360.986714] Inside workqueue_func_1
[ 2361.498682] Inside workqueue_func_1
[ 2362.010688] Inside workqueue_func_1
[ 2362.522739] Inside workqueue_func_1
[ 2363.034725] Inside workqueue_func_1
Unload the module using rmmod command.
$ sudo rmmod tc2
Check kernel messages to see if the module is unloaded or not.
$ dmesg
[ 2391.552930] Inside queue_exit function
[ 2391.552940] Destroying workqueue
In this example let’s see how to schedule workqueue 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/workqueue.h>
#include <linux/delay.h>
#include <linux/jiffies.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 work_on_cpu");
This workqueue_func_1 function executes when work is queued to workqueue.
long int workqueue_func_1(struct work_struct *work)
{
int i = 0;
while (i < 10) {
pr_info("Inside workqueue_func_1\n");
i++;
msleep(500);
}
}
This workqueue_func_2 function executes when work is queued to workqueue.
long int workqueue_func_2(struct work_struct *work)
{
int i = 0;
while (i < 10) {
pr_info("Inside workqueue_func_2\n");
i++;
msleep(500);
}
}
This function executes during execution of queue_start, creates workqueue, intiializes work and queues to the workqueue.
void queue_start(void)
{
work_on_cpu(0,workqueue_func_1,NULL);
work_on_cpu(0,workqueue_func_2,NULL);
}
This function executes when module is loaded.
static int __init queue_init(void)
{
pr_info("Inside queue_init function\n");
queue_start();
return 0;
}
This function executes during execution of queue_exit, waits until the completion and destroys workqueue.
void queue_stop(void)
{
pr_info("Destroying workqueue\n");
}
This function executes when module is unloaded.
static void __exit queue_exit(void)
{
pr_info("Inside queue_exit function\n");
queue_stop();
return;
}
Add the driver entry points which will be executed once the module is inserted or removed from the kernel.
module_init(queue_init);
module_exit(queue_exit);
1#include <linux/init.h>
2#include <linux/kernel.h>
3#include <linux/module.h>
4#include <linux/workqueue.h>
5#include <linux/delay.h>
6#include <linux/jiffies.h>
7
8#define WQ_NAME_1 "tc17_workqueue_1"
9#define WQ_NAME_2 "tc17_workqueue_2"
10
11MODULE_LICENSE("GPL");
12MODULE_AUTHOR("Linux_usr");
13MODULE_DESCRIPTION("Example of work_on_cpu");
14
15long int workqueue_func_1(void *data);
16long int workqueue_func_2(void *data);
17void queue_start(void);
18void queue_stop(void);
19
20/* workqueue_func_1 - executes when work is queued to workqueue,
21 * prints a statement and sleeps for 1000ms,
22 * stops when i value is greater than 10 */
23
24long int workqueue_func_1(void *data)
25{
26 int i = 0;
27 while (i < 10) {
28 pr_info("Inside workqueue_func_1\n");
29 i++;
30 msleep(500);
31 }
32 return 0;
33}
34
35long int workqueue_func_2(void *data)
36{
37 int i = 0;
38 while (i < 10) {
39 pr_info("Inside workqueue_func_2\n");
40 i++;
41 msleep(500);
42 }
43 return 0;
44}
45
46/* queue_start - executes during execution of queue_start,
47 * creates workqueue,
48 * intiializes work and queues to the workqueue */
49
50void queue_start(void)
51{
52 work_on_cpu(0,workqueue_func_1,NULL);
53 work_on_cpu(0,workqueue_func_2,NULL);
54}
55
56/* queue_init - executes when module is loaded,
57 * calls queue_start */
58
59static int __init queue_init(void)
60{
61 pr_info("Inside queue_init function\n");
62 queue_start();
63 return 0;
64}
65
66/* queue_stop - executes during execution of queue_exit,
67 * waits until the completion and destroys workqueue */
68
69void queue_stop(void)
70{
71 pr_info("Destroying workqueue\n");
72}
73
74/* queue_exit - executes when module is unloaded,
75 * calls queue_stop */
76
77static void __exit queue_exit(void)
78{
79 pr_info("Inside queue_exit function\n");
80 queue_stop();
81 return;
82}
83
84module_init(queue_init);
85module_exit(queue_exit);
1obj-m += tc3.o
2all:
3 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
4clean:
5 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Run make to load the kernel module.
$ make
Check if work_queue.ko is generated or not using ls command.
$ ls -l
total 368
-rw-rw-r-- 1 test test 151 Aug 2 11:42 Makefile
-rw-rw-r-- 1 test test 72 Aug 2 13:02 modules.order
-rw-rw-r-- 1 test test 0 Aug 2 13:02 Module.symvers
-rw-rw-r-- 1 test test 1826 Aug 2 11:42 tc3.c
-rw-rw-r-- 1 test test 175808 Aug 2 13:02 tc3.ko
-rw-rw-r-- 1 test test 72 Aug 2 13:02 tc3.mod
-rw-rw-r-- 1 test test 1031 Aug 2 13:02 tc3.mod.c
-rw-rw-r-- 1 test test 149144 Aug 2 13:02 tc3.mod.o
-rw-rw-r-- 1 test test 28160 Aug 2 13:02 tc3.o
Load the module to kernel using insmod command.
$ sudo insmod ./tc3.ko
Check kernel messages to verify if the module is loaded or not.
$ dmesg
[ 2586.720879] Inside queue_init function
[ 2586.720925] Inside workqueue_func_1
[ 2587.226675] Inside workqueue_func_1
[ 2587.738795] Inside workqueue_func_1
[ 2588.250747] Inside workqueue_func_1
[ 2588.762771] Inside workqueue_func_1
[ 2589.274774] Inside workqueue_func_1
[ 2589.786797] Inside workqueue_func_1
[ 2590.298791] Inside workqueue_func_1
[ 2590.810741] Inside workqueue_func_1
[ 2591.322597] Inside workqueue_func_1
[ 2591.834882] Inside workqueue_func_2
[ 2592.346790] Inside workqueue_func_2
[ 2592.858774] Inside workqueue_func_2
[ 2593.370736] Inside workqueue_func_2
[ 2593.882757] Inside workqueue_func_2
[ 2594.394540] Inside workqueue_func_2
[ 2594.906671] Inside workqueue_func_2
[ 2595.418783] Inside workqueue_func_2
[ 2595.930782] Inside workqueue_func_2
[ 2596.442785] Inside workqueue_func_2
Unload the module using rmmod command.
$ sudo rmmod tc3
Check kernel messages to see if the module is unloaded or not.
$ dmesg
[ 2614.919189] Inside queue_exit function
[ 2614.919199] Destroying workqueue
In this example let’s see how to schedule workqueue 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/workqueue.h>
#include <linux/delay.h>
#include <linux/jiffies.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 work_on_cpu_safe");
This workqueue_func_1 function executes when work is queued to workqueue.
long int workqueue_func_1(struct work_struct *work)
{
int i = 0;
while (i < 10) {
pr_info("Inside workqueue_func_1\n");
i++;
msleep(500);
}
}
This workqueue_func_2 function executes when work is queued to workqueue.
long int workqueue_func_2(struct work_struct *work)
{
int i = 0;
while (i < 10) {
pr_info("Inside workqueue_func_2\n");
i++;
msleep(500);
}
}
This function executes during execution of queue_start, creates workqueue, intiializes work and queues to the workqueue.
void queue_start(void)
{
work_on_cpu_safe(0,workqueue_func_1,NULL);
work_on_cpu_safe(0,workqueue_func_2,NULL);
}
This function executes when module is loaded.
static int __init queue_init(void)
{
pr_info("Inside queue_init function\n");
queue_start();
return 0;
}
This function executes during execution of queue_exit, waits until the completion and destroys workqueue.
void queue_stop(void)
{
pr_info("Destroying workqueue\n");
}
This function executes when module is unloaded.
static void __exit queue_exit(void)
{
pr_info("Inside queue_exit function\n");
queue_stop();
return;
}
Add the driver entry points which will be executed once the module is inserted or removed from the kernel.
module_init(queue_init);
module_exit(queue_exit);
1#include <linux/init.h>
2#include <linux/kernel.h>
3#include <linux/module.h>
4#include <linux/workqueue.h>
5#include <linux/delay.h>
6#include <linux/jiffies.h>
7
8#define WQ_NAME_1 "tc17_workqueue_1"
9#define WQ_NAME_2 "tc17_workqueue_2"
10
11MODULE_LICENSE("GPL");
12MODULE_AUTHOR("Linux_usr");
13MODULE_DESCRIPTION("Example of work_on_cpu_safe");
14
15long int workqueue_func_1(void *data);
16long int workqueue_func_2(void *data);
17void queue_start(void);
18void queue_stop(void);
19
20/* workqueue_func_1 - executes when work is queued to workqueue,
21 * prints a statement and sleeps for 1000ms,
22 * stops when i value is greater than 10 */
23
24long int workqueue_func_1(void *data)
25{
26 int i = 0;
27 while (i < 10) {
28 pr_info("Inside workqueue_func_1\n");
29 i++;
30 msleep(500);
31 }
32 return 0;
33}
34
35long int workqueue_func_2(void *data)
36{
37 int i = 0;
38 while (i < 10) {
39 pr_info("Inside workqueue_func_2\n");
40 i++;
41 msleep(500);
42 }
43 return 0;
44}
45
46/* queue_start - executes during execution of queue_start,
47 * creates workqueue,
48 * intiializes work and queues to the workqueue */
49
50void queue_start(void)
51{
52 work_on_cpu_safe(0,workqueue_func_1,NULL);
53 work_on_cpu_safe(0,workqueue_func_2,NULL);
54}
55
56/* queue_init - executes when module is loaded,
57 * calls queue_start */
58
59static int __init queue_init(void)
60{
61 pr_info("Inside queue_init function\n");
62 queue_start();
63 return 0;
64}
65
66/* queue_stop - executes during execution of queue_exit,
67 * waits until the completion and destroys workqueue */
68
69void queue_stop(void)
70{
71 pr_info("Destroying workqueue\n");
72}
73
74/* queue_exit - executes when module is unloaded,
75 * calls queue_stop */
76
77static void __exit queue_exit(void)
78{
79 pr_info("Inside queue_exit function\n");
80 queue_stop();
81 return;
82}
83
84module_init(queue_init);
85module_exit(queue_exit);
1obj-m += tc4.o
2all:
3 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
4clean:
5 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Run make to load the kernel module.
$ make
Check if work_queue.ko is generated or not using ls command.
$ ls -l
total 368
-rw-rw-r-- 1 test test 151 Aug 2 11:42 Makefile
-rw-rw-r-- 1 test test 77 Aug 2 13:06 modules.order
-rw-rw-r-- 1 test test 0 Aug 2 13:06 Module.symvers
-rw-rw-r-- 1 test test 1836 Aug 2 11:42 tc4.c
-rw-rw-r-- 1 test test 175832 Aug 2 13:06 tc4.ko
-rw-rw-r-- 1 test test 77 Aug 2 13:06 tc4.mod
-rw-rw-r-- 1 test test 1036 Aug 2 13:06 tc4.mod.c
-rw-rw-r-- 1 test test 149152 Aug 2 13:06 tc4.mod.o
-rw-rw-r-- 1 test test 28184 Aug 2 13:06 tc4.o
Load the module to kernel using insmod command.
$ sudo insmod ./tc4.ko
Check kernel messages to verify if the module is loaded or not.
$ dmesg
[ 2840.301249] Inside queue_init function
[ 2840.301327] Inside workqueue_func_1
[ 2840.826763] Inside workqueue_func_1
[ 2841.338795] Inside workqueue_func_1
[ 2841.850758] Inside workqueue_func_1
[ 2842.362763] Inside workqueue_func_1
[ 2842.874753] Inside workqueue_func_1
[ 2843.386787] Inside workqueue_func_1
[ 2843.898748] Inside workqueue_func_1
[ 2844.410762] Inside workqueue_func_1
[ 2844.922632] Inside workqueue_func_1
[ 2845.434911] Inside workqueue_func_2
[ 2845.946770] Inside workqueue_func_2
[ 2846.458715] Inside workqueue_func_2
[ 2846.970762] Inside workqueue_func_2
[ 2847.482759] Inside workqueue_func_2
[ 2847.994557] Inside workqueue_func_2
[ 2848.506718] Inside workqueue_func_2
[ 2849.018758] Inside workqueue_func_2
[ 2849.530761] Inside workqueue_func_2
[ 2850.042761] Inside workqueue_func_2
Unload the module using rmmod command.
$ sudo rmmod tc4
Check kernel messages to see if the module is unloaded or not.
$ dmesg
[ 2866.416509] Inside queue_exit function
[ 2866.416516] Destroying workqueue