Create Dynamic 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 below APIs ?
Here is the function prototype of the API: create_workqueue
#include <linux/workqueue.h>
#define create_workqueue(name)
Here is an example of how to use the API,
my_workqueue = create_workqueue(WQ_NAME);
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: queue_work
#include <linux/workqueue.h>
static inline bool queue_work(struct workqueue_struct *wq, struct work_struct *work);
Here is an example of how to use the API,
queue_work(my_workqueue,&my_work_1);
Here is the function prototype of the API: queue_work
#include <linux/workqueue.h>
extern void destroy_workqueue(struct workqueue_struct *wq);
Here is an example of how to use the API,
destroy_workqueue(my_workqueue);
Here is the function prototype of the API: INIT_WORK_ONSTACK
#include <linux/workqueue.h>
#define INIT_WORK_ONSTACK(_work, _func)
Here is an example of how to use the API,
INIT_WORK_ONSTACK(&my_work_1,workqueue_func_1);
INIT_WORK_ONSTACK(&my_work_2,workqueue_func_2);
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);
INIT_DELAYED_WORK(&my_work_2,workqueue_func_2);
Here is the function prototype of the API: queue_delayed_work
#include <linux/workqueue.h>
static inline bool queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *dwork, unsigned long delay);
Here is an example of how to use the API,
queue_delayed_work(my_workqueue,&my_work_1,msecs_to_jiffies(100));
queue_delayed_work(my_workqueue,&my_work_2,msecs_to_jiffies(300));
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);
cancel_delayed_work_sync(&my_work_2);
Here is the function prototype of the API: INIT_DELAYED_WORK_ONSTACK
#include <linux/workqueue.h>
#define INIT_DELAYED_WORK_ONSTACK(_work, _func)
Here is an example of how to use the API,
INIT_DELAYED_WORK_ONSTACK(&my_work,workqueue_func);
Here is the function prototype of the API: INIT_DEFERRABLE_WORK
#include <linux/workqueue.h>
#define INIT_DEFERRABLE_WORK(_work, _func)
Here is an example of how to use the API,
INIT_DEFERRABLE_WORK(&my_work,workqueue_func);
Here is the function prototype of the API: schedule_delayed_work
#include <linux/workqueue.h>
static inline bool schedule_delayed_work(struct delayed_work *dwork, unsigned long delay);
Here is an example of how to use the API,
schedule_delayed_work(&my_work,msecs_to_jiffies(100));
Here is the function prototype of the API: cancel_delayed_work
#include <linux/workqueue.h>
extern bool cancel_delayed_work(struct delayed_work *dwork);
Here is an example of how to use the API,
cancel_delayed_work(&my_work);
Here is the function prototype of the API: INIT_RCU_WORK
#include <linux/workqueue.h>
#define INIT_RCU_WORK(_work, _func)
Here is an example of how to use the API,
INIT_RCU_WORK(&my_work,workqueue_func);
Here is the function prototype of the API: queue_rcu_work
#include <linux/workqueue.h>
extern bool queue_rcu_work(struct workqueue_struct *wq, struct rcu_work *rwork);
Here is an example of how to use the API,
queue_rcu_work(my_workqueue,&my_work);
Here is the function prototype of the API: flush_workqueue
#include <linux/workqueue.h>
#define flush_workqueue(wq)
Here is an example of how to use the API,
flush_workqueue(my_workqueue);
In this example let’s see how to create 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 INIT_WORK");
Initialize the work which we are going to use in this example
INIT_WORK(&my_work_1,workqueue_func_1);
INIT_WORK(&my_work_2,workqueue_func_2);
This workqueue_func_1 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(1000);
}
}
This workqueue_func_2 function executes when work is queued to workqueue.
void workqueue_func_2(struct work_struct *work)
{
pr_info("Inside workqueue_func_2\n");
}
This function creates workqueue, intiializes work and queues to the workqueue.
void queue_start(void)
{
my_work_queue = create_workqueue(WQ_NAME);
INIT_WORK(&my_work_1,workqueue_func_1);
INIT_WORK(&my_work_2,workqueue_func_2);
queue_work(my_work_queue,&my_work_2);
queue_work(my_work_queue,&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)
{
destroy_workqueue(my_workqueue);
}
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
7#define WQ_NAME "tc1_workqueue"
8
9MODULE_LICENSE("GPL");
10MODULE_AUTHOR("Linux_usr");
11MODULE_DESCRIPTION("Example of INIT_WORK");
12
13struct work_struct my_work_1;
14struct work_struct my_work_2;
15struct workqueue_struct *my_work_queue;
16void workqueue_func_1(struct work_struct *work);
17void workqueue_func_2(struct work_struct *work);
18void queue_start(void);
19void queue_stop(void);
20
21/* workqueue_func_1 - executes when work_1 is queued to workqueue,
22 * prints a statements and sleeps for 1000 secs,
23 * stops when i values goes greater than 10 */
24
25void workqueue_func_1(struct work_struct *work)
26{
27 int i = 0;
28 while(i < 10){
29 pr_info("Inside workqueue_func_1\n");
30 i++;
31 msleep(1000);
32 }
33}
34
35/* workqueue_func_2 - executes when work_2 is queued to workqueue,
36 * prints a statements and exits from the function */
37
38void workqueue_func_2(struct work_struct *work)
39{
40 pr_info("Inside workqueue_func_2\n");
41}
42
43/* queue_start - executes when the module is initialized,
44 * creates workqueue,
45 * initializes work and queues to workqueue */
46
47void queue_start(void)
48{
49 my_work_queue = create_workqueue(WQ_NAME);
50 INIT_WORK(&my_work_1,workqueue_func_1);
51 INIT_WORK(&my_work_2,workqueue_func_2);
52 queue_work(my_work_queue,&my_work_2);
53 queue_work(my_work_queue,&my_work_1);
54}
55
56/* queue_init - calls when module is inserted,
57 * calls queue_start function */
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 - calls during the execution of queue_exit,
67 * destroys the workqueue */
68
69void queue_stop(void)
70{
71 destroy_workqueue(my_work_queue);
72}
73
74/* queue_exit - executes when the module is removed,
75 * calls queue_stop function */
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 += 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 384
-rw-rw-r-- 1 test test 151 Aug 2 11:47 Makefile
-rw-rw-r-- 1 test test 76 Aug 2 12:48 modules.order
-rw-rw-r-- 1 test test 0 Aug 2 12:48 Module.symvers
-rw-rw-r-- 1 test test 2040 Aug 2 11:47 tc1.c
-rw-rw-r-- 1 test test 180944 Aug 2 12:48 tc1.ko
-rw-rw-r-- 1 test test 76 Aug 2 12:48 tc1.mod
-rw-rw-r-- 1 test test 1103 Aug 2 12:48 tc1.mod.c
-rw-rw-r-- 1 test test 149280 Aug 2 12:48 tc1.mod.o
-rw-rw-r-- 1 test test 33112 Aug 2 12:48 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
[ 1812.726131] Inside queue_init function
[ 1812.726612] Inside workqueue_func_2
[ 1812.726979] Inside workqueue_func_1
[ 1813.754717] Inside workqueue_func_1
[ 1814.778711] Inside workqueue_func_1
[ 1815.802723] Inside workqueue_func_1
[ 1816.826704] Inside workqueue_func_1
[ 1817.850705] Inside workqueue_func_1
[ 1818.874707] Inside workqueue_func_1
[ 1819.898722] Inside workqueue_func_1
[ 1820.922729] Inside workqueue_func_1
[ 1821.946714] 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
[ 1835.094347] Inside queue_exit function
In this example let’s see how to create 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 INIT_WORK_ONSTACK");
Initialize the work which we are going to use in this example
INIT_WORK_ONSTACK(&my_work_1,workqueue_func_1);
INIT_WORK_ONSTACK(&my_work_2,workqueue_func_2);
This workqueue_func_1 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(1000);
}
}
This workqueue_func_2 function executes when work is queued to workqueue.
void workqueue_func_2(struct work_struct *work)
{
int i = 0;
while (i < 10) {
pr_info("Inside workqueue_func_2\n");
i++;
msleep(1000);
}
}
This function creates workqueue, intiializes work and queues to the workqueue.
void queue_start(void)
{
my_workqueue_1 = create_workqueue(WQ_NAME_1);
my_workqueue_2 = create_workqueue(WQ_NAME_2);
INIT_WORK_ONSTACK(&my_work_1,workqueue_func_1);
INIT_WORK_ONSTACK(&my_work_2,workqueue_func_2);
queue_work(my_work_queue,&my_work_2);
queue_work(my_work_queue,&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)
{
destroy_workqueue(my_workqueue);
destroy_workqueue(my_workqueue_2);
}
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
7#define WQ_NAME_1 "tc2_workqueue_1"
8#define WQ_NAME_2 "tc2_workqueue_2"
9
10MODULE_LICENSE("GPL");
11MODULE_AUTHOR("Linux_usr");
12MODULE_DESCRIPTION("Example of INIT_WORK_ONSTACK");
13
14struct workqueue_struct *my_workqueue_1;
15struct workqueue_struct *my_workqueue_2;
16struct work_struct my_work_1;
17struct work_struct my_work_2;
18void workqueue_func_1(struct work_struct *work);
19void workqueue_func_2(struct work_struct *work);
20void queue_start(void);
21void queue_stop(void);
22
23/* workqueue_func_1 - executes when work_1 is queued to workqueue,
24 * prints a statement and sleeps for 1000ms,
25 * stops when i value goes greater than 10 */
26
27void workqueue_func_1(struct work_struct *work)
28{
29 int i = 0;
30 while (i < 10) {
31 pr_info("Inside workqueue_func_1\n");
32 i++;
33 msleep(1000);
34 }
35}
36
37/* workqueue_func_2 - executes when work_2 is queued to workqueue,
38 * prints a statement and sleeps for 1000ms,
39 * stops when i value goes greater than 10 */
40
41void workqueue_func_2(struct work_struct *work)
42{
43 int i = 0;
44 while (i < 10) {
45 pr_info("Inside workqueue_func_2\n");
46 i++;
47 msleep(1000);
48 }
49}
50
51/* queue_start - executes during the execution of queue_init,
52 * creates workqueues,
53 * intializes work and queues to the workqueue */
54
55void queue_start(void)
56{
57 my_workqueue_1 = create_workqueue(WQ_NAME_1);
58 my_workqueue_2 = create_workqueue(WQ_NAME_2);
59 INIT_WORK_ONSTACK(&my_work_1,workqueue_func_1);
60 INIT_WORK_ONSTACK(&my_work_2,workqueue_func_2);
61 queue_work(my_workqueue_1,&my_work_1);
62 queue_work(my_workqueue_2,&my_work_2);
63}
64
65/* queue_init - executes during the module insertion,
66 * calls queue_start */
67
68static int __init queue_init(void)
69{
70 pr_info("Inside queue_init function\n");
71 queue_start();
72 return 0;
73}
74
75/* queue_stop - executes during the execution of queue_exit,
76 * destroys workqueues */
77
78void queue_stop(void)
79{
80 destroy_workqueue(my_workqueue_1);
81 destroy_workqueue(my_workqueue_2);
82}
83
84/* queue_exit - executes during the removal of module,
85 * calls queue_stop */
86
87static void __exit queue_exit(void)
88{
89 pr_info("Inside queue_exit function\n");
90 queue_stop();
91 return;
92}
93
94module_init(queue_init);
95module_exit(queue_exit);
1obj-m += tc2.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 384
-rw-rw-r-- 1 test test 151 Aug 2 11:47 Makefile
-rw-rw-r-- 1 test test 84 Aug 2 12:51 modules.order
-rw-rw-r-- 1 test test 0 Aug 2 12:51 Module.symvers
-rw-rw-r-- 1 test test 2356 Aug 2 11:47 tc2.c
-rw-rw-r-- 1 test test 181992 Aug 2 12:51 tc2.ko
-rw-rw-r-- 1 test test 84 Aug 2 12:51 tc2.mod
-rw-rw-r-- 1 test test 1103 Aug 2 12:51 tc2.mod.c
-rw-rw-r-- 1 test test 149296 Aug 2 12:51 tc2.mod.o
-rw-rw-r-- 1 test test 34160 Aug 2 12:51 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
[ 1927.976881] Inside queue_init function
[ 1927.977802] Inside workqueue_func_1
[ 1927.977886] Inside workqueue_func_2
[ 1928.986617] Inside workqueue_func_2
[ 1928.986634] Inside workqueue_func_1
[ 1930.010693] Inside workqueue_func_2
[ 1930.010731] Inside workqueue_func_1
[ 1931.034722] Inside workqueue_func_2
[ 1931.034739] Inside workqueue_func_1
[ 1932.058735] Inside workqueue_func_2
[ 1932.058751] Inside workqueue_func_1
[ 1933.082732] Inside workqueue_func_2
[ 1933.082760] Inside workqueue_func_1
[ 1934.106692] Inside workqueue_func_1
[ 1934.106709] Inside workqueue_func_2
[ 1935.130737] Inside workqueue_func_2
[ 1935.130753] Inside workqueue_func_1
[ 1936.154741] Inside workqueue_func_1
[ 1936.154758] Inside workqueue_func_2
[ 1937.178738] Inside workqueue_func_2
[ 1937.178755] 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
[ 1955.215382] Inside queue_exit function
In this example let’s see how to create 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 INIT_DELAYED_WORK");
Initialize the work which we are going to use in this example
INIT_DELAYED_WORK(&my_work_1,workqueue_func_1);
INIT_DELAYED_WORK(&my_work_2,workqueue_func_2);
This workqueue_func_1 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(1000);
}
}
This workqueue_func_2 function executes when work is queued to workqueue.
void workqueue_func_2(struct work_struct *work)
{
int i = 0;
while (i < 10) {
pr_info("Inside workqueue_func_2\n");
i++;
msleep(1000);
}
}
This function creates workqueue, intiializes work and queues to the workqueue.
void queue_start(void)
{
my_workqueue = create_workqueue(WQ_NAME);
INIT_DELAYED_WORK(&my_work_1,workqueue_func_1);
INIT_DELAYED_WORK(&my_work_2,workqueue_func_2);
queue_delayed_work(my_workqueue,&my_work_1,msecs_to_jiffies(100));
queue_delayed_work(my_workqueue,&my_work_2,msecs_to_jiffies(300));
}
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)
{
cancel_delayed_work_sync(&my_work_1);
cancel_delayed_work_sync(&my_work_2);
pr_info("Destroying workqueue\n");
destroy_workqueue(my_workqueue);
}
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 "tc3_workqueue"
9
10MODULE_LICENSE("GPL");
11MODULE_AUTHOR("Linux_usr");
12MODULE_DESCRIPTION("Example of INIT_DELAYED_WORK");
13
14struct workqueue_struct *my_workqueue;
15struct delayed_work my_work_1;
16struct delayed_work my_work_2;
17void workqueue_func_1(struct work_struct *work);
18void workqueue_func_2(struct work_struct *work);
19void queue_start(void);
20void queue_stop(void);
21
22/* workqueue_func_1 - exectues when work_1 is queued to workqueue,
23 * prints a statement and sleeps for 1000ms,
24 * stops when i value goes greater than 10 */
25
26void workqueue_func_1(struct work_struct *work)
27{
28 int i = 0;
29 while (i < 10) {
30 pr_info("Inside workqueue_func_1\n");
31 i++;
32 msleep(1000);
33 }
34}
35
36/* workqueue_func_2 - executes when work_2 is queued to workqueue,
37 * prints a statement and sleeps for 1000ms,
38 * stops when i value goes greater than 10ms */
39
40void workqueue_func_2(struct work_struct *work)
41{
42 int i = 0;
43 while (i < 10) {
44 pr_info("Inside workqueue_func_2\n");
45 i++;
46 msleep(1000);
47 }
48}
49
50/* queue_start - executes during execution of queue_init,
51 * creates workqueue,
52 * initializes work and queues to the workqueue */
53
54void queue_start(void)
55{
56 my_workqueue = create_workqueue(WQ_NAME);
57 INIT_DELAYED_WORK(&my_work_1,workqueue_func_1);
58 INIT_DELAYED_WORK(&my_work_2,workqueue_func_2);
59 queue_delayed_work(my_workqueue,&my_work_1,msecs_to_jiffies(100));
60 queue_delayed_work(my_workqueue,&my_work_2,msecs_to_jiffies(300));
61}
62
63/* queue_init - executes when the module is inserted,
64 * calls queue_start */
65
66static int __init queue_init(void)
67{
68 pr_info("Inside queue_init function\n");
69 queue_start();
70 return 0;
71}
72
73/* queue_stop - executes during the execution of queue_exit,
74 * destroys work and workqueues */
75
76void queue_stop(void)
77{
78 cancel_delayed_work_sync(&my_work_1);
79 cancel_delayed_work_sync(&my_work_2);
80 pr_info("Destroying workqueue\n");
81 destroy_workqueue(my_workqueue);
82}
83
84/* queue_exit - executes when the module is removed,
85 * calls queue_stop */
86
87static void __exit queue_exit(void)
88{
89 pr_info("Inside queue_exit function\n");
90 queue_stop();
91 return;
92}
93
94module_init(queue_init);
95module_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 388
-rw-rw-r-- 1 test test 151 Aug 2 11:47 Makefile
-rw-rw-r-- 1 test test 84 Aug 2 12:42 modules.order
-rw-rw-r-- 1 test test 0 Aug 2 12:42 Module.symvers
-rw-rw-r-- 1 test test 2390 Aug 2 11:47 tc3.c
-rw-rw-r-- 1 test test 184616 Aug 2 12:42 tc3.ko
-rw-rw-r-- 1 test test 84 Aug 2 12:42 tc3.mod
-rw-rw-r-- 1 test test 1233 Aug 2 12:42 tc3.mod.c
-rw-rw-r-- 1 test test 149488 Aug 2 12:42 tc3.mod.o
-rw-rw-r-- 1 test test 36616 Aug 2 12:42 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
[ 1400.538722] Inside workqueue_func_1
[ 1401.562742] Inside workqueue_func_1
[ 1402.586747] Inside workqueue_func_1
[ 1403.610761] Inside workqueue_func_1
[ 1404.634741] Inside workqueue_func_1
[ 1405.658741] Inside workqueue_func_1
[ 1406.682728] Inside workqueue_func_2
[ 1407.706664] Inside workqueue_func_2
[ 1408.730598] Inside workqueue_func_2
[ 1409.754723] Inside workqueue_func_2
[ 1410.778722] Inside workqueue_func_2
[ 1411.802725] Inside workqueue_func_2
[ 1412.826721] Inside workqueue_func_2
[ 1413.850751] Inside workqueue_func_2
[ 1414.874732] Inside workqueue_func_2
[ 1415.898674] 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
[ 1428.223989] Inside queue_exit function
[ 1428.223998] Destroying workqueue
In this example let’s see how to create 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 INIT_DELAYED_WORK");
Initialize the work which we are going to use in this example
INIT_DELAYED_WORK(&my_work_1,workqueue_func_1);
INIT_DELAYED_WORK(&my_work_2,workqueue_func_2);
This workqueue_func_1 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(1000);
}
}
This workqueue_func_2 function executes when work is queued to workqueue.
void workqueue_func_2(struct work_struct *work)
{
int i = 0;
while (i < 10) {
pr_info("Inside workqueue_func_2\n");
i++;
msleep(1000);
}
}
This function creates workqueue, intiializes work and queues to the workqueue.
void queue_start(void)
{
my_workqueue = create_workqueue(WQ_NAME);
INIT_DELAYED_WORK_ONSTACK(&my_work,workqueue_func);
queue_delayed_work(my_workqueue,&my_work,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");
destroy_workqueue(my_workqueue);
}
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 "tc4_workqueue"
9
10MODULE_LICENSE("GPL");
11MODULE_AUTHOR("Linux_usr");
12MODULE_DESCRIPTION("Example of INIT_DELAYED_WORK_ONSTACK");
13
14struct workqueue_struct *my_workqueue;
15struct delayed_work my_work;
16void workqueue_func(struct work_struct *work);
17void queue_start(void);
18void queue_stop(void);
19
20/* workqueue_func - executes when work is queued to workqueue,
21 * prints a statement and sleeps for 1000ms,
22 * stops when i value goes greater than 10 */
23
24void workqueue_func(struct work_struct *work)
25{
26 int i = 0;
27 while (i < 10) {
28 pr_info("Inside workqueue_func\n");
29 i++;
30 msleep(1000);
31 }
32}
33
34/* queue_start - executes during the execution of queue_init,
35 * creates workqueue,
36 * initializes work and queues it to workqueue */
37
38void queue_start(void)
39{
40 my_workqueue = create_workqueue(WQ_NAME);
41 INIT_DELAYED_WORK_ONSTACK(&my_work,workqueue_func);
42 queue_delayed_work(my_workqueue,&my_work,msecs_to_jiffies(100));
43}
44
45/* queue_init - executes during the module initialization,
46 * calls queue_start */
47
48static int __init queue_init(void)
49{
50 pr_info("Inside queue_init function\n");
51 queue_start();
52 return 0;
53}
54
55/* queue_stop - executes during execution of queue_exit,
56 * destroys the workqueue */
57
58void queue_stop(void)
59{
60 pr_info("Destroying workqueue\n");
61 destroy_workqueue(my_workqueue);
62}
63
64/* queue_exit - executes during the execution of queue_exit,
65 * calls queue_stop */
66
67static void __exit queue_exit(void)
68{
69 pr_info("Inside queue_exit function\n");
70 queue_stop();
71 return;
72}
73
74module_init(queue_init);
75module_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 384
-rw-rw-r-- 1 test test 151 Aug 2 11:47 Makefile
-rw-rw-r-- 1 test test 92 Aug 2 12:44 modules.order
-rw-rw-r-- 1 test test 0 Aug 2 12:44 Module.symvers
-rw-rw-r-- 1 test test 1770 Aug 2 11:47 tc4.c
-rw-rw-r-- 1 test test 181696 Aug 2 12:44 tc4.ko
-rw-rw-r-- 1 test test 92 Aug 2 12:44 tc4.mod
-rw-rw-r-- 1 test test 1188 Aug 2 12:44 tc4.mod.c
-rw-rw-r-- 1 test test 149440 Aug 2 12:44 tc4.mod.o
-rw-rw-r-- 1 test test 33672 Aug 2 12:44 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
[ 1558.768976] Inside queue_init function
[ 1558.870683] Inside workqueue_func
[ 1559.902483] Inside workqueue_func
[ 1560.922696] Inside workqueue_func
[ 1561.946674] Inside workqueue_func
[ 1562.970693] Inside workqueue_func
[ 1563.994707] Inside workqueue_func
[ 1565.018698] Inside workqueue_func
[ 1566.042704] Inside workqueue_func
[ 1567.066717] Inside workqueue_func
[ 1568.090639] Inside workqueue_func
Unload the module using rmmod command.
$ sudo rmmod tc4
Check kernel messages to see if the module is unloaded or not.
$ dmesg
[ 1578.489697] Inside queue_exit function
[ 1578.489703] Destroying workqueue
In this example let’s see how to create 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 INIT_DEFERRABLE_WORK");
Initialize the work which we are going to use in this example
INIT_DEFERRABLE_WORK(&my_work,workqueue_func);
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(1000);
}
}
This function creates workqueue, intiializes work and queues to the workqueue.
void queue_start(void)
{
INIT_DEFERRABLE_WORK(&my_work,workqueue_func);
schedule_delayed_work(&my_work,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(&my_work);
}
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 INIT_DEFERRABLE_WORK");
11
12struct delayed_work my_work;
13void workqueue_func(struct work_struct *work);
14void queue_start(void);
15void queue_stop(void);
16
17/* workqueue_func - 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(struct work_struct *work)
22{
23 int i = 0;
24 while (i < 10) {
25 pr_info("Inside workqueue_func\n");
26 i++;
27 msleep(1000);
28 }
29}
30
31/* queue_start - executes during the execution of queue_init,
32 * initializes work and schedule the work */
33
34void queue_start(void)
35{
36 INIT_DEFERRABLE_WORK(&my_work,workqueue_func);
37 schedule_delayed_work(&my_work,msecs_to_jiffies(100));
38}
39
40/* queue_init - executes during module initialization,
41 * calls queue_start */
42
43static int __init queue_init(void)
44{
45 pr_info("Inside queue_init function\n");
46 queue_start();
47 return 0;
48}
49
50/* queue_stop - executes during the execution of queue_exit,
51 * destroys the work after its completion */
52
53void queue_stop(void)
54{
55 pr_info("Destroying workqueue\n");
56 cancel_delayed_work(&my_work);
57}
58
59/* queue_exit - executes during removal of module,
60 * calls queue_exit */
61
62static void __exit queue_exit(void)
63{
64 pr_info("Inside queue_exit function\n");
65 queue_stop();
66 return;
67}
68
69module_init(queue_init);
70module_exit(queue_exit);
1obj-m += tc5.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:47 Makefile
-rw-rw-r-- 1 test test 87 Aug 2 12:39 modules.order
-rw-rw-r-- 1 test test 0 Aug 2 12:39 Module.symvers
-rw-rw-r-- 1 test test 1607 Aug 2 11:47 tc5.c
-rw-rw-r-- 1 test test 180088 Aug 2 12:39 tc5.ko
-rw-rw-r-- 1 test test 87 Aug 2 12:39 tc5.mod
-rw-rw-r-- 1 test test 1184 Aug 2 12:39 tc5.mod.c
-rw-rw-r-- 1 test test 149424 Aug 2 12:39 tc5.mod.o
-rw-rw-r-- 1 test test 32096 Aug 2 12:39 tc5.o
Load the module to kernel using insmod command.
$ sudo insmod ./tc5.ko
Check kernel messages to verify if the module is loaded or not.
$ dmesg
[ 1244.134006] Inside queue_init function
[ 1248.986733] Inside workqueue_func
[ 1250.010739] Inside workqueue_func
[ 1251.034686] Inside workqueue_func
[ 1252.058733] Inside workqueue_func
[ 1253.082743] Inside workqueue_func
[ 1254.106735] Inside workqueue_func
[ 1255.130726] Inside workqueue_func
[ 1256.154716] Inside workqueue_func
[ 1257.178737] Inside workqueue_func
[ 1258.202672] Inside workqueue_func
Unload the module using rmmod command.
$ sudo rmmod tc5
Check kernel messages to see if the module is unloaded or not.
$ dmesg
[ 1280.080401] Inside queue_exit function
[ 1280.080405] Destroying workqueue
In this example let’s see how to create 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 INIT_DEFERRABLE_WORK");
Initialize the work which we are going to use in this example
INIT_DEFERRABLE_WORK(&my_work,workqueue_func);
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(1000);
}
}
This function creates workqueue, intiializes work and queues to the workqueue.
void queue_start(void)
{
INIT_DEFERRABLE_WORK(&my_work,workqueue_func);
schedule_delayed_work(&my_work,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(&my_work);
}
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 "tc6_workqueue"
9
10MODULE_LICENSE("GPL");
11MODULE_AUTHOR("Linux_usr");
12MODULE_DESCRIPTION("Example of INIT_RCU_WORK");
13
14struct workqueue_struct *my_workqueue;
15struct rcu_work my_work;
16void workqueue_func(struct work_struct *work);
17void queue_start(void);
18void queue_stop(void);
19
20/* workqueue_func - 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
24void workqueue_func(struct work_struct *work)
25{
26 int i = 0;
27 while (i < 10) {
28 pr_info("Inside workqueue_func\n");
29 i++;
30 msleep(1000);
31 }
32}
33
34/* queue_start - executes during execution of queue_start,
35 * creates workqueue,
36 * intiializes work and queues to the workqueue */
37
38void queue_start(void)
39{
40 my_workqueue = create_workqueue(WQ_NAME);
41 INIT_RCU_WORK(&my_work,workqueue_func);
42 queue_rcu_work(my_workqueue,&my_work);
43}
44
45/* queue_init - executes when module is loaded,
46 * calls queue_start */
47
48static int __init queue_init(void)
49{
50 pr_info("Inside queue_init function\n");
51 queue_start();
52 return 0;
53}
54
55/* queue_stop - executes during execution of queue_exit,
56 * waits until the completion and destroys workqueue */
57
58void queue_stop(void)
59{
60 pr_info("Destroying workqueue\n");
61 flush_workqueue(my_workqueue);
62}
63
64/* queue_exit - executes when module is unloaded,
65 * calls queue_stop */
66
67static void __exit queue_exit(void)
68{
69 pr_info("Inside queue_exit function\n");
70 queue_stop();
71 return;
72}
73
74module_init(queue_init);
75module_exit(queue_exit);
1obj-m += tc6.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 380
-rw-rw-r-- 1 test test 151 Aug 2 11:47 Makefile
-rw-rw-r-- 1 test test 80 Aug 2 12:46 modules.order
-rw-rw-r-- 1 test test 0 Aug 2 12:46 Module.symvers
-rw-rw-r-- 1 test test 1715 Aug 2 11:47 tc6.c
-rw-rw-r-- 1 test test 180448 Aug 2 12:46 tc6.ko
-rw-rw-r-- 1 test test 80 Aug 2 12:46 tc6.mod
-rw-rw-r-- 1 test test 1104 Aug 2 12:46 tc6.mod.c
-rw-rw-r-- 1 test test 149288 Aug 2 12:46 tc6.mod.o
-rw-rw-r-- 1 test test 32624 Aug 2 12:46 tc6.o
Load the module to kernel using insmod command.
$ sudo insmod ./tc6.ko
Check kernel messages to verify if the module is loaded or not.
$ dmesg
[ 1708.830257] Inside queue_init function
[ 1708.870492] Inside workqueue_func
[ 1709.882740] Inside workqueue_func
[ 1710.906743] Inside workqueue_func
[ 1711.930741] Inside workqueue_func
[ 1712.954710] Inside workqueue_func
[ 1713.978702] Inside workqueue_func
[ 1715.002762] Inside workqueue_func
[ 1716.026772] Inside workqueue_func
[ 1717.050761] Inside workqueue_func
[ 1718.074730] Inside workqueue_func
Unload the module using rmmod command.
$ sudo rmmod tc6
Check kernel messages to see if the module is unloaded or not.
$ dmesg
[ 1730.664537] Inside queue_exit function
[ 1730.664543] Destroying workqueue