Kernel threads in linux

Creating Linux Kernel Threads

It’s been quite some time since I touched linux kernel modules, right now I’m revisiting the concepts once more. In this post I’m writing down the bullet points for creating the kernel threads.

To create a linux kernel thread, we need to:

  • Include: linux/kthread.h
  • Include: linux/sched.h
  • Create: struct task_struct * this structure is defined in linux/sched.h .
  • Create a function that you need to execute from the thread: The signature of that function needs to be int function_name (void *data)
  • Create a kthread using : kthread_create from linux/kthread.h .
  • Move the thread to the set of runnable processes using wake_up_process .
  • Stop the thread before exiting the module using kthread_stop .

Putting everything together,

Following is the (same old 😅) example program to create multiple threads from a kernel module.

#include // included for all kernel modules #include // included for __init and __exit macros #include // included for threading related functions #include // included to create tesk_struct #include // included for the sleep/delay function in the thread // array for task_struct to hold task info static struct task_struct kth_arr[4]; // long running function to be executed inside a thread, this will run for 30 secs. int thread_function(void * idx)  unsigned int i = 0; int t_id = * (int * ) idx; // kthread_should_stop call is important. while (!kthread_should_stop())  printk(KERN_INFO "Thread %d Still running. %d secs\n", t_id, i); i++; if (i == 30) break; msleep(1000); > printk(KERN_INFO "thread %d stopped\n", t_id); return 0; > // initialize one thread at a time. int initialize_thread(struct task_struct * kth, int idx)  char th_name[20]; sprintf(th_name, "kthread_%d", idx); kth = kthread_create(thread_function, & idx, (const char * ) th_name); if (kth != NULL)  wake_up_process(kth); printk(KERN_INFO "%s is running\n", th_name); > else  printk(KERN_INFO "kthread %s could not be created\n", th_name); return -1; > return 0; > // module init function static int __init mod_init(void)  int i = 0; printk(KERN_INFO "Initializing thread module\n"); for (i = 0; i  4; i++)  // initialize one thread at a time. if (initialize_thread( & kth_arr[i], i) == -1)  return -1; > > printk(KERN_INFO "all of the threads are running\n"); return 0; > // module exit function. static void __exit mod_exit(void)  int i = 0; int ret = 0; printk(KERN_INFO "exiting thread module\n"); for (i = 0; i  4; i++)  // stop all of the threads before removing the module. ret = kthread_stop( & kth_arr[i]); if (!ret)  printk("can't stop thread %d", i); > > printk(KERN_INFO "stopped all of the threads\n"); > MODULE_LICENSE("GPL"); MODULE_AUTHOR("GIRISH JOSHI"); MODULE_DESCRIPTION("KTHREAD demo"); module_init(mod_init); module_exit(mod_exit);

and of course the makefile looks like

obj-m+=kthread_demo.o all: make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean 

Источник

Kernel Thread – Linux Device Driver Tutorial Part 19

kernel thread

This article is a continuation of the Series on Linux Device Driver and carries the discussion on Linux device drivers and their implementation. The aim of this series is to provide easy and practical examples that anyone can understand. This is the Kernel Thread in Linux kernel driver – Linux Device Driver Tutorial Part 19.

Process

An executing instance of a program is called a process. Some operating systems use the term ‘task‘ to refer to a program that is being executed. The process is a heavyweight process. The context switch between the process is time-consuming.

Threads

A thread is an independent flow of control that operates within the same address space as other independent flows of control within a process.

Kernel Thread

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. Threads, also known as lightweight processes.

One of the advantages of the thread is that since all the threads within the processes share the same address space, the communication between the threads is far easier and less time-consuming as compared to processes. This approach has one disadvantage also. It leads to several concurrency issues and requires synchronization mechanisms to handle the same.

Thread Management

Whenever we are creating a thread, it has to manage by someone. So that management follows like below.

  • A thread is a sequence of instructions.
  • CPU can handle one instruction at a time.
  • To switch between instructions on parallel threads, the execution state needs to be saved.
  • Execution state in its simplest form is a program counter and CPU registers.
  • The program counter tells us what instruction to execute next.
  • CPU registers hold execution arguments, for example, addition operands.
  • This alternation between threads requires management.
  • Management includes saving state, restoring state, deciding what thread to pick next.

Types of Thread

There are two types of threads.

User Level Thread

In this type, the kernel is not aware of these threads. Everything is maintained by the user thread library. That thread library contains code for creating and destroying threads, for passing messages and data between threads, for scheduling thread execution, and for saving and restoring thread contexts. So all will be in User Space.

Kernel Level Thread

Kernel level threads are managed by the OS, therefore, thread operations are implemented in the kernel code. There is no thread management code in the application area.

Anyhow each type of thread has advantages and disadvantages too.

Now we will move into Kernel Thread Programming. First, we will see the functions used in a kernel thread.

Kernel Thread Management Functions

There are many functions used in Kernel Thread. We will see each one by one. We can classify those functions based on functionalities.

  • Create Kernel Thread
  • Start Kernel Thread
  • Stop Kernel Thread
  • Other functions in Kernel Thread

For use the below functions you should include linux/kthread.h header file.

Create Kernel Thread

kthread_create

This API creates a kthread.

struct task_struct * kthread_create (int (* threadfn(void *data), void *data, const char namefmt[], . );

threadfn – the function to run until signal_pending(current).

data – data ptr for threadfn .

namefmt[] – printf-style name for the thread.

. – variable arguments

This helper function creates and names a kernel thread. But we need to wake up that thread manually. When woken, the thread will run threadfn() with data as its argument.

threadfn can either call do_exit directly if it is a standalone thread for which no one will call kthread_stop , or return when ‘ kthread_should_stop ‘ is true (which means kthread_stop has been called). The return value should be zero or a negative error number; it will be passed to kthread_stop .

It Returns task_struct or ERR_PTR(-ENOMEM) .

Start Kernel Thread

wake_up_process

int wake_up_process (struct task_struct * p);

p – The process to be woken up.

Attempt to wake up the nominated process and move it to the set of runnable processes.

It returns 1 if the process was woken up, 0 if it was already running.

It may be assumed that this function implies a write memory barrier before changing the task state if and only if any tasks are woken up.

Stop Kernel Thread

kthread_stop

int kthread_stop ( struct task_struct *k);

k – thread created by kthread_create .

Sets kthread_should_stop for k to return true , wakes it and waits for it to exit. Your threadfn must not call do_exit itself, if you use this function! This can also be called after kthread_create instead of calling wake_up_process : the thread will exit without calling threadfn .

It Returns the result of threadfn , or –EINTR if wake_up_process was never called.

Other functions in Kernel Thread

kthread_should_stop

should this kthread return now?

int kthread_should_stop (void);

When someone calls kthread_stop on your kthread, it will be woken and this will return true. You should then return, and your return value will be passed through to kthread_stop .

kthread_bind

void kthread_bind (struct task_struct *k, unsigned int cpu);

Источник

Читайте также:  Лучшие музыкальные плееры linux
Оцените статью
Adblock
detector