| @@ -2995,6 +2995,8 @@ account_entity_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se) · 2994 unmodified lines |
| 2995 | 2995 | } |
| 2996 | 2996 | #endif |
| 2997 | 2997 | cfs_rq->nr_running++; |
| 2998 | + if (se_is_idle(se)) |
| 2999 | + cfs_rq->idle_nr_running++; |
| 2998 | 3000 | } |
| 2999 | 3001 | |
| 3000 | 3002 | static void |
| @@ -3008,6 +3010,8 @@ account_entity_dequeue(struct cfs_rq *cfs_rq, struct sched_entity *se) · 7 unmodified lines |
| 3008 | 3010 | } |
| 3009 | 3011 | #endif |
| 3010 | 3012 | cfs_rq->nr_running--; |
| 3013 | + if (se_is_idle(se)) |
| 3014 | + cfs_rq->idle_nr_running--; |
| 3011 | 3015 | } |
| 3012 | 3016 | |
| 3013 | 3017 | /* |
| @@ -5577,6 +5581,17 @@ static int sched_idle_rq(struct rq *rq) · 2563 unmodified lines |
| 5577 | 5581 | rq->nr_running); |
| 5578 | 5582 | } |
| 5579 | 5583 | |
| 5584 | +/* |
| 5585 | + * Returns true if cfs_rq only has SCHED_IDLE entities enqueued. Note the use |
| 5586 | + * of idle_nr_running, which does not consider idle descendants of normal |
| 5587 | + * entities. |
| 5588 | + */ |
| 5589 | +static bool sched_idle_cfs_rq(struct cfs_rq *cfs_rq) |
| 5590 | +{ |
| 5591 | + return cfs_rq->nr_running && |
| 5592 | + cfs_rq->nr_running == cfs_rq->idle_nr_running; |
| 5593 | +} |
| 5594 | + |
| 5580 | 5595 | #ifdef CONFIG_SMP |
| 5581 | 5596 | static int sched_idle_cpu(int cpu) |
| 5582 | 5597 | { |
| @@ -11575,7 +11590,7 @@ int sched_group_set_idle(struct task_group *tg, long idle) · 5992 unmodified lines |
| 11575 | 11590 | for_each_possible_cpu(i) { |
| 11576 | 11591 | struct rq *rq = cpu_rq(i); |
| 11577 | 11592 | struct sched_entity *se = tg->se[i]; |
| 11578 | | − struct cfs_rq *grp_cfs_rq = tg->cfs_rq[i]; |
| 11593 | + struct cfs_rq *parent_cfs_rq, *grp_cfs_rq = tg->cfs_rq[i]; |
| 11579 | 11594 | bool was_idle = cfs_rq_is_idle(grp_cfs_rq); |
| 11580 | 11595 | long idle_task_delta; |
| 11581 | 11596 | struct rq_flags rf; |
| @@ -11586,6 +11601,14 @@ int sched_group_set_idle(struct task_group *tg, long idle) · 4 unmodified lines |
| 11586 | 11601 | if (WARN_ON_ONCE(was_idle == cfs_rq_is_idle(grp_cfs_rq))) |
| 11587 | 11602 | goto next_cpu; |
| 11588 | 11603 | |
| 11604 | + if (se->on_rq) { |
| 11605 | + parent_cfs_rq = cfs_rq_of(se); |
| 11606 | + if (cfs_rq_is_idle(grp_cfs_rq)) |
| 11607 | + parent_cfs_rq->idle_nr_running++; |
| 11608 | + else |
| 11609 | + parent_cfs_rq->idle_nr_running--; |
| 11610 | + } |
| 11611 | + |
| 11589 | 11612 | idle_task_delta = grp_cfs_rq->h_nr_running - |
| 11590 | 11613 | grp_cfs_rq->idle_h_nr_running; |
| 11591 | 11614 | if (!cfs_rq_is_idle(grp_cfs_rq)) |