Adds cfs_rq->idle_nr_running, which accounts the number of idle entities directly enqueued on the cfs_rq.
Showing the changes to kernel (3 of 3 files). Show all
Unified · Split
| @@ -614,6 +614,8 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) · 613 unmodified lines | ||
| 614 | 614 | cfs_rq->nr_spread_over); |
| 615 | 615 | SEQ_printf(m, " .%-30s: %d\n", "nr_running", cfs_rq->nr_running); |
| 616 | 616 | SEQ_printf(m, " .%-30s: %d\n", "h_nr_running", cfs_rq->h_nr_running); |
| 617 | + SEQ_printf(m, " .%-30s: %d\n", "idle_nr_running", | |
| 618 | + cfs_rq->idle_nr_running); | |
| 617 | 619 | SEQ_printf(m, " .%-30s: %d\n", "idle_h_nr_running", |
| 618 | 620 | cfs_rq->idle_h_nr_running); |
| 619 | 621 | SEQ_printf(m, " .%-30s: %ld\n", "load", cfs_rq->load.weight); |
| @@ -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)) |
| @@ -530,6 +530,7 @@ struct cfs_rq { · 529 unmodified lines | ||
| 530 | 530 | struct load_weight load; |
| 531 | 531 | unsigned int nr_running; |
| 532 | 532 | unsigned int h_nr_running; /* SCHED_{NORMAL,BATCH,IDLE} */ |
| 533 | + unsigned int idle_nr_running; /* SCHED_IDLE */ | |
| 533 | 534 | unsigned int idle_h_nr_running; /* SCHED_IDLE */ |
| 534 | 535 | |
| 535 | 536 | u64 exec_clock; |