Monthly Archives: April 2015

Kernel Threads

<< Previous Article

In the previous article, we learned to write a simple kernel module. This was needed to kick start our journey into the Kernel Internals, as all of the code we are going to discuss, has to be pushed into the kernel as module. In this article, we will discuss about the Kernel Threads. So, lets begin…

Understanding Threads

Threads, also known as light weight processes are the basic unit of CPU initialization. So, why do we call them as light weight processes? One of the reason is that the context switch between the threads takes much lesser time as compared to processes, which results from the fact that all the threads within the process share the same address space, so you don’t need to switch the address space. In the user space, threads are created using the POSIX APIs and are known as pthreads. Some 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. And usually is done through the global variables. This approach has one disadvantage though. It leads to several concurrency issues and require the synchronization mechanisms to handle the same.

Having said that, why do we require threads? Need for the multiple threads arises, when we need to achieve the parallelism within the process. To give you the simple example, while working on the word processor, if we enable the spell and grammar check, as we key in the words, you will see red/green lines appear, if we type something syntactically/grammatically incorrect. This can most probably be implemented as threads.

Kernel Threads

Now, what are kernel threads? They are same as user space threads in many aspects, but one of the biggest difference is that they exist in the kernel space and execute in a privileged mode and have full access to the kernel data structures. These are basically used to implement background tasks inside the kernel. The task can be handling of asynchronous events or waiting for an event to occur. Device drivers utilize the services of kernel threads to handle such tasks. For example, the ksoftirqd/0 thread is used to implement the Soft IRQs in kernel. The khubd kernel thread monitors the usb hubs and helps in configuring  usb devices during hot-plugging.

APIs for creating the Kernel thread

Below is the API for creating the thread:

#include <kthread.h>
kthread_create(int (*function)(void *data), void *data, const char name[], ...)

Parameters:
function – The function that the thread has to execute
data – The ‘data’ to be passed to the function
name – The name by which the process will be recognized in the kernel

Retuns: Pointer to a structure of type task_struct

Below is an example code which creates a kernel thread:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>

static struct task_struct *thread_st;
// Function executed by kernel thread
static int thread_fn(void *unused)
{
    while (1)
    {
        printk(KERN_INFO "Thread Running\n");
        ssleep(5);
    }
    printk(KERN_INFO "Thread Stopping\n");
    do_exit(0);
    return 0;
}
// Module Initialization
static int __init init_thread(void)
{
    printk(KERN_INFO "Creating Thread\n");
    //Create the kernel thread with name 'mythread'
    thread_st = kthread_create(thread_fn, NULL, "mythread");
    if (thread_st)
        printk("Thread Created successfully\n");
    else
        printk(KERN_INFO "Thread creation failed\n");
    return 0;
}
// Module Exit
static void __exit cleanup_thread(void)
{
    printk("Cleaning Up\n");
}

In the above code, thread is created in the init_thread(). Created thread executes the function thread_fn(). Compile the above code and insert the module with insmod. Below is the output, you get:

Thread Created successfully

That’s all we get as an output. Now, you might be wondering why is thread_fn() not executing? The reason for this is, when we create the thread with kthread_create(), it creates the thread in sleep state and thus nothing is executed. So, how do we wake up the thread. We have a API wake_up_process() for this. Below is modified code which uses this API.

// Module Initialization
static struct task_struct *thread_st;
{
    printk(KERN_INFO "Creating Thread\n");
    //Create the kernel thread with name 'mythread'
    thread_st = kthread_create(thread_fn, NULL, "mythread");
    if (thread_st)
    {
        printk("Thread Created successfully\n");
        wake_up_process(thread_st);
    }
    else
        printk(KERN_INFO "Thread creation failed\n");
    return 0;
}

As you might notice, wake_up_process() takes pointer to task_struct as an argument, which in turn is returned from kthread_create(). Below is the output:

Thread Created successfully
Thread Running
Thread Running
...

As seen, running a thread is a two step process – First create a thread and wake it up using wake_up_process(). However, kernel provides an API, which performs both these steps in one go as shown below:

#include <kthread.h>
kthread_run(int (*function)(void *data), void *data, const char name[], ...)

Parameters:
function – The function that the thread has to execute
data – The ‘data’ to be passed to the function
name – The name by which the process will be recognized in the kernel

Returns: Pointer to a structure of type task_struct

So, just replace the kthread_create() and wake_up_process() calls in above code with kthread_run and you will notice that thread starts running immediately.

Conclusion

So, now we are comfortable with creating the threads, let us remove the module with rmmod.  What do you get? Oops…isn’t it? To understand the reason for the crash, stay tuned to my next article on kernel threads. Till then, good bye.

Next Article >>

   Send article as PDF   

Sensing Someone Around

This 3rd article in the series of “Do It Yourself: Electronics”, takes you through the basics of infra red sensing using an IR LED and an IR diode.

<< Previous Article

Early morning, Pugs went to the ECE Department to meet Surya, who was creating some experiments for his juniors.

“What are you doing at this time in your department lab?”, exclaimed Pugs to Surya.

“Setting up a robot framework for our ECE juniors, for the robotic showcase planned for today afternoon”, replied Surya

“Interesting. I see that you are also using the IR transmitter and the IR receiver, you asked me to buy. By the name itself, I can make out that one would transmit IR signals, and other would receive the same. But what could we use them for?”

“These can be used for a wide range of applications …”

“To me it seems like another light sensor. Sun also emits IR. So, may be we can detect presence of sun”, interrupted Pugs.

“Why only sun? Even our bodies are good source of IR”, added Surya.

“Okay. So, do we detect sunlight, living beings, etc using the IR receiver? But then what is the IR transmitter for?”

“We can detect, but for that we may need more sophistication to eliminate the unwanted IRs. Anyways, the purpose here is not that. It is more of obstacle detection, and that’s where, we need this IR transmitter, as well.”

“I see. So, how do these IR Tx & Rx pair work?”

“Let me just show you a small working demo of the same.”

With that Surya picked up the various stuff needed, from around the lab, and showed the following:

Pugs went to his room & rebuilt the circuit. But to his surprise, the LED was always on. He tried debugging it, as in his previous light sensing circuit, but in vain. So, in frustration, he called up Surya and said, “Surya, your debugging gyaan is not working out. I tried all your suggested debugging tricks, but not able to figure out the problem in my circuit”.

“What happened? Have you powered up your circuit?”, queried Surya.

“Yes obviously. And that’s what the problem is. In my circuit, the LED is now always powered on”, replied Pugs with a sarcastic voice.

“Where have you put the circuit?”, asked Surya.

“On my table. Where else?”

“Put it below the table, and check out.”

“Why are you joking with me? How does it matter, whether I put it above or below the table?”

“Just try it, na”, emphasized Surya.

So, unwillingly Pugs put his circuit below the table, and viola the LED went off. And then, when he hovered his hand over the circuit, the LED switched on. He couldn’t believe himself. So, he tried the same multiple times. Then, he also put back the circuit on the table to check the problem, again. And yes, it was there. But all fine, when below the table.

“What happened Pugs? Did it work?”, asked Surya, as he didn’t receive any response from Pugs for a while.

“Yaaa. It is working. But how?”

“Now as it is working, I can explain you. Remember, you only told me that sun also emits IR, and your table is near the window. So, the IR receiver was always getting the IR, and hence LED was always on.”

“A ha! That’s cool. So, when I put it below the table – no IR from the sun – and things worked. That’s a great insight, that when we are playing with real world stuff, we need to keep our minds and thoughts open to all possibilities.”

“In fact, there is a simpler way to fix this problem. But I thought, why not have this fun experience.”

“What’s that?”, asked Pugs curiously.

“You may just adjust the pot to appropriately set the threshold value, depending on where you are keeping your circuit.”

“O ya! That’s what we have put the pot for.”

Next Article >>

   Send article as PDF