Changing process state in a module

The example shows how we can change the state of a process.

Every process in linux has a task_struct for itself which stores all the relevant information about the process.
The possible states a process can have in linux are

Running or Runnable defined as TASK_RUNNING
Interruptible sleep defined as TASK_INTERRUPTIBLE
Uniterruptible sleep defined as TASK_UNINTERRUPTIBLE
Terminated task defined as TASK_STOPPED
(There are few more states that are not used often).

To look at the state of the task we can use the command

ps -eo state,comm

For eg  : The ouput of the above command could be

S evince
S evinced
D gnome-terminal
S gnome-pty-helpe
S bash
R ps

The first column sigifies the state of the process where

S implies Interruptible Sleep 
D implies Uninterruptible Sleep
R implies Running or Runnable.    
T imples STOPPED

The second coulmn has the name of the process.

The module below creates a thread on inserting into the module kernel. The thread runs for a minute before terminating itself. The details how the thread gets created can be seen in "Kernel Threads" .

There are two proc entries that get created on inserting the module

suspend_state: On reading this proc entry the running thread's state is changed from running to Interruptible sleep
This is done by setting " thread1->state" to TASK_INTERRUPTIBLE. where thread1 is the task_struct of the thread that was created.

run_state: On reading this proc entry the thread that is in sleep state is woken up. This is done by calling wake_up_process() on thread1. Which reschedules the sleeping process.

You can read more about proc entry creation in "Creating proc entries" .

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/semaphore.h>
#include <linux/kthread.h>  // for threads
#include <linux/sched.h>  // for task_struct
#include <linux/time.h>
#include <linux/timer.h>
#include <linux/proc_fs.h>

/*char buffer[10];
int count;
struct semaphore sem;*/
static struct task_struct *thread1;

int thread_fn() {

unsigned long j0,j1;
int delay = 100*HZ;
j0 = jiffies;
j1 = j0 + delay;

while (time_before(jiffies, j1))
printk(KERN_INFO "In thread1");

while (!kthread_should_stop())

return 0;

int suspendstate(char *buf,char **start,off_t offset,int count,int *eof,void *data)
    printk(KERN_INFO "In suspend sate");
    thread1->state = TASK_INTERRUPTIBLE;
    return 0;

int runstate(char *buf,char **start,off_t offset,int count,int *eof,void *data)
    printk(KERN_INFO "In runsate");
    return 0;

int thread_init (void) {
    char name[15]="process1";
    printk(KERN_INFO "in init");
    thread1 = kthread_create(thread_fn,NULL,name);
        printk(KERN_INFO "in if");
    return 0;

void thread_cleanup(void) {
    int ret;
    ret = kthread_stop(thread1);
        printk(KERN_INFO "Thread stopped");


   obj-m := process_change.o

KERNELDIR ?= /lib/modules/$(shell uname -r)/build

PWD := $(shell pwd)

    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 
    $(MAKE) -C $(KERNELDIR) M=$(PWD) clean

Save the above two files with the respective names and run the following commands to see the output.

$ make
$ sudo insmod process_change.ko
$ ps -eo state,comm | grep process1
R process1
The output shows process1 is currently running

$ cat /proc/suspend_state    
$ ps -eo state,comm | grep process1
S process1

After read of the proc entry suspend_state the process state changed to S, i.e. sleep state. But note the thread runs approximately for a minute so you will have to execute the "cat" command within one minute to be able to see this change.

$ cat /proc/run_state.
$ ps -eo state,comm | grep process1

R process1

After read of proc entry run_state the process state has again changed to run state.
To remove the module
$ sudo rmmod process_change

Follow by Email