Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple kernel multithreading

I am new to kernel module programming and for my work I need to write a multithreaded kernel module. So I tried some primary uses of kernel threads. I wrote the following. It is supposed to print 1 in one thread and 2 in another thread, both 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 am facing following problems. -

  1. First thread is printing all ten 1s and then second thread is executing. I wanted to run these two in interleaved manner.
  2. First thread is printing all 1s OK but second is not printing 2s. It is printing 0s. Probably parameter is not passing to second thread properly.
  3. When I am inserting module it is running but when I am removing module the machine hangs

What are the problems? How can I solve them.

like image 931
taufique Avatar asked Oct 19 '12 12:10

taufique


3 Answers

  1. You need schedule() unless you have a preemptible kernel and some sleeps.
  2. You are passing data pointers from the stack and thus corrupting kernel memory. Make those ints global variables.
like image 133
cdleonard Avatar answered Sep 25 '22 06:09

cdleonard


1.Don't use these code, delete them

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

it seems after the termination of the thread, task will be set to null, then calling kthread_stop() will cause a null pointer error

2.Don't pass local variable to threads, use global variable instead.

3.If you want two threads switch between each other, use "wait_event" and "wake_up" function. Here is my code that work.

#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;
}

like image 23
Vector Avatar answered Sep 22 '22 06:09

Vector


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();
}
like image 34
Ilya Matveychikov Avatar answered Sep 24 '22 06:09

Ilya Matveychikov