Linux Kernel- task_h_load

我试图了解在load_balance函数中发生了什么。
我正在检查版本3.14,但我也看了4.3版,因为有人告诉我,这个版本的机制已经改变了,并且更加清晰。

v3.14中 ,调用来自move_tasks

v4.3中 ,调用来自detach_tasks

从我看到它是相同的function,但只有一个不同的名称。

此函数根据env->balance参数将任务从一个队列移动到另一个队列。
我不明白的是在task_h_load如何计算负载。

有没有人知道负载成员代表以及如何在task_h_load函数中计算?

Solutions Collecting From Web of "Linux Kernel- task_h_load"

CFS拥有一个“调度实体”的树。 每个调度实体都可以有自己的树,等等以递归的方式…(例如,这对于将特定用户的所有进程分组到一个调度实体是有用的;从而防止具有许多任务的用户比使用更少的进程消耗更多的CPU时间)

task_h_load – 代表“ 任务层次加载

由于一个任务可以嵌套在一些树中,那么计算它的负载就不那么简单了。

 static unsigned long task_h_load(struct task_struct *p){ struct cfs_rq *cfs_rq = task_cfbs_rq(p); update_cfs_rq_h_load(cfs_rq); return div64_ul(p->se.avg.load_avg * cfs_rq->h_load, cfs_rq_load_avg(cfs_rq) + 1); } 

在开始时, cfs_rq指向发现p的直接树。如果我们只有两个嵌套树,那么计算p的负载就简单了:

task_h_load = task_load_in_its_tree *(load_of_immediate_tree / load_of_containing_tree);

(而immediate_tree是指包含任务的树,而contains_tree是指包含包含任务的树的树。)

但这种情况并非如此。 我们的树可能是一个调度实体内部的嵌套树,它本身就是另一棵树中的一片叶子。

所以,我们要做的第一件事就是调用update_cfs_rq_h_load(cfs_rq)来计算cfs_rq及其所有祖先(祖先)的层次加载因子:这个函数从树根到树根,然后从根到树我们的cfs_rq同时计算层次结构中每个树的分层负载因子。

计算以类似的方式完成:

cfs_rq_h_load = cfs_rq_load_in_its_tree *(load_of_immediate_tree / load_of_containing_tree)

所以,最后我们有cfs_rq的分数负载,我们所要做的就是使用相同的公式计算h_load。

task_h_load = task_load_in_its_tree *(load_of_immediate_tree / load_of_containing_tree)

如果配置了SMP,则会调用负载均衡.Linux使用完全公平调度程序 (CFS)来调度每个任务,以使每个任务获得处理器时间的“公平”份额。CFS使用红黑树的概念。

在这里输入图像说明

调度程序记录任务进入运行队列的当前时间。 当进程等待处理器时间时,“等待”值将从当前运行队列中的任务总数和进程优先级中获​​得的值增加。 处理器运行此任务时,此“等待”值将递减。 如果这个值下降到一定值以下,那么调度器将抢占任务,而其他任务接近处理器执行。 CFS总是试图通过保持“等待”值为零来保持情况的理想。

linux负载均衡和select_task_rq_fair()有两个函数用于执行负载均衡任务。

简单地说,CFS负载均衡机制将繁忙的CPU卸载到不太忙或理想的CPU。

task_h_load用于计算任务的权重。

我不明白的是在task_h_load中如何计算负载。 它是如何计算在task_h_load函数?

这个权重因素取决于过程的价值。

 weighting factor = weight of process with nice value 0 / weight of current task; 

其中“ 重量 ”约等于1024 *(1.25)^( – 很好)

例如:好的值1的权重是820.好的值-1的权重是1277

task_h_load
对于更多的负载均衡方法和基础知识,请参阅内核注释 task_h_load使用update_cfs_rq_h_load来计算公平时间调度的运行队列的分层负载,以及使用cfs_rq_load_avg返回runqueue load_avg的平均负载的分层负载。

虚拟运行时间是任务在CPU上运行的加权时间。 CFS总是设法保持这棵红黑树平衡。

在这里输入图像说明

< – 较小的值———– vruntime值——–较大的值 – >

每个可运行任务都放置在基于vruntime自平衡红黑树上。 如果任务已准备好运行(意味着任务不等待任何资源),则将其放置到树中。 如果任务正在等待某个资源(即等待I / O),那么它将被删除。 具有较少处理时间(意味着较小的vruntime )的任务朝向树的左侧,具有较多处理时间的任务是树的右侧。

左节点具有最小的键值(对于CFS,它是具有较高优先级的任务)。 自平衡红黑树需要O(lgN)操作才能导航到左节点。 调度程序将此值缓存在rb_leftmost 。 通过只检索这个值,调度程序确定下一个要运行的任务

此负载平衡仅用于实际任务的非真实任务任务由Steven Rostedt和Gregory Haskins开发的推拉操作

关于CFS还有一件事情也对公平组排序有帮助。请参考下图

在这里输入图像说明

move_task只是简单地将不平衡加权负载(如上所示的计算负载因子后的方法)从this_rqthis_rqthis_rq 。 它试图平衡两个运行队列的负载平衡,以便两者都可以节省“合理”的处理器时间。

detach_task分离在linux内核的env指针中指定的迁移任务。

detach_one_task试图从env-> src_rq中准确出列一个任务。

detach_tasks()尝试从busiest_rq分离出不平衡加权负载。 它返回分离任务的数量,否则返回零,如果不能分离。

要将这个分离的任务附加到新的rq (运行队列),根据情况使用attach_task, attach_one_task,attach_tasks

新的警告检查lockdep_assert_held()detach_tasks中引入,而detach_tasks中不存在

在多处理器上,如此容易地移动任务是不容易的,所以cfs执行域特定的负载平衡如下: 在这里输入图像说明

为了这一切理解,我希望你通过以下参考

  1. 用于负载平衡的每个实体负载跟踪度量

  2. 重量因素

  3. 开放式的SUSE

  4. 罗伯特爱第3章

  5. CPU调度

我特意阅读了所有这些文件来回答你的问题,我希望你不要介意如果有东西丢失评论。