I\'m trying to understand what happens during the load_balance function.
I\'m checking version 3.14 but I also took a look at version 4.3 since I was told that
CFS holds a tree of "scheduling entities". Each scheduling entity can have its own tree, and so on in a recursive way... (This is useful, for example, for grouping all the processes of a specific user into one scheduling entity; thus preventing a user that has many tasks from consuming more cpu time than users with fewer processes)
task_h_load - stands for "task hierarchical load"
Since a task can be nested in a few trees, then calculating its load is not so simple...
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);
}
At the beginning cfs_rq points to the immediate tree at which p is found in. If we had only two nested trees then calculating the load of p would have been simple:
task_h_load = task_load_in_its_tree * ( load_of_immediate_tree / load_of_containing_tree);
(while immediate_tree refers to the tree that contains the task, and containing_tree refers to the tree that contains the tree that contains the task.)
But this is not the case. Our tree might be a nested tree inside a scheduling entity, which is itself just a leaf in another tree.
So, the first thing we do is to call update_cfs_rq_h_load(cfs_rq) which computes the hierarchical load factor for cfs_rq and all its ascendants (ancestors): this function goes up the tree hierarchy all the way to the root, and down from the root to our cfs_rq while computing the hierarchical load factor for each tree in the hierarchy.
The computation is done in a similar way:
cfs_rq_h_load = cfs_rq_load_in_its_tree * (load_of_immediate_tree / load_of_containing_tree)
So, finally we have the fractional load of cfs_rq and all we have to do is to calculate the h_load using the same formula.
task_h_load = task_load_in_its_tree * (load_of_immediate_tree / load_of_containing_tree)