调度器30—调度相关结构体—p->state
一、TASK_DEAD
1. 赋值调用路径
do_exit //的最后调用 do_task_dead //sched/core.c set_special_state(TASK_DEAD); WRITE_ONCE(current->__state, state_value); copy_process //fork.c 中 copy_creds() 执行失败调用,非主要路径 WRITE_ONCE(p->__state, TASK_DEAD); //kernel/fork.c
看来是任务自己主动退出时将自己设置为 TASK_DEAD 状态。
二、TASK_NOLOAD
1. TASK_NOLOAD 或在 TASK_IDLE 上使用,主要使用位置:
#define TASK_IDLE TASK_UNINTERRUPTIBLE | TASK_NOLOAD) swait_event_idle_exclusive //这里面使用 TASK_IDLE 状态 schedule_timeout_idle(signed long timeout) //将当前进程设置为 TASK_IDLE,然后休眠timeout时间后被唤醒 schedule_timeout_uninterruptible(signed long timeout) //常用的是这类将当前进程设置为 TASK_UNINTERRUPTIBLE/TASK_INTERRUPTIBLE
2. TASK_NOLOAD 唯一使用位置:
__schedule if (!preempt && prev_state) { //若不是抢占,prev->state的状态也不是TASK_RUNNING才会发生deactive prev task。 prev->sched_contributes_to_load =(prev_state & TASK_UNINTERRUPTIBLE) && !(prev_state & TASK_NOLOAD) && !(prev->flags & PF_FROZEN); //主要影响 sched_contributes_to_load 的值 if (prev->sched_contributes_to_load) rq->nr_uninterruptible++; }
3. prev->sched_contributes_to_load 的使用位置:
位置1:
ttwu_do_activate if (p->sched_contributes_to_load) rq->nr_uninterruptible--;
位置2:就是上面赋值和加加,没有其它使用位置了。
4. rq->nr_uninterruptible 使用位置:
print_cpu ///kernel/sched/debug.c P(nr_uninterruptible) //# cat /proc/sched_debug | grep nr_uninterruptible 打印每个cpu的这个值
然后就是上面core.c中的++/--
scheduler_tick //core.c calc_load_nohz_fold //loadavg.c 将delta加到全局变量 calc_load_tasks tick_nohz_stop_tick calc_load_nohz_start //loadavg.c sched_tick_start sched_tick_remote //core.c INIT_DELAYED_WORK(&twork->work, sched_tick_remote); 异步调用的 calc_load_nohz_remote //loadavg.c calc_global_load_tick calc_load_fold_active nr_active += (long)this_rq->nr_uninterruptible;
loadavg.c: 全局负载平均值是 nr_running + nr_uninterruptible 的指数衰减平均值。
5. 全局变量 calc_load_tasks:
在 loadavg.c 中主要用于初始化 avenrun[] 数组
avenrun[] 数组: SYSCALL_DEFINE1(sysinfo, struct sysinfo __user *, info) //kernel/sys.c COMPAT_SYSCALL_DEFINE1(sysinfo, struct compat_sysinfo __user *, info) //kernel/sys.c do_sysinfo //kernel/sys.c get_avenrun //sched/loadavg.c
拷贝到用户空间,报告 1, 5, and 15 minute load averages。
/proc/loadavg 文件,cat如下 loadavg_proc_show //proc/loadavg.c get_avenrun //sched/loadavg.c //对应: # cat /proc/loadavg 15.30 15.21 12.72 1/3499 8280
6. 结论:看来 TASK_NOLOAD 的影响对调度/调频没有关系,只与上层统计 1, 5, 15分钟的负载有关。
posted on 2023-01-31 22:37 Hello-World3 阅读(239) 评论(0) 编辑 收藏 举报