The length of timeslices for processes under CFS process scheduling algorithm in Linux Kernel

Abstract
As is known, CFS (Completely Fair Scheduling) is a famous process scheduling algorithm in Linux Kernel but there is no convenient way for developers to get the timeslices of processes if CFS is chosen. In this article, I will introduce one way to hack the timeslices of process easily for CFS in Linux Kernel. Note that, the way introduced following is under Linux Kernel 3.16.39.

Details
Firstly, you need to export two flags from Linux kernel so that you can control them to output which process’s (PID) timeslice. The way to export them in ‘linux-3.16.39/kernel/sched/core.c’ is as follows.

//added by Weiwei Jia
#include <include/time.h>
int enable_flag = 0;
module_param(enable_flag, int, 0664);
EXPORT_SYMBOL_GPL(enable_flag);
//ended

In above source codes, ‘enable_flag’ controls whether to output the timeslice and ‘enable_pid’ controls which process’s timeslice to be outputed, which can be controled in userspace (“/sys/module/core/parameters/enable_flag” and “/sys/module/core/parameters/enable_pid”) by users/developers. We also need to add some other source codes before context switch in core.c like following.

2805 static void __sched __schedule(void)                                    
2806 { 
...
2869         //added by Weiwei Jia                                                                                                                                                                                                          
2870         do_gettimeofday(&(next->__ts));                                 
2871         next->__start_ts = (next->__ts).tv_sec * 1000 + (next->__ts).tv_usec;
2872         prev->__end_ts = next->__start_ts;                              
2873         if (enable_flag == 1 && prev->;pid == enable_pid) {              
2874             printk(KERN_INFO "%d\n", prev->;__end_ts - prev->__start_ts); 
2875         }                                                                                                  
2876         //ended
2877                                                                         
2878         context_switch(rq, prev, next); /* unlocks the rq */            
...
2895 }

Above source codes show us when there is a context switch from process A to process B, we need to get the end time-stamp of A and the start time-stamp of B (using start/end times-stamp of one process will get its timeslice). Then, we check whether we need to output the timeslice of specific process according to ‘enable_flag’ and ‘enable_pid’.

Of course, we have to add some fields (like __start_ts, __end_ts as above) in task_struct structure (each process in linux Kernel is represented by one task_struct structure) like following.

1235 struct task_struct {
...
1327                                                                                                            
1328     //added by Weiwei Jia                                                                                                                                                                                                              
1329     struct timeval __ts;                                                                                   
1330     int __start_ts;                                                                                        
1331     int __end_ts;                                                                                          
1332     //ended                                                                                                
1333
...
1675 };                

Up to here, everything is okay, we just need to recompile the kernel and load it. After the kernel is loaded, echo ‘1’ to “/sys/module/core/parameters/enable_flag” and process PID to “/sys/module/core/parameters/enable_pid” to find process’s timeslices (use ‘dmesg’ command to retrieve timeslices).

Conclusion
This article introduces a simple way to get timeslices of processes. You can also use some other ways, for example, export interface in proc FS or use one self-made module and so on. However, I think the way shown above is simplest and with high efficiency.

2 comments:

  1. A nice post!

    But this part seems incomplete:

    //added by Weiwei Jia
    #include 
    int enable_flag = 0;
    module_param(enable_flag, int, 0664);
    EXPORT_SYMBOL_GPL(enable_flag);
    
  2. Yes, it is really incomplete. The complete one should be like following.

    //added by Weiwei Jia
    #include <linux/time.h>
    int enable_flag = 0;
    module_param(enable_flag, int, 0664);
    EXPORT_SYMBOL_GPL(enable_flag);
    //ended

    It seems that WordPress will remove the contents inside angle brackets. At last, I find a way to input angle brackets but still cannot add angle brackets in the code “{{{…}}}” field.

Leave a Reply

Your email address will not be published. Required fields are marked *