Skip to content
Permalink
Browse files
sched/fair: Correctly insert cfs_rq's to list on unthrottle
This fixes an issue where fairness is decreased since cfs_rq's can
end up not being decayed properly. For two sibling control groups with
the same priority, this can often lead to a load ratio of 99/1 (!!).

This happen because when a cfs_rq is throttled, all the descendant cfs_rq's
will be removed from the leaf list. When they initial cfs_rq is
unthrottled, it will currently only re add descendant cfs_rq's if they
have one or more entities enqueued. This is not a perfect heuristic.

Instead, we insert all cfs_rq's that contain one or more enqueued
entities, or it its load is not completely decayed.

Can often lead to situations like this for equally weighted control
groups:

$ ps u -C stress
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root       10009 88.8  0.0   3676   100 pts/1    R+   11:04   0:13 stress --cpu 1
root       10023  3.0  0.0   3676   104 pts/1    R+   11:04   0:00 stress --cpu 1

Fixes: 31bc6ae ("sched/fair: Optimize update_blocked_averages()")
Signed-off-by: Odin Ugedal <odin@uged.al>
  • Loading branch information
odinuge authored and intel-lab-lkp committed Jun 16, 2021
1 parent 0159bb0 commit 670fb8556a2d3594c67bf4ab2983ba4f91f5686b
Showing 1 changed file with 20 additions and 19 deletions.
@@ -3252,6 +3252,24 @@ static inline void cfs_rq_util_change(struct cfs_rq *cfs_rq, int flags)

#ifdef CONFIG_SMP
#ifdef CONFIG_FAIR_GROUP_SCHED

static inline bool cfs_rq_is_decayed(struct cfs_rq *cfs_rq)
{
if (cfs_rq->load.weight)
return false;

if (cfs_rq->avg.load_sum)
return false;

if (cfs_rq->avg.util_sum)
return false;

if (cfs_rq->avg.runnable_sum)
return false;

return true;
}

/**
* update_tg_load_avg - update the tg's load avg
* @cfs_rq: the cfs_rq whose avg changed
@@ -4702,8 +4720,8 @@ static int tg_unthrottle_up(struct task_group *tg, void *data)
cfs_rq->throttled_clock_task_time += rq_clock_task(rq) -
cfs_rq->throttled_clock_task;

/* Add cfs_rq with already running entity in the list */
if (cfs_rq->nr_running >= 1)
/* Add cfs_rq with load or one or more already running entities to the list */
if (!cfs_rq_is_decayed(cfs_rq) || cfs_rq->nr_running)
list_add_leaf_cfs_rq(cfs_rq);
}

@@ -8012,23 +8030,6 @@ static bool __update_blocked_others(struct rq *rq, bool *done)

#ifdef CONFIG_FAIR_GROUP_SCHED

static inline bool cfs_rq_is_decayed(struct cfs_rq *cfs_rq)
{
if (cfs_rq->load.weight)
return false;

if (cfs_rq->avg.load_sum)
return false;

if (cfs_rq->avg.util_sum)
return false;

if (cfs_rq->avg.runnable_sum)
return false;

return true;
}

static bool __update_blocked_fair(struct rq *rq, bool *done)
{
struct cfs_rq *cfs_rq, *pos;

0 comments on commit 670fb85

Please sign in to comment.