Tasklet Disable =============== .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Topics in this section, * :ref:`Version Info ` * :ref:`Learnings in this section ` * :ref:`Explanation of tasklet APIs ` * :ref:`tasklet_init ` * :ref:`tasklet_disable_nosync ` * :ref:`tasklet_enable ` * :ref:`tasklet_schedule ` * :ref:`from_tasklet ` * :ref:`tasklet_setup ` * :ref:`tasklet_disable_in_atomic ` * :ref:`tasklet_kill ` * :ref:`Explanation of miscellaneous APIs ` * :ref:`Module parameter APIs ` * :ref:`Driver entry point APIs ` * :ref:`Example 1: Creating tasklet using DECLARE_TASKLET ` * :ref:`List of headers ` * :ref:`Module Macros ` * :ref:`Declare and Initialize tasklet ` * :ref:`Tasklet Handler Function ` * :ref:`Tasklet Start Function ` * :ref:`Task Init Function ` * :ref:`Tasklet Stop Function ` * :ref:`Task Exit Function ` * :ref:`Driver entry points ` * :ref:`See the full program below ` * :ref:`Makefile ` * :ref:`Compile and load the module ` * :ref:`Example 2: Creating tasklet using DECLARE_TASKLET_OLD ` * :ref:`List of headers ` * :ref:`Module Macros ` * :ref:`Declare and Initialize tasklet ` * :ref:`Tasklet Handler Function ` * :ref:`Tasklet Start Function ` * :ref:`Task Init Function ` * :ref:`Tasklet Stop Function ` * :ref:`Task Exit Function ` * :ref:`Driver entry points ` * :ref:`See the full program below ` * :ref:`Makefile ` * :ref:`Compile and load the module ` .. _p1_taskletstatic_0: .. tab-set:: .. tab-item:: Version Info =============================== ======================================= # Version =============================== ======================================= Ubuntu Ubuntu 22.10 Kernel 6.8.0 =============================== ======================================= .. _p1_taskletstatic_1: .. tab-set:: .. tab-item:: Learnings in this section * In this program, you are going to learn .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * How to create tasklet ? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * What are the different ways to create tasklet ? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * How to enable the tasklet ? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * How to disable the tasklet ? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * What are the different ways to create tasklet ? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * How to kill the tasklet ? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * How to use tasklet APIs ? * `tasklet_init `_ * `tasklet_disable_nosync `_ * `tasklet_enable `_ * `tasklet_schedule `_ * `from_tasklet `_ * `tasklet_setup `_ * `tasklet_disable_in_atomic `_ * `tasklet_kill `_ .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * How to use below APIs ? * `MODULE_LICENSE `_ * `MODULE_DESCRIPTION `_ * `MODULE_AUTHOR `_ * `module_init `_ * `module_exit `_ .. _p1_taskletstatic_2: .. tab-set:: .. tab-item:: Explanation of tasklet APIs .. _p1_taskletstatic_3: .. tab-set:: .. tab-item:: tasklet_init * Here is the function prototype of the API: `tasklet_init `_ .. code-block:: c #include extern void tasklet_init(struct tasklet_struct *t, void (*func)(unsigned long), unsigned long data); * Here is an example of how to use the API, .. code-block:: c tasklet_init(tasklet, tasklet_handler1, 20); .. _p1_taskletstatic_35: .. tab-set:: .. tab-item:: tasklet_disable_nosync * Here is the function prototype of the API: `tasklet_disable_nosync `_ .. code-block:: c #include static inline void tasklet_disable_nosync(struct tasklet_struct *t); * Here is an example of how to use the API, .. code-block:: c tasklet_disable_nosync(tasklet); .. _p1_taskletstatic_36: .. tab-set:: .. tab-item:: tasklet_enable * Here is the function prototype of the API: `tasklet_enable `_ .. code-block:: c #include static inline void tasklet_enable(struct tasklet_struct *t); * Here is an example of how to use the API, .. code-block:: c tasklet_enable(tasklet); .. _p1_taskletstatic_4: .. tab-set:: .. tab-item:: tasklet_schedule * Here is the function prototype of the API: `tasklet_schedule `_ .. code-block:: c #include static inline void tasklet_schedule(struct tasklet_struct *t); * Here is an example of how to use the API, .. code-block:: c tasklet_schedule(&my_tasklet); .. _p1_taskletstatic_37: .. tab-set:: .. tab-item:: from_tasklet * Here is the function prototype of the API: `from_tasklet `_ .. code-block:: c #include #define from_tasklet(var, callback_tasklet, tasklet_fieldname) * Here is an example of how to use the API, .. code-block:: c struct task *task_1 = from_tasklet(task_1, t, my_tasklet); .. _p1_taskletstatic_38: .. tab-set:: .. tab-item:: tasklet_setup * Here is the function prototype of the API: `tasklet_setup `_ .. code-block:: c #include extern void tasklet_setup(struct tasklet_struct *t, void (*callback)(struct tasklet_struct *)); * Here is an example of how to use the API, .. code-block:: c tasklet_setup(&task_t->my_tasklet, tasklet_handler); .. _p1_taskletstatic_39: .. tab-set:: .. tab-item:: tasklet_disable_in_atomic * Here is the function prototype of the API: `tasklet_disable_in_atomic `_ .. code-block:: c #include static inline void tasklet_disable_in_atomic(struct tasklet_struct *t); * Here is an example of how to use the API, .. code-block:: c tasklet_disable_in_atomic(&task_t->my_tasklet); .. _p1_taskletstatic_5: .. tab-set:: .. tab-item:: tasklet_kill * Here is the function prototype of the API: `tasklet_kill `_ .. code-block:: c #include extern void tasklet_kill(struct tasklet_struct *t); * where * `tasklet_kill `_: kills tasklet. * struct tasklet_struct * t : Parameter of type pointer to struct tasklet_struct, representing the tasklet that is to be killed or stopped. * Here is an example of how to use the API, .. code-block:: c tasklet_kill(&my_tasklet); .. _p1_taskletstatic_6: .. tab-set:: .. tab-item:: Explanation of miscellaneous APIs .. _p1_taskletstatic_7: .. tab-set:: .. tab-item:: Module parameter APIs * Here is the prototype of module paramter APIs .. code-block:: c #include #define MODULE_LICENSE(_license) MODULE_FILE MODULE_INFO(license, _license) #define MODULE_AUTHOR(_author) MODULE_INFO(author, _author) #define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description) * where * `MODULE_LICENSE `_: tells the kernel what license is used by our module. * `MODULE_AUTHOR `_: denotes the author of this kernel module. * `MODULE_DESCRIPTION `_: gives a basic idea about what the kernel module does. * These information can be found when modinfo command is used which lists out all these above mentioned information. * Here is the example of how to use the Module parameter APIs, .. code-block:: c MODULE_LICENSE("GPL"); MODULE_AUTHOR("usr"); MODULE_DESCRIPTION("Tasklet"); .. _p1_taskletstatic_8: .. tab-set:: .. tab-item:: Driver entry point API's * Here is the prototype of the Driver entry point API's .. code-block:: c #include #define module_init(x) __initcall(x); #define module_exit(x) __exitcall(x); * where * `module_init `_: driver initialization entry point which will be called at module insertion time. * `module_exit `_: driver exit entry point which will be called during the removal of module. * x: * function to be run at module insertion for `module_init `_ function. * function to be run when driver is removed for `module_exit `_ function. * Here is an example of how to use the driver entry point API's .. code-block:: c module_init(task_init); module_exit(task_exit); .. _p1_taskletstatic_9: .. tab-set:: .. tab-item:: Example 1: Disabling tasklet using tasklet_disable_nosync * In this example let's see how to disable tasklet using tasklet_disable_nosync and execute it. .. _p1_taskletstatic_10: .. tab-set:: .. tab-item:: List of headers * Include the follow header files(.h) to refer the API being used for the execution. .. code-block:: c #include #include #include #include #include .. _p1_taskletstatic_11: .. tab-set:: .. tab-item:: Module macros * Add the following module macros to display information about the license, author and description about the module. .. code-block:: c MODULE_LICENSE("GPL"); MODULE_AUTHOR("usr"); MODULE_DESCRIPTION("Tasklet"); .. _p1_taskletstatic_12: .. tab-set:: .. tab-item:: Initialize the tasklet dynamically. * Initialize the tasklet which we are going to create and use in this example .. code-block:: c tasklet_init(tasklet, tasklet_handler1, 20); .. _p1_taskletstatic_13: .. tab-set:: .. tab-item:: Tasklet Handler Function * This function executes once the tasklet is scheduled using tasklet_schedule. .. code-block:: c void tasklet_handler1(unsigned long data) { pr_info("Inside tasklet handler function with data : %ld\n", data); pr_info("Tasklet handler function executed\n"); } .. _p1_taskletstatic_14: .. tab-set:: .. tab-item:: Tasklet Start Function * This function initializes the tasklet dynamically using tasklet_init. * Immediately disabling the tasklet using tasklet_disable_nosync. * Enabling the tasklet using tasklet_enable. * schedules a tasklet using tasklet_schedule. .. code-block:: c void tasklet_start(void) { tasklet = kmalloc(sizeof(struct tasklet_struct), GFP_KERNEL); if (tasklet == NULL) pr_info("Cannot allocate memory\n"); tasklet_init(tasklet, tasklet_handler1, 20); tasklet_disable_nosync(tasklet); tasklet_enable(tasklet); tasklet_schedule(tasklet); pr_info("tasklet schecduled!!\n"); } .. _p1_taskletstatic_15: .. tab-set:: .. tab-item:: Task Init Function * This function calls tasklet_start function, will be executed once the module is loaded into the linux kernel. .. code-block:: c static int __init task_init(void) { pr_info("driver loaded\n"); tasklet_start(); return 0; } .. _p1_taskletstatic_16: .. tab-set:: .. tab-item:: Tasklet Stop Function * This function kills tasklet and stops it's execution. .. code-block:: c void tasklet_stop(void) { tasklet_kill(tasklet); if (tasklet != NULL) kfree(tasklet); } .. _p1_taskletstatic_17: .. tab-set:: .. tab-item:: Task Exit Function * This function calls tasklet_stop function, will be executed once the module is removed from the linux kernel .. code-block:: c static void __exit task_exit(void) { pr_info("driver unloaded\n"); tasklet_stop(); } .. _p1_taskletstatic_18: .. tab-set:: .. tab-item:: Driver entry points * Add the driver entry points which will be executed once the module is inserted or removed from the kernel. .. code-block:: c module_init(task_init); module_exit(task_exit); .. _p1_taskletstatic_19: .. tab-set:: .. tab-item:: See the full program below .. tab-set:: .. tab-item:: tasklet.c .. literalinclude:: disable_tasklet/tc1/tasklet.c :language: c :linenos: .. _p1_taskletstatic_20: .. tab-set:: .. tab-item:: Makefile .. literalinclude:: disable_tasklet/tc1/Makefile :language: c :linenos: .. _p1_taskletstatic_21: .. tab-set:: .. tab-item:: Compile and load the module * Run make to compile the kernel source and generate the .ko image. .. code-block:: shell $ make make -C /lib/modules/6.8.0/build M=/home/arun/Desktop/kernel_api/tasklet/disable_tasklet/tc1 modules make[1]: Entering directory '/home/arun/Desktop/kernel_api/linux-6.8' CC [M] /home/arun/Desktop/kernel_api/tasklet/disable_tasklet/tc1/tasklet.o MODPOST /home/arun/Desktop/kernel_api/tasklet/disable_tasklet/tc1/Module.symvers CC [M] /home/arun/Desktop/kernel_api/tasklet/disable_tasklet/tc1/tasklet.mod.o LD [M] /home/arun/Desktop/kernel_api/tasklet/disable_tasklet/tc1/tasklet.ko make[1]: Leaving directory '/home/arun/Desktop/kernel_api/linux-6.8' * Check if the .ko is generated or not using ls command. .. code-block:: shell $ ls -l total 384 -rw-rw-r-- 1 arun arun 206 Jun 21 15:29 Makefile -rw-rw-r-- 1 arun arun 68 Jul 11 16:50 modules.order -rw-rw-r-- 1 arun arun 0 Jul 11 16:50 Module.symvers -rw-rw-r-- 1 arun arun 1772 Jun 24 18:06 tasklet.c -rw-rw-r-- 1 arun arun 183344 Jul 11 16:50 tasklet.ko -rw-rw-r-- 1 arun arun 68 Jul 11 16:50 tasklet.mod -rw-rw-r-- 1 arun arun 1166 Jul 11 16:50 tasklet.mod.c -rw-rw-r-- 1 arun arun 149416 Jul 11 16:50 tasklet.mod.o -rw-rw-r-- 1 arun arun 35320 Jul 11 16:50 tasklet.o * Run modinfo command to get the information about the kernel module. .. code-block:: shell $ modinfo tasklet.ko filename: /home/arun/Desktop/kernel_api/tasklet/disable_tasklet/tc1/tasklet.ko description: Tasklet author: Linux_usr license: GPL srcversion: 0C829F1613CD92F609A6D88 depends: retpoline: Y name: tasklet vermagic: 6.8.0 SMP preempt mod_unload modversions * insert the module using insmod command. .. code-block:: shell $ sudo insmod ./tasklet.ko * check if the module is loaded or not using lsmod command. .. code-block:: shell $ lsmod | grep tasklet tasklet 12288 0 * check for the kernel messages from init function and thread function once the module is loaded and thread is created. .. code-block:: shell $ sudo dmesg [536638.783820] driver loaded [536638.783836] tasklet schecduled!! [536638.784422] Inside tasklet handler function with data : 20 [536638.784426] Tasklet handler function executed * remove the module from kernel using rmmod command. .. code-block:: shell $ sudo rmmod tasklet * check if the module is still loaded after removing the kernel module using lsmod if it is not displayed in lsmod output it is verified that the module is removed successfully. .. code-block:: shell $ lsmod | grep tasklet * Check for kernel messages from exit function using dmesg command. .. code-block:: shell $ sudo dmesg [534946.455200] driver unloaded .. _p1_taskletstatic_22: .. tab-set:: .. tab-item:: Example 2: Creating tasklet using DECLARE_TASKLET_OLD * In this example let's see how to create tasklet using DECLARE_TASKLET_OLD and execute it. .. _p1_taskletstatic_23: .. tab-set:: .. tab-item:: List of headers * Include the follow header files(.h) to refer the API being used for the execution. .. code-block:: c #include #include #include #include #include .. _p1_taskletstatic_24: .. tab-set:: .. tab-item:: Module macros * Add the following module macros to display information about the license, author and description about the module. .. code-block:: c MODULE_LICENSE("GPL"); MODULE_AUTHOR("usr"); MODULE_DESCRIPTION("Tasklet"); .. _p1_taskletstatic_25: .. tab-set:: .. tab-item:: Initialize the tasklet dynamically. * Initialize the tasklet which we are going to create and use in this example .. code-block:: c tasklet_setup(&task_t->my_tasklet, tasklet_handler); .. _p1_taskletstatic_26: .. tab-set:: .. tab-item:: Tasklet Handler Function * This function executes once the tasklet is scheduled using tasklet_schedule. .. code-block:: c void tasklet_handler(struct tasklet_struct *t) { struct task *task_1 = from_tasklet(task_1, t, my_tasklet); pr_info("Inside tasklet handler function\n"); pr_info("task_a : %d\n", task_1->task_a); pr_info("task_b : %d\n", task_1->task_b); pr_info("task_c : %c\n", task_1->task_c); pr_info("task_d : %s\n", task_1->task_d); } .. _p1_taskletstatic_27: .. tab-set:: .. tab-item:: Tasklet Start Function * This function initializes the tasklet dynamically using tasklet_setup. * Disabling the tasklet using tasklet_disable_in_atomic. * Enabling the tasklet using tasklet_enable. * schedules a tasklet using tasklet_schedule. .. code-block:: c void tasklet_start(void) { task_t = kmalloc(sizeof(struct tasklet_struct *), GFP_KERNEL); if (task_t == NULL) pr_info("Cannot allocate memory\n"); task_t->task_a = 10; task_t->task_b = 20; task_t->task_c = 'a'; strncpy(task_t->task_d, "hello", sizeof(task_t->task_d)); tasklet_setup(&task_t->my_tasklet, tasklet_handler); tasklet_disable_in_atomic(&task_t->my_tasklet); tasklet_enable(&task_t->my_tasklet); tasklet_schedule(&task_t->my_tasklet); pr_info("tasklet schecduled!!\n"); } .. _p1_taskletstatic_28: .. tab-set:: .. tab-item:: Task Init Function * This function calls tasklet_start function, will be executed once the module is loaded into the linux kernel. .. code-block:: c static int __init task_init(void) { pr_info("driver loaded\n"); tasklet_start(); return 0; } .. _p1_taskletstatic_29: .. tab-set:: .. tab-item:: Tasklet Stop Function * This function kills tasklet and stops it's execution. .. code-block:: c void tasklet_stop(void) { tasklet_kill(&task_t->my_tasklet); if (task_t != NULL) kfree(task_t); } .. _p1_taskletstatic_30: .. tab-set:: .. tab-item:: Task Exit Function * This function calls tasklet_stop function, will be executed once the module is removed from the linux kernel .. code-block:: c static void __exit task_exit(void) { pr_info("driver unloaded\n"); tasklet_stop(); } .. _p1_taskletstatic_31: .. tab-set:: .. tab-item:: Driver entry points * Add the driver entry points which will be executed once the module is inserted or removed from the kernel. .. code-block:: c module_init(task_init); module_exit(task_exit); .. _p1_taskletstatic_32: .. tab-set:: .. tab-item:: See the full program below .. tab-set:: .. tab-item:: tasklet.c .. literalinclude:: disable_tasklet/tc2/tasklet.c :language: c :linenos: .. _p1_taskletstatic_33: .. tab-set:: .. tab-item:: Makefile .. literalinclude:: disable_tasklet/tc2/Makefile :language: c :linenos: .. _p1_taskletstatic_34: .. tab-set:: .. tab-item:: Compile and load the module * Run make to compile the kernel source and generate the .ko image. .. code-block:: shell $ make make -C /lib/modules/6.8.0/build M=/home/arun/Desktop/kernel_api/tasklet/disable_tasklet/tc2 modules make[1]: Entering directory '/home/arun/Desktop/kernel_api/linux-6.8' CC [M] /home/arun/Desktop/kernel_api/tasklet/disable_tasklet/tc2/tasklet.o MODPOST /home/arun/Desktop/kernel_api/tasklet/disable_tasklet/tc2/Module.symvers CC [M] /home/arun/Desktop/kernel_api/tasklet/disable_tasklet/tc2/tasklet.mod.o LD [M] /home/arun/Desktop/kernel_api/tasklet/disable_tasklet/tc2/tasklet.ko make[1]: Leaving directory '/home/arun/Desktop/kernel_api/linux-6.8' * Check if the .ko is generated or not using ls command. .. code-block:: shell $ ls -l total 392 -rw-rw-r-- 1 arun arun 206 Jun 24 17:18 Makefile -rw-rw-r-- 1 arun arun 68 Jul 11 17:59 modules.order -rw-rw-r-- 1 arun arun 0 Jul 11 17:59 Module.symvers -rw-rw-r-- 1 arun arun 2220 Jun 24 17:58 tasklet.c -rw-rw-r-- 1 arun arun 186000 Jul 11 17:59 tasklet.ko -rw-rw-r-- 1 arun arun 68 Jul 11 17:59 tasklet.mod -rw-rw-r-- 1 arun arun 1212 Jul 11 17:59 tasklet.mod.c -rw-rw-r-- 1 arun arun 149480 Jul 11 17:59 tasklet.mod.o -rw-rw-r-- 1 arun arun 37928 Jul 11 17:59 tasklet.o * Run modinfo command to get the information about the kernel module. .. code-block:: shell $ modinfo tasklet.ko filename: /home/arun/Desktop/kernel_api/tasklet/disable_tasklet/tc2/tasklet.ko description: Tasklet author: Linux_usr license: GPL srcversion: DF2CE7D8870F4E515BA7CEA depends: retpoline: Y name: tasklet vermagic: 6.8.0 SMP preempt mod_unload modversions * insert the module using insmod command. .. code-block:: shell $ sudo insmod ./tasklet.ko * check if the module is loaded or not using lsmod command. .. code-block:: shell $ lsmod | grep tasklet tasklet 12288 0 * check for the kernel messages from init function and thread function once the module is loaded and thread is created. .. code-block:: shell $ sudo dmesg [540980.854372] driver loaded [540980.854378] tasklet schecduled!! [540980.854648] Inside tasklet handler function [540980.854649] task_a : 10 [540980.854650] task_b : 20 [540980.854651] task_c : a [540980.854651] task_d : hello * remove the module from kernel using rmmod command. .. code-block:: shell $ sudo rmmod tasklet * check if the module is still loaded after removing the kernel module using lsmod if it is not displayed in lsmod output it is verified that the module is removed successfully. .. code-block:: shell $ lsmod | grep tasklet * Check for kernel messages from exit function using dmesg command. .. code-block:: shell $ sudo dmesg [534946.455200] driver unloaded