【问题标题】:how list_head structure used for scheduling in kernellist_head 结构如何用于内核中的调度
【发布时间】:2012-10-07 21:13:41
【问题描述】:

我已经阅读了一些内容,从中可以看出,与其使用调度策略来调度任务,不如使用调度策略来调度实体。优点是您可以使用相同的调度策略来调度许多事情。因此,为两个调度策略(CFS 和 RT)定义了两个实体,即sched_entitysched_rt_entity。 CFS 实体的代码是(从 v3.5.4 开始)

struct sched_entity {
    struct load_weight  load;       /* for load-balancing */
    struct rb_node      run_node;
    struct list_head    group_node;
    unsigned int        on_rq;

    u64         exec_start;
    u64         sum_exec_runtime;
    u64         vruntime;
    u64         prev_sum_exec_runtime;

    u64         nr_migrations;


#ifdef CONFIG_SCHEDSTATS
    struct sched_statistics statistics;
#endif

#ifdef CONFIG_FAIR_GROUP_SCHED
    struct sched_entity *parent;
    /* rq on which this entity is (to be) queued: */
    struct cfs_rq       *cfs_rq;
    /* rq "owned" by this entity/group: */
    struct cfs_rq       *my_q;
#endif
};

对于 RT(实时)实体是

struct sched_rt_entity {
     struct list_head run_list;
     unsigned long timeout;
     unsigned int time_slice;

     struct sched_rt_entity *back;
     #ifdef CONFIG_RT_GROUP_SCHED
     struct sched_rt_entity  *parent;
     /* rq on which this entity is (to be) queued: */
     struct rt_rq            *rt_rq;
     /* rq "owned" by this entity/group: */
     struct rt_rq            *my_q;
     #endif
};

这两个都使用./include/linux/types.h中定义的list_head结构

struct list_head {
     struct list_head *next, *prev;
};

老实说,我不明白如何安排这样的事情。谁能解释这是如何工作的。

附言

此外,我真的很难理解数据成员名称的含义。任何人都可以建议阅读理解内核结构的好书,以便我可以轻松地弄清楚这些事情。我花费的大部分时间都浪费在搜索数据成员的含义上。

【问题讨论】:

    标签: linux linux-kernel kernel


    【解决方案1】:

    为了实现组调度,引入了调度实体,因此 CFS(或 RT 调度程序)将为单个任务提供公平的 CPU 时间,同时也为任务组提供公平的 CPU 时间。调度实体可以是一个任务或一组任务。

    struct list_head只是Linux实现链表的方式。在您发布的代码中,group_noderun_list 字段允许创建 struct sched_entitystruct sched_rt_entity 列表。更多信息可以在here找到。

    使用这些list_heads,调度实体存储在某些与调度程序相关的数据结构中,例如cfs_rq.cfs_tasks,如果实体是使用account_entity_enqueue() 排队的任务。

    始终可以在其源代码中找到 Linux 内核的最新文档。在这种情况下,您应该检查this 目录,尤其是描述CFS 的this 文件。还有an explanation的任务组。

    编辑: task_struct 包含 se 类型为 struct sched_entity 的字段。然后,使用container_of 宏获得sched_entity 对象的地址,就可以检索task_struct 对象的地址,参见task_of()。 (sched_entity 对象的地址 - task_structse 的偏移量 = task_struct 对象的地址)这是我之前在此答案中提到的列表实现中使用的非常常见的技巧。

    【讨论】:

    • 感谢它的帮助,但它引起了另一个疑问。关于要安排的任务或组的信息在哪里。我没有看到任何链接,例如 task_struct,这是策略要安排的事情。
    • 基于类似的理由我也有这个疑问:你说“group_noderun_list 允许创建struct sched_entitystruct sched_rt_entity 的列表”但是然后通过这些解析这样形成的列表指针只是给我list_head 指针。如何获得下一个或上一个sched_entity
    • container_of 允许您获取父结构的地址。请参阅我的更新答案以及此:stackoverflow.com/questions/5145027/…
    • 谢谢。知道了。我正在浏览您提供的链接。我认为他们没有太多的实现细节,他们更倾向于展示设计特征。但无论如何,它有点帮助。
    • 您可能想查看 Robert Love 的 Linux Kernel Development (3 ed.)。我不拥有那本书,但它是我所知道的对 Linux 内核内部结构的最新描述。
    猜你喜欢
    • 2015-09-24
    • 2015-08-21
    • 1970-01-01
    • 1970-01-01
    • 2020-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-27
    相关资源
    最近更新 更多