Schedule Work

#

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 ?

  • 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);
#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);
#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);
#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);
#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));
#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);
#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