3

我正在探索 CFS 调度程序。根据 CFS,vruntime 是进程在 CPU 上运行的时间。因此,一旦一个进程消耗了一些 CPU,它的 vruntime 就会增加。

为了深入理解 context_switch 的概念,我研究了 kernel/sched/core.c 文件的 context_switch 方法实现。

context_switch(struct rq *rq, struct task_struct *prev,
           struct task_struct *next)

要了解上下文切换所涉及的进程 - 特别是要知道哪个进程被调度出来以及哪个进程被调度进来,我添加了

trace_printk(KERN_INFO "**$$,traceme,%d,%llu,%llu,%d,%llu,%llu\n", (int)(prev->pid),prev->se.vruntime,prev->se.sum_exec_runtime, (int)(next->pid),next->se.vruntime,next->se.sum_exec_runtime);

在 kernel/sched/core.c 文件的 context_switch() 函数内部。

清理后的一些样本数据

//(prev->pid),prev->se.vruntime,prev->se.sum_exec_runtime, (int)(next->pid),next->se.vruntime,next->se.sum_exec_runtime



 Line-1 :    7560,24498429469681,823155565,7566,24498418258892,1637962
 Line-2 :    7566,24498418261234,1640304,7580,24498417733416,1018016
 Line-3 :    7580,24498417752807,1037407,686,24498429468802,48339928895
 Line-4 :    686,24498429469817,48339929910,7566,24498418261234,1640304
 Line-5 :    7566,24498418263610,1642680,7581,24498417762357,1038126
 Line-6 :    7581,24498417781339,1057108,7560,24498429469681,823155565

 Line-7 :    7560,24498429470724,823156608,7566,24498418263610,1642680
 Line-8 :    7566,24498418265980,1645050,7582,24498418395747,1202608
 Line-9 :    7582,24498418414400,1221261,686,24498429469817,48339929910
 Line-10:    686,24498429470804,48339930897,7566,24498418265980,1645050
 Line-11:    7566,24498418268334,1647404,7583,24498417826636,1168325
 Line-12:    7583,24498417845297,1186986,7560,24498429470724,823156608

 Line-13:    7560,24498429471802,823157686,7566,24498418268334,1647404
 Line-14:    7566,24498418270800,1649870,686,24498429470804,48339930897
 // Up to this line vruntime of all process increased in each run as expected.


 Line-15: 686,24498438028365,48348488458,7560,24498429471802,823157686
 Line-16: 0,0,0,7,918077230457,2930949708
 Line-17: 7,918077232097,2930951348,0,0,0
 Line-18: 7560,6056741110796,823305719,7584,24498429478909,1156272 <---- Here vruntime of process 7560 is decreased . Why?

从上面的数据我们可以推断出每个进程在被调度之前执行了多少时间。

p_pid   p_vrt         p_sum_exe_rt   n_pid    n_vrt     n_sum_exe_rt                 |  prev_tslice next_tslice  CPU
 7560 ,  24498429469681,       823155565,   7566 ,  24498418258892,        1637962, | ,       1191 ,      2327 
  7566 ,  24498418261234,         1640304,   7580 ,  24498417733416,        1018016, | ,       2342 ,     19462 
  7580 ,  24498417752807,         1037407,    686 ,  24498429468802,    48339928895, | ,      19391 ,      1003 
   686 ,  24498429469817,     48339929910,   7566 ,  24498418261234,        1640304, | ,       1015 ,      2342 
  7566 ,  24498418263610,         1642680,   7581 ,  24498417762357,        1038126, | ,       2376 ,     18429 
  7581 ,  24498417781339,         1057108,   7560 ,  24498429469681,      823155565, | ,      18982 ,      1191 

  7560 ,  24498429470724,       823156608,   7566 ,  24498418263610,        1642680, | ,       1043 ,      2376 
  7566 ,  24498418265980,         1645050,   7582 ,  24498418395747,        1202608, | ,       2370 ,     19520 
  7582 ,  24498418414400,         1221261,    686 ,  24498429469817,    48339929910, | ,      18653 ,      1015 
   686 ,  24498429470804,     48339930897,   7566 ,  24498418265980,        1645050, | ,        987 ,      2370 
  7566 ,  24498418268334,         1647404,   7583 ,  24498417826636,        1168325, | ,       2354 ,     19617 
  7583 ,  24498417845297,         1186986,   7560 ,  24498429470724,      823156608, | ,      18661 ,      1043 
  7560 ,  24498429471802,       823157686,   7566 ,  24498418268334,        1647404, | ,       1078 ,      2354 


   7566 ,  24498418270800,         1649870,    686 ,  24498429470804,    48339930897, | ,       2466 ,       987 



   686 ,  24498438028365,     48348488458,   7560 ,  24498429471802,      823157686, | ,    8557561 ,      1078 
 //----------------------- Up to this line vruntime is increased      
   7560 ,   6056741110796,       823305719,   7584 ,  24498429478909,        1156272, | ,     148033 ,     18671 

一切看起来都很完美 - 每次运行都会增加进程的 vruntime。

令我惊讶的是,在最后一行中,正在运行的进程的 vruntime 减少了

  1. pid 7560 进程的 vruntime 在最后一行减少(从 24498429471802 到 6056741110796) - 为什么?

  2. 即使进程被固定到特定的 CPU 核心(因此没有机会迁移到其他 CPU 核心),如何减少正在运行的进程的 vruntime?

  3. 另一个重要的观察结果是,在其他运行 7560 进程中运行的时间片较短,但最后一次它获得了更高的时间片。更大的时间片和减少 vruntime 之间有什么关联吗?

我正在使用 Debian 8.0 和 Ubuntu 16.04,内核 3.16.35,这在两个操作系统中都发生了。

任何了解原因的链接都会有很大帮助。

4

0 回答 0