Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Not able to bind kernel threads to CPU

I have written this code to bind 2 kernel threads to different CPUs :

#include<linux/kthread.h>
#include<linux/sched.h>
#include<linux/delay.h>
#include<linux/slab.h>

struct task_struct *task1;
struct task_struct *task2;
int cpu, data;

int thread_function_one(void *data)
{
    int ret = 10;
    printk(KERN_INFO "IN THREAD FUNCTION 1 \n");

    while(!kthread_should_stop()){
       cpu = get_cpu();
       put_cpu();
       printk("t1 cpu = %d\n",cpu);
       msleep(5000);
    }
    printk(KERN_INFO "EXIT from thread function 1\n");
    return ret;
}

int thread_function_two(void *data)
{
    int ret = 10;
    printk(KERN_INFO "IN THREAD FUNCTION 2 \n");

    while(!kthread_should_stop()){
        cpu = get_cpu();
        put_cpu();
        printk("t2 cpu = %d\n",cpu);
        msleep(6000);
    }
    printk(KERN_INFO "EXIT from thread function 2\n");
    return ret;
}

static int kernel_init(void)
{
   printk(KERN_INFO "module_init\n");

   cpu = get_cpu();
   put_cpu();
   printk("main thread cpu = %d \n",cpu);

   task1 = kthread_create(&thread_function_one,(void *)&data,"one");
   kthread_bind(task1, cpu);
   wake_up_process(task1);

   cpu = 5;
   task2 = kthread_create(&thread_function_two,(void *)&data,"two");
   kthread_bind(task2, cpu);
   wake_up_process(task2);

   return 0;
}

static void kernel_exit(void)
{
   kthread_stop(task1);
   kthread_stop(task2);
   printk(KERN_INFO "module_exit\n");
}

module_init(kernel_init);
module_exit(kernel_exit);
MODULE_AUTHOR("K_K");
MODULE_LICENSE("GPL");

But when I print the cpu id in thread_function_one and thread_function_two both print the same CPU as that of main thread.

Am I doing smthing wrong ?

Output of this prog :

kernel: [  956.816510] module_init
kernel: [  956.816515] main thread cpu = 8 
kernel: [  956.816743] IN THREAD FUNCTION 1 
kernel: [  956.816748] t1 cpu = 8
kernel: [  956.817057] IN THREAD FUNCTION 2 
kernel: [  956.817062] t2 cpu = 8
kernel: [  961.815160] t1 cpu = 8
kernel: [  962.814649] t2 cpu = 8
kernel: [  966.816760] t1 cpu = 8
kernel: [  968.815711] t2 cpu = 8
kernel: [  971.818307] EXIT from thread function 1
kernel: [  974.816813] EXIT from thread function 2
kernel: [  974.816872] module_exit
like image 660
K_K Avatar asked Jan 02 '15 06:01

K_K


People also ask

Can a kernel thread make a system call?

Operating Systems kernel provides system call to create and manage threads. Advantages: Because kernel has full knowledge of all threads, Scheduler may decide to give more time to a process having large number of threads than process having small number of threads.

How are user threads mapped to kernel threads?

The mapping of user threads to kernel threads is done using virtual processors. A virtual processor (VP) is a library entity that is usually implicit. For a user thread, the VP behaves like a CPU. In the library, the VP is a kernel thread or a structure bound to a kernel thread.

Can a process have multiple kernel threads?

One process can have multiple threads, with each thread executing different code concurrently, while sharing data and synchronizing much more easily than cooperating processes. Threads require fewer system resources than processes, and can start more quickly.

How do you create a kernel thread?

A kernel thread is created with: struct task_struct *kthread_create(int (*threadfn)(void *data), void *data, const char *namefmt, ...); The data argument will simply be passed to the thread function. A standard printk()-style formatted string can be used to name the thread.


1 Answers

The module works fine if the "int cpu" variable is not global. The thread one modifies this global and thread two binds itself to the same CPU. This is the race condition between main thread, thread one and thread two.

like image 92
K_K Avatar answered Oct 23 '22 02:10

K_K