对待实时进程(RT)抢占的问题

晨曦之光 发布于 2012/04/10 14:58
阅读 259
收藏 0

一个进程被唤醒,在linux中是调用try_to_wake_up函数,对于RT进程也不例外,对于一般进程而言,如果在一个cpu运行队列上被唤醒的进程的优先级大于该cpu的当前进程,那么就会发生抢占,而如果两个进程都是RT进程则不会发生抢占,理由是cache的保持,如果发生抢占的话,被抢占的RT进程将丢失其所有的cache,可是这样做合理吗?
     先看一下RT进程的特征,这种进程一旦运行,除非自愿放弃cpu,一般是不会停止运行的,对于高优先级的RT进程总是优先运行,如果对于RT进程为了保持cache不抢占的话,除了cache的保持之外,其实是得不到任何优势的,并且,在这种情况下还会造成RT进程的乒乓效应,也就是造成RT进程频繁迁移,在很多RT进程争抢一个资源,比如lock的情况下,这种乒乓效应带来的弊端更加明显,低优先级的RT进程释放了lock,唤醒了高优先级的RT进程,由于此时当前cpu上的进程仍然是低优先级的进程,所有被唤醒的高优先级进程不得不被迁移到别的cpu上执行,如果低优先级的进程没有释放资源,而由于另一个原因睡眠了,此时它的优先级可能已被提升,当它再度被另一RT进程唤醒的时候,即使它拥有高优先级也不得不迁移到另外的cpu上,这些迁移动作肯定会影响性能的。可以说,RT进程调度的无条件不抢占特性大大削弱了高优先级RT进程的优势,高优先级RT进程除了在运行队列的位置靠前之外,没有多少优势可言了。
     确实,如果是由于非争抢资源被释放原因的唤醒,那抢占正在运行的rt进程确实对于cache优化是一种抵消,然而要知道即使这样我们也只是损失了相对低优先级rt进程的性能,我们得到的是避免了一次高优先级rt进程的迁移。另一方面,当我们面对多个rt进程争抢资源这种类型的睡眠/唤醒时,抢占的优势就明显了,有时一个又有很高优先级的rt进程在运行中由于得不到资源而睡眠,这种睡眠时间一般不会太久,只是一小会儿,它争抢的资源此时正在被一个低优先级的rt进程占据,此时它提升低优先级进程的优先级,以使它不被抢占地尽快完成资源的释放,这一切都是为了高优先级进程不会睡得太久,于是资源尽可能早的被释放了,高优先级进程被唤醒,此时应该知道,将此高优先级rt进程唤醒在它本来运行的cpu上是一个最佳的选择。
     这就是一个权衡的问题了,是保留cache还是最小化迁移,还是交给调度器吧,严格按照优先级调度会好一些,起码能照顾高优先级的RT进程,使得高优先级的RT进程的优势更加明显。于是,新的2.6.37内核对此进行了改进,补丁很简单:
--- a/kernel/sched_rt.c
+++ b/kernel/sched_rt.c
@@ -960,18 +960,18 @@ select_task_rq_rt(struct rq *rq, struct task_struct *p, int sd_flag, int flags)
        if (unlikely(rt_task(rq->curr)) &&
+           rq->curr->prio < p->prio &&
            (p->rt.nr_cpus_allowed > 1)) {
                int cpu = find_lowest_rq(p);
 
@@ -1491,6 +1491,8 @@ static void task_woken_rt(struct rq *rq, struct task_struct *p)
        if (!task_running(rq, p) &&
            !test_tsk_need_resched(rq->curr) &&
            has_pushable_tasks(rq) &&
+           rt_task(rq->curr) &&
+           rq->curr->prio < p->prio &&
            p->rt.nr_cpus_allowed > 1)
                push_rt_tasks(rq);
}


原文链接:http://blog.csdn.net/dog250/article/details/6129396
加载中
返回顶部
顶部