Simple multithreading core

I am new to kernel module programming, and for my work I need to write a multi-threaded kernel module. So I tried some of the primary uses of kernel threads. I wrote the following. It should print 1 in one thread and 2 in another thread as 10 times.

#include <linux/module.h> #include <linux/moduleparam.h> #include <linux/kernel.h> #include <linux/udp.h> #include <linux/mm.h> #include <linux/init.h> #include <linux/kthread.h> struct task_struct *task1; struct task_struct *task2; static void thread_func(void* data) { int *n; n = (int *)data; int i = 0; while(i < 10){ printk("%d\n", *n); i++; } //do_exit(); } static int t_start(void) { printk("Module starting ... ... ..\n"); int *p1, *p2; int one = 1, two = 2; p1 = &one; p2 = &two; task1 = kthread_run(&thread_func, (void*)p1, "thread_func_1"); task2 = kthread_run(&thread_func, (void*)p2, "thread_func_2"); return 0; } static void t_end (void) { printk("Module terminating ... ... ...\n"); kthread_stop(task1); kthread_stop(task2); } module_init(t_start); module_exit(t_end); MODULE_AUTHOR("Md. Taufique Hussain"); MODULE_DESCRIPTION("Testing kernel threads"); MODULE_LICENSE("GPL"); 

But I have the following problems. -

  • The first thread prints all ten seconds, and then the second thread of execution. I would like to run these two in alternation.
  • The first thread prints all 1s OK, and the second does not print 2s. This print is 0s. The parameter probably does not go into the second thread properly.
  • When I insert the module, it works, but when I remove the module the machine hangs

What are the problems? How can I solve them.

+4
source share
3 answers

Add schedule call to force thread scheduling.

 static void thread_func(void* data) { int *n; n = (int *)data; int i = 0; while(i < 10){ printk("%d\n", *n); schedule(); i++; } //do_exit(); } 
+2
source
  • You will need a schedule () if you do not have a preventive kernel and some dreams.
  • You pass data pointers from the stack and thus decompose kernel memory. Make these ints global variables.
+1
source

1. Do not use this code, delete them

 // kthread_stop(task1); // kthread_stop(task2); 

It seems that after the end of the thread the task will be set to null, and calling kthread_stop () will result in a null pointer error

2. Do not pass a local variable into streams, use a global variable instead.

3. If you want the two threads to switch between themselves, use the wait_event and wake_up functions. Here is my code that works.

 #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/kthread.h> #include <linux/wait.h> MODULE_LICENSE("GPL"); int pid1 = 1; int pid2 = 2; DECLARE_WAIT_QUEUE_HEAD(wq); int condition; struct task_struct *task1; struct task_struct *task2; static int thread_function(void *data){ int *thread_id = (int*)data; int i = 0; while(i < 10){ printk(KERN_INFO "install kernel thread: %d\n", *thread_id); i++; if(*thread_id == 1) { wait_event(wq, condition == 0xA); condition = 0xB; wake_up(&wq); } else{ wait_event(wq, condition == 0xB); condition = 0xA; wake_up(&wq); } } return 0; } static int kernel_init(void) { condition = 0xA; task1 = kthread_create(&thread_function, (void *)&pid1, "pradeep"); task2 = kthread_create(&thread_function, (void *)&pid2, "pradeep"); //printk(KERN_INFO "After create kernel thread\n"); wake_up_process(task1); wake_up_process(task2); return 0; } int init_module(void) { kernel_init(); return 0; } void cleanup_module(void) { return; } 

+1
source

Source: https://habr.com/ru/post/1440768/


All Articles