函数更新进程从其他状态(休眠,不可中断等)切换到运行状态后进入运行等待队列的起始时刻;
enqueue_task->sched_info_queued
进程被从一个cpu的运行等待队列移动到另外一个cpu的运行等待队列时更新进入新的运行等待队列的起始时刻:
更新进程从正在运行被调度放入可运行队列的起始时刻:
__sched_info_switch->sched_info_depart->sched_info_queued
static inline void sched_info_queued(struct task_struct *t)
{
if (unlikely(sched_info_on()))
if (!t->sched_info.last_queued)//为0代表当前不是在可运行队列中;
t->sched_info.last_queued = task_rq(t)->clock;
}
//更新task_struct 结构体成员sched_entity的exec_start:
schedule ->pick_next_task->pick_next_task_fair->set_next_entity->update_stats_curr_start
//进程从运行队列中被调度到cpu上运行时更新last_arrival:
schedule ->sched_info_switch->__sched_info_switch->sched_info_arrive
exec_start与last_arrival 的区别是last_arrival只有当同一cpu上一次运行的任务跟即将调度运行的任务不是同一个任务时才会更新,而exec_start则在进程每一次被调度运行时都会更新,比如cpu当前运行的是任务id 100,紧接着下一次调度到同一个cpu运行的任务如果还是该进程id 100,那么此时会更新exec_start,但是不会再次更新last_arrival。所以使用last_arrival 来统计连续占用一个cpu的时间更贴切。
static inline void
update_stats_curr_start(struct cfs_rq *cfs_rq, struct sched_entity *se)
{
/*
* We are starting a new run period:
*/
se->exec_start = rq_of(cfs_rq)->clock_task;
}
static void sched_info_arrive(struct task_struct *t)
{
unsigned long long now = task_rq(t)->clock, delta = 0;
if (t->sched_info.last_queued)
delta = now - t->sched_info.last_queued;//当前时刻减去进程进入运行等待队列时间得到进程在运行等待队列中排队等待的时间
sched_info_reset_dequeued(t);//这个函数将sched_info.last_queued置为0
t->sched_info.run_delay += delta;//累加在运行等待队列的等待时间
t->sched_info.last_arrival = now;//记录当前时刻到last_arrival,也就是最新一次进程被调度到cpu运行的起始时间
t->sched_info.pcount++;//累加进程被调度到cpu运行的次数
rq_sched_info_arrive(task_rq(t), delta);
}
实例说明:
系统触发panic时刻:
crash> log | grep panic
[1538913.626675] begin to panic..
进程billserver开始在cpu 0上运行的时刻:
crash> ps -l | grep 160945
[1538793610558655] [RU] PID: 160945 TASK: ffff880b6fcf2200 CPU: 0 COMMAND: "billserver"
crash>
crash> struct task_struct ffff880b6fcf2200 | grep sched_info -A5
sched_info = {
pcount = 5426473,//进程启动后被调度在cpu上运行的次数
run_delay = 13234246925,//进程启动后在运行等待队列中累加总共等待的时间
last_arrival = 1538793610558655,//进程上一次获取cpu资源,开始被调度在cpu上运行的时刻
last_queued = 0,//进入可运行等待队列的时刻,也就是处于RUNNING状态,但是还未被调度到cpu上运行。
//为0代表此时不在运行等待队列中(包括IN,UN状态以及RUNNING状态并且当前已经在cpu运行,这里的例子是正在cpu上运行)
bkl_count = 0
crash>
系统panic的时刻减去进程最后一次被调度到cpu上运行的开始时刻(并且当前还在cpu上运行着)即为该进程最后一次在该cpu上运行到系统出现panic时连续占用cpu的总时间
crash> eval 1538913-1538793
hexadecimal: 78
decimal: 120
octal: 170
binary: 0000000000000000000000000000000000000000000000000000000001111000
crash>
crash> ps -l | grep 15095
[1538783705296235] [RU] PID: 15095 TASK: ffff880c6f1aa240 CPU: 0 COMMAND: "watchdog/0"
crash>
crash> struct task_struct ffff880c6f1aa240 | grep sched_info -A5
sched_info = {
pcount = 57323,//进程启动后被调度在cpu上运行的次数
run_delay = 699350653,//进程启动后在运行等待队列中累加总共等待的时间
last_arrival = 1538783705296235,//进程上一次获取cpu资源,开始被调度在cpu上运行的时刻
last_queued = 1538810548747542,//进入可运行等待队列的时刻,也就是处于RUNNING状态,但是还未被调度到cpu上运行;
// last_queued比last_arrival大代表进程已经进入可运行等待队列,但是还没有被调度到cpu上运行
bkl_count = 0
crash>
watchdog/0进程上一次在cpu上运行到重启时间已经过去130s
crash> eval 1538913-1538783
hexadecimal: 82
decimal: 130
octal: 202
binary: 0000000000000000000000000000000000000000000000000000000010000010
crash>
watchdog/0进程在运行等待队列中等待的时间已经过去103s
crash> eval 1538913-1538810
hexadecimal: 67
decimal: 103
octal: 147
binary: 0000000000000000000000000000000000000000000000000000000001100111
crash>
实例说明:
系统触发panic时刻:
crash> log | grep panic
[1538913.626675] begin to panic..
进程billserver开始在cpu 0上运行的时刻:
crash> ps -l | grep 160945
[1538793610558655] [RU] PID: 160945 TASK: ffff880b6fcf2200 CPU: 0 COMMAND: "billserver"
crash>
crash> struct task_struct ffff880b6fcf2200 | grep sched_info -A5
sched_info = {
pcount = 5426473,//进程启动后被调度在cpu上运行的次数
run_delay = 13234246925,//进程启动后在运行等待队列中累加总共等待的时间
last_arrival = 1538793610558655,//进程上一次获取cpu资源,开始被调度在cpu上运行的时刻
last_queued = 0,//进入可运行等待队列的时刻,也就是处于RUNNING状态,但是还未被调度到cpu上运行。
//为0代表此时不在运行等待队列中(包括IN,UN状态以及RUNNING状态并且当前已经在cpu运行,这里的例子是正在cpu上运行)
bkl_count = 0
crash>
系统panic的时刻减去进程最后一次被调度到cpu上运行的开始时刻(并且当前还在cpu上运行着)即为该进程最后一次在该cpu上运行到系统出现panic时连续占用cpu的总时间
crash> eval 1538913-1538793
hexadecimal: 78
decimal: 120
octal: 170
binary: 0000000000000000000000000000000000000000000000000000000001111000
crash>
crash> ps -l | grep 15095
[1538783705296235] [RU] PID: 15095 TASK: ffff880c6f1aa240 CPU: 0 COMMAND: "watchdog/0"
crash>
crash> struct task_struct ffff880c6f1aa240 | grep sched_info -A5
sched_info = {
pcount = 57323,//进程启动后被调度在cpu上运行的次数
run_delay = 699350653,//进程启动后在运行等待队列中累加总共等待的时间
last_arrival = 1538783705296235,//进程上一次获取cpu资源,开始被调度在cpu上运行的时刻
last_queued = 1538810548747542,//进入可运行等待队列的时刻,也就是处于RUNNING状态,但是还未被调度到cpu上运行;
// last_queued比last_arrival大代表进程已经进入可运行等待队列,但是还没有被调度到cpu上运行
bkl_count = 0
crash>
watchdog/0进程上一次在cpu上运行到重启时间已经过去130s
crash> eval 1538913-1538783
hexadecimal: 82
decimal: 130
octal: 202
binary: 0000000000000000000000000000000000000000000000000000000010000010
crash>
watchdog/0进程在运行等待队列中等待的时间已经过去103s
crash> eval 1538913-1538810
hexadecimal: 67
decimal: 103
octal: 147
binary: 0000000000000000000000000000000000000000000000000000000001100111
crash>
---来自腾讯云社区的---CD
微信扫一扫打赏
支付宝扫一扫打赏