diff options
Diffstat (limited to 'kernel/sched/hmp.c')
| -rw-r--r-- | kernel/sched/hmp.c | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/kernel/sched/hmp.c b/kernel/sched/hmp.c index a3d454f987ef..ae6876e62c0f 100644 --- a/kernel/sched/hmp.c +++ b/kernel/sched/hmp.c @@ -1602,7 +1602,7 @@ unsigned int nr_eligible_big_tasks(int cpu) int nr_big = rq->hmp_stats.nr_big_tasks; int nr = rq->nr_running; - if (cpu_max_possible_capacity(cpu) != max_possible_capacity) + if (!is_max_capacity_cpu(cpu)) return nr_big; return nr; @@ -2611,7 +2611,8 @@ update_task_rq_cpu_cycles(struct task_struct *p, struct rq *rq, int event, trace_sched_get_task_cpu_cycles(cpu, event, rq->cc.cycles, rq->cc.time); } -static int account_busy_for_task_demand(struct task_struct *p, int event) +static int +account_busy_for_task_demand(struct rq *rq, struct task_struct *p, int event) { /* * No need to bother updating task demand for exiting tasks @@ -2630,6 +2631,17 @@ static int account_busy_for_task_demand(struct task_struct *p, int event) (event == PICK_NEXT_TASK || event == TASK_MIGRATE))) return 0; + /* + * TASK_UPDATE can be called on sleeping task, when its moved between + * related groups + */ + if (event == TASK_UPDATE) { + if (rq->curr == p) + return 1; + + return p->on_rq ? SCHED_ACCOUNT_WAIT_TIME : 0; + } + return 1; } @@ -2770,7 +2782,7 @@ static u64 update_task_demand(struct task_struct *p, struct rq *rq, u64 runtime; new_window = mark_start < window_start; - if (!account_busy_for_task_demand(p, event)) { + if (!account_busy_for_task_demand(rq, p, event)) { if (new_window) /* * If the time accounted isn't being accounted as @@ -4335,8 +4347,20 @@ void note_task_waking(struct task_struct *p, u64 wallclock) { u64 sleep_time = wallclock - p->last_switch_out_ts; - p->last_wake_ts = wallclock; + /* + * When a short burst and short sleeping task goes for a long + * sleep, the task's avg_sleep_time gets boosted. It will not + * come below short_sleep threshold for a lot of time and it + * results in incorrect packing. The idead behind tracking + * avg_sleep_time is to detect if a task is short sleeping + * or not. So limit the sleep time to twice the short sleep + * threshold. For regular long sleeping tasks, the avg_sleep_time + * would be higher than threshold, and packing happens correctly. + */ + sleep_time = min_t(u64, sleep_time, 2 * sysctl_sched_short_sleep); update_avg(&p->ravg.avg_sleep_time, sleep_time); + + p->last_wake_ts = wallclock; } #ifdef CONFIG_CGROUP_SCHED |
