2

enqueue_task_rtfunction in./kernel/sched/rt.c负责将任务排入运行队列。enqueue_task_rt包含调用enqueue_rt_entity哪个调用dequeue_rt_stack。大部分代码看起来合乎逻辑,但由于函数dequeue_rt_stack无法理解它的作用,我有点迷茫。有人可以告诉我我缺少什么逻辑或建议一些好读的东西。

编辑:以下是dequeue_rt_stack函数的代码

     struct sched_rt_entity *back = NULL;
     /* macro for_each_sched_rt_entity defined as
     for(; rt_se; rt_se = rt_se->parent)*/
     for_each_sched_rt_entity(rt_se) {
             rt_se->back = back;
             back = rt_se;
     }

     for (rt_se = back; rt_se; rt_se = rt_se->back) {
             if (on_rt_rq(rt_se))
                     __dequeue_rt_entity(rt_se);
     }

更具体地说,我不明白为什么需要这段代码:

     for_each_sched_rt_entity(rt_se) {
             rt_se->back = back;
             back = rt_se;
     }

它的相关性是什么。

4

2 回答 2

3

当一个任务被添加到某个队列时,它必须首先从它当前所在的队列中移除,如果有的话。

使用group scheduler,任务始终位于树的最低级别,并且可能有多个祖先:

       NULL
         ^
         |
+-----parent------+
|                 |
| top-level group |
|                 |
+-----------------+
         ^      ^_____________
         |                    \
+-----parent------+   +-----parent------+
|                 |   |                 |
| mid-level group |   |   other group   |  ...
|                 |   |                 |
+-----------------+   +-----------------+
         ^      ^_____________
         |                    \
+-----parent------+   +-----------------+
|                 |   |                 |
|      task       |   |   other task    |  ...
|                 |   |                 |
+-----------------+   +-----------------+

要从树中删除任务,必须将其从所有组的队列中删除,并且必须首先在顶级组中完成(否则,调度程序可能会尝试运行已经部分删除的任务)。因此,dequeue_rt_stack使用back指针构造一个相反方向的列表:

   NULL    back
     ^      |
     |      V
+-parent----------+
|                 |
| top-level group |
|                 |
+----------back---+
     ^      |   ^_____________
     |      V                 \
+-parent----------+   +-----parent------+
|                 |   |                 |
| mid-level group |   |   other group   |  ...
|                 |   |                 |
+----------back---+   +-----------------+
     ^      |   ^_____________
     |      V                 \
+-parent----------+   +-----------------+
|                 |   |                 |
|      task       |   |   other task    |  ...
|                 |   |                 |
+----------back---+   +-----------------+
            |
            V
           NULL

back然后可以使用该列表沿着树向下走,以正确的顺序删除实体。

于 2012-10-19T13:02:52.997 回答
1

我是内核黑客的新手。这是我第一次回答linux内核问题。也许这对你有帮助。

我阅读了源代码。我认为这可能与小组安排有关。

当内核有这些代码时:

#ifdef CONFIG_RT_GROUP_SCHED

它表示我们可以将一些调度实体收集到一个调度组中。

static void enqueue_rt_entity(struct sched_rt_entity *rt_se, bool head)

{

    dequeue_rt_stack(rt_se);
    for_each_sched_rt_entity(rt_se)
          __enqueue_rt_entity(rt_se, head);

}

函数 dequeue_rt_stack(rt_se) 提取属于该组的所有调度实体,然后将它们添加到运行队列中。

分层组 I/O 调度

CFS 组调度

于 2012-10-10T03:25:50.377 回答