Workqueue : queue_work: periodic
In this program, you are going to learn
How to schedule a specific workqueue periodically ?
How to use the below API’s ?
Topics in this section,
queue_work
is a function used to schedule a work item for execution on a specific workqueue. For example,
queue_work(system_wq, &q_work);
cancel_work_sync
is a function used to cancel a scheduled work item and wait for it to complete before returning. For example,
cancel_work_sync(&q_work);
To schedule a specific workqueue periodically, we need to call
queue_work
inside theworkqueue_func
.
static void workqueue_func(struct work_struct * work)
{
pr_info("Inside Workqueue function\n");
queue_work(system_wq, &q_work);
}
Here is the explanation of the source code.
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/workqueue.h>
Include the headers file to refer the APIs used in this program.
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Linux_usr");
MODULE_DESCRIPTION("Workqueue");
Add the modules macro which contains the information of module such as license, author and description.
void workqueue_func(struct work_struct *work);
static struct work_struct q_work;
Initialize the variables and APIs which is used in this program.
static int __init queue_init(void)
{
INIT_WORK(&q_work, workqueue_func);
queue_work(system_wq, &q_work);
pr_info("Driver Loaded\n");
return 0;
}
Create the module init function which will be called once the module is loaded into linux kernel.
schedule_work
is used to schedule the workqueue.
static void __exit queue_exit(void)
{
cancel_work_sync(&q_work);
pr_info("Driver Unloaded...\n");
}
Create the module exit function which will be called once the module is unloaded into linux kernel.
void workqueue_func(struct work_struct *work)
{
pr_info("Inside Workqueue function\n");
queue_work(system_wq, &q_work);
}
Workqueue APIs is called once the work is scheduled.
This API will be passed as a parameter during the time of declaring the workqueue.
module_init(queue_init);
module_exit(queue_exit);
Mention the module init and exit functions which needs to be executed when the module is loaded and unloaded.
1#include <linux/init.h>
2#include <linux/kernel.h>
3#include <linux/module.h>
4#include <linux/fs.h>
5#include <linux/workqueue.h>
6
7MODULE_LICENSE("GPL");
8MODULE_AUTHOR("Linux_usr");
9MODULE_DESCRIPTION("Workqueue");
10
11static void workqueue_func(struct work_struct *work);
12
13static struct work_struct q_work;
14
15static void workqueue_func(struct work_struct *work)
16{
17 pr_info("Inside Workqueue function\n");
18 queue_work(system_wq, &q_work);
19}
20
21static int __init queue_init(void)
22{
23 INIT_WORK(&q_work, workqueue_func);
24 queue_work(system_wq, &q_work);
25
26 pr_info("Driver Loaded...\n");
27
28 return 0;
29}
30
31static void __exit queue_exit(void)
32{
33 cancel_work_sync(&q_work);
34 pr_info("Driver Unloaded...\n");
35}
36
37module_init(queue_init);
38module_exit(queue_exit);
1obj-m += work_queue.o
2
3KDIR = /lib/modules/$(shell uname -r)/build
4
5
6all:
7 make -C $(KDIR) M=$(shell pwd) modules
8
9clean:
10 make -C $(KDIR) M=$(shell pwd) clean
Run make to load the kernel module.
$ make
make -C /lib/modules/5.4.0-150-generic/build M=$HOME/kernel_work_queue modules
make[1]: Entering directory '/usr/src/linux-headers-5.4.0-150-generic'
CC [M] $HOME/kernel_work_queue/work_queue.o
Building modules, stage 2.
MODPOST 1 modules
CC [M] $HOME/kernel_work_queue/work_queue.mod.o
LD [M] $HOME/kernel_work_queue/work_queue.ko
make[1]: Leaving directory '/usr/src/linux-headers-5.4.0-150-generic'
Check if work_queue.ko is generated or not using ls command.
$ ls -l
total 36
-rw-rw-r-- 1 test test 154 Feb 26 13:18 Makefile
-rw-rw-r-- 1 test test 47 Feb 26 13:18 modules.order
-rw-rw-r-- 1 test test 0 Feb 26 13:18 Module.symvers
-rw-rw-r-- 1 test test 820 Feb 26 13:18 work_queue.c
-rw-rw-r-- 1 test test 5880 Feb 26 13:18 work_queue.ko
-rw-rw-r-- 1 test test 47 Feb 26 13:18 work_queue.mod
-rw-rw-r-- 1 test test 919 Feb 26 13:18 work_queue.mod.c
-rw-rw-r-- 1 test test 3448 Feb 26 13:18 work_queue.mod.o
-rw-rw-r-- 1 test test 3320 Feb 26 13:18 work_queue.o
Load the module to kernel using insmod command.
$ sudo insmod ./work_queue.ko
Check kernel messages to verify if the module is loaded or not.
$ dmesg
[79276.652478] Inside Workqueue function
[79276.652479] Inside Workqueue function
[79276.652479] Inside Workqueue function
[79276.652480] Inside Workqueue function
[79276.652480] Inside Workqueue function
[79276.652481] Inside Workqueue function
[79276.652482] Inside Workqueue function
[79276.652482] Inside Workqueue function
[79276.652482] Inside Workqueue function
[79276.652483] Inside Workqueue function
[79276.652484] Inside Workqueue function
[79276.652484] Inside Workqueue function
[79276.652485] Inside Workqueue function
[79276.652485] Inside Workqueue function
[79276.652486] Inside Workqueue function
[79276.652486] Inside Workqueue function
[79276.652487] Inside Workqueue function
[79276.652487] Inside Workqueue function
[79276.652488] Inside Workqueue function
[79276.652488] Inside Workqueue function
[79276.652489] Inside Workqueue function
[79276.652489] Inside Workqueue function
[79276.652490] Inside Workqueue function
[79276.652491] Inside Workqueue function
[79276.652491] Inside Workqueue function
[79276.652492] Inside Workqueue function
[79276.652492] Inside Workqueue function
[79276.666059] Inside Workqueue function
[79276.666060] Inside Workqueue function
[79276.666060] Inside Workqueue function
[79276.666061] Inside Workqueue function
[79276.666061] Inside Workqueue function
[79276.666062] Inside Workqueue function
[79276.666062] Inside Workqueue function
[79276.666063] Inside Workqueue function
[79276.666063] Inside Workqueue function
[79276.666064] Inside Workqueue function
[79276.666064] Inside Workqueue function
[79276.666065] Inside Workqueue function
[79276.666065] Inside Workqueue function
[79276.666066] Inside Workqueue function
[79276.666067] Inside Workqueue function
[79276.666067] Inside Workqueue function
[79276.666068] Inside Workqueue function
[79276.666068] Inside Workqueue function
[79276.666069] Inside Workqueue function
[79276.666069] Inside Workqueue function
Unload the module using rmmod command.
$ sudo rmmod work_queue
Check kernel messages to see if the module is unloaded or not.
$ dmesg
[79276.652478] Inside Workqueue function
[79276.652479] Inside Workqueue function
[79276.652479] Inside Workqueue function
[79276.652480] Inside Workqueue function
[79276.652480] Inside Workqueue function
[79276.652481] Inside Workqueue function
[79276.652482] Inside Workqueue function
[79276.652482] Inside Workqueue function
[79276.652482] Inside Workqueue function
[79276.652483] Inside Workqueue function
[79276.652484] Inside Workqueue function
[79276.652484] Inside Workqueue function
[79276.652485] Inside Workqueue function
[79276.652485] Inside Workqueue function
[79276.652486] Inside Workqueue function
[79276.652486] Inside Workqueue function
[79276.652487] Inside Workqueue function
[79276.652487] Inside Workqueue function
[79276.652488] Inside Workqueue function
[79276.652488] Inside Workqueue function
[79276.652489] Inside Workqueue function
[79276.652489] Inside Workqueue function
[79276.652490] Inside Workqueue function
[79276.652491] Inside Workqueue function
[79276.652491] Inside Workqueue function
[79276.652492] Inside Workqueue function
[79276.652492] Inside Workqueue function
[79276.666059] Inside Workqueue function
[79276.666060] Inside Workqueue function
[79276.666060] Inside Workqueue function
[79276.666061] Inside Workqueue function
[79276.666061] Inside Workqueue function
[79276.666062] Inside Workqueue function
[79276.666062] Inside Workqueue function
[79276.666063] Inside Workqueue function
[79276.666063] Inside Workqueue function
[79276.666064] Inside Workqueue function
[79276.666064] Inside Workqueue function
[79276.666065] Inside Workqueue function
[79276.666065] Inside Workqueue function
[79276.666066] Inside Workqueue function
[79276.666067] Inside Workqueue function
[79276.666067] Inside Workqueue function
[79276.666068] Inside Workqueue function
[79276.666068] Inside Workqueue function
[79276.666069] Inside Workqueue function
[79276.666069] Inside Workqueue function
[79276.666072] Driver Unloaded...
API |
Learning |
---|---|
INIT_WORK |
Used for initializing a workqueue structure |
queue_work |
To schedule a workqueue |
cancel_work_sync |
To cancel a scheduled workqueue |