EDF时间管理
EDF的时间更新可以理解为edf runtime的一个消耗,或者叫做更新它的执行时间。它的更新时间有两个地方:
1. 每个时钟中断到来的时候,比如HZ=1000的话,即每1ms更新一次。
调用的关系如下:
Tick_periodic(int cpu)
-->update_process_timers();
--->scheduler_tick()
--->curr->sched_class->task_tick();
如果是EDf的调度的话就调用edf实现的tack_tick()函数。分析如下:
2. 每个cpu rq中的hrtimer到期时间。Hrtimer的到期时间函数为hrtick函数。
Hrimter_restart()
—rq->curr->sched_class->task_tick();
进行时间的更新的函数又主要在task_tick_dl函数中。我们看下它的具体的实现
static void task_tick_dl(struct rq *rq, struct task_struct *p, int queued)
{
update_curr_dl(rq);
ifdef CONFIG_SCHED_HRTICK
if (hrtick_enabled(rq) && queued && p->dl.runtime > 0)
start_hrtick_dl(rq, p);
endif
}
首先,更新当前的rq的时间。然后,如果使能了高精度定时器。启动高精度定时器。定时的时间为剩余的runtime的长度。EDF使用高精度定时器有两个地方:
1. Pick_next_task,在选择下个任务的时候
2. Task_tick_dl,在系统tick的时候
EDF负载均衡
Edf调度类本身同rt调度类一样实现了自己的负载均衡的函数,同样它和其它的负载均衡的原理差不多,如下:
确保每个cpu的负载均衡在cpu和cache以及内存布局的影响下加权执行对于实施进程的均衡则要保证系统有N个cpu核心时,保证系统优先级队列中的top-N的实时进程得到运行。
负载均衡的时机:
负载均衡分两种情况,push和pull。分别指把当前cpu上的dl任务迁移到别的cpu上去和把别的cpu上的dl任务迁移到当前的cpu上来。
首先看下push的时机:
Dl_task_timer
从前面可知,dl_task_timer是用来将已经throttled的进程重新插入dl的队列中。这个时候当前的cpu的dl任务会增多,因此会考虑是不是要迁移。
1.__schedule
当需要切换的进程是dl的任务的时候,同样当前的cpu中的任务也会增多,同样会考虑是否要迁移。
2.Switched_to_dl
当把一个其他的调度类的进程转化成EDF任务的时候,同样增加了当前cpu的EDF任务,这时候也会考虑迁移。
再看下pull的时机:
3.Prio_changed_dl
如果改变正在运行的EDF进程的prio,即deadline的值,则有可能其他cpu上的EDF任务有可能迁移到本cpu上来。
4.Schedule
当被调走的任务是EDF任务时候,则有可能迁移其他cpu的EDF任务到本cpu上来。
5.Switch_from_dl
同push一样,当把EDF的任务改成其他类型的任务时,其它cpu的EDF任务有可能迁移到本cpu上来。
负载均衡实现的原理:
上面介绍的是负载均衡的时机,但并不是所有的时机到了就一定发生迁移,而是需要许多触发的条件。而这些触发的条件就需要引入更多的管理结构。
struct array_item {
u64 dl;
int cpu;
};
dl:deadline的值
cpu:cpu的编号
struct cpudl {
raw_spinlock_t lock;
int size;
int cpu_to_idx[NR_CPUS];
struct array_item elements[NR_CPUS];
cpumask_var_t free_cpus;
};
Int Cpu_to_idx[NR_CPUS]: 通过cpu号找到对应在array_item_elements中的值
struct array_item elements[NR_CPUS]: 记录了每个cpu上的deadline的最小的任务的deadline的值。
cpumask_var_t free_cpus:哪些cpu上还没有EDF任务
这个结构里最重要的元素就是array_item_elements数组,它里面的每个元素记录了是cpu号及此cpu上优先级最高的dl任务的deadline值。它的数组元素的组织形式是一颗二叉树,构建这棵二叉树的原则就是根节点的deadline值要大于子节点的deadline的值。
图5 deadline索引图
本章小结
本章讲述了EDF的基本概念,分析其在linux的内实现的原理和机制。描述了如何使用EDF。通过分析可以看出EDF是一个动态优先级的实时调度类。根据deadline(截止时间)来定优先级,在多任务是哪个任务的deadline(截止时间)越小哪个任务的优先级就月高,就首先得到cpu调度运行。