Merge "sched: walt: take runnable into account for placement descision"

This commit is contained in:
qctecmdr
2022-02-19 00:04:40 -08:00
committed by Gerrit - the friendly Code Review server
2 changed files with 39 additions and 13 deletions

View File

@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#undef TRACE_SYSTEM #undef TRACE_SYSTEM
@@ -1091,11 +1092,13 @@ TRACE_EVENT(sched_find_best_target,
unsigned long candidates, unsigned long candidates,
int most_spare_cap, int most_spare_cap,
int order_index, int end_index, int order_index, int end_index,
int skip, bool running), int skip, bool running,
int most_spare_rq_cpu, unsigned int cpu_rq_runnable_cnt),
TP_ARGS(tsk, min_util, start_cpu, candidates, TP_ARGS(tsk, min_util, start_cpu, candidates,
most_spare_cap, most_spare_cap,
order_index, end_index, skip, running), order_index, end_index, skip, running,
most_spare_rq_cpu, cpu_rq_runnable_cnt),
TP_STRUCT__entry( TP_STRUCT__entry(
__array(char, comm, TASK_COMM_LEN) __array(char, comm, TASK_COMM_LEN)
@@ -1108,6 +1111,8 @@ TRACE_EVENT(sched_find_best_target,
__field(int, end_index) __field(int, end_index)
__field(int, skip) __field(int, skip)
__field(bool, running) __field(bool, running)
__field(int, most_spare_rq_cpu)
__field(unsigned int, cpu_rq_runnable_cnt)
), ),
TP_fast_assign( TP_fast_assign(
@@ -1121,9 +1126,11 @@ TRACE_EVENT(sched_find_best_target,
__entry->end_index = end_index; __entry->end_index = end_index;
__entry->skip = skip; __entry->skip = skip;
__entry->running = running; __entry->running = running;
__entry->most_spare_rq_cpu = most_spare_rq_cpu;
__entry->cpu_rq_runnable_cnt = cpu_rq_runnable_cnt;
), ),
TP_printk("pid=%d comm=%s start_cpu=%d candidates=%#lx most_spare_cap=%d order_index=%d end_index=%d skip=%d running=%d", TP_printk("pid=%d comm=%s start_cpu=%d candidates=%#lx most_spare_cap=%d order_index=%d end_index=%d skip=%d running=%d min_util=%lu spare_rq_cpu=%d min_runnable=%u",
__entry->pid, __entry->comm, __entry->pid, __entry->comm,
__entry->start_cpu, __entry->start_cpu,
__entry->candidates, __entry->candidates,
@@ -1131,7 +1138,10 @@ TRACE_EVENT(sched_find_best_target,
__entry->order_index, __entry->order_index,
__entry->end_index, __entry->end_index,
__entry->skip, __entry->skip,
__entry->running) __entry->running,
__entry->min_util,
__entry->most_spare_rq_cpu,
__entry->cpu_rq_runnable_cnt)
); );
TRACE_EVENT(sched_enq_deq_task, TRACE_EVENT(sched_enq_deq_task,

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <trace/hooks/sched.h> #include <trace/hooks/sched.h>
@@ -227,6 +228,8 @@ static inline bool is_complex_sibling_idle(int cpu)
} }
static inline int walt_get_mvp_task_prio(struct task_struct *p); static inline int walt_get_mvp_task_prio(struct task_struct *p);
#define DIRE_STRAITS_PREV_NR_LIMIT 10
static void walt_find_best_target(struct sched_domain *sd, static void walt_find_best_target(struct sched_domain *sd,
cpumask_t *candidates, cpumask_t *candidates,
struct task_struct *p, struct task_struct *p,
@@ -239,8 +242,9 @@ static void walt_find_best_target(struct sched_domain *sd,
int i, start_cpu; int i, start_cpu;
long spare_wake_cap, most_spare_wake_cap = 0; long spare_wake_cap, most_spare_wake_cap = 0;
int most_spare_cap_cpu = -1; int most_spare_cap_cpu = -1;
int least_nr_cpu = -1;
unsigned int cpu_rq_runnable_cnt = UINT_MAX;
int prev_cpu = task_cpu(p); int prev_cpu = task_cpu(p);
int active_candidate = -1;
int order_index = fbt_env->order_index, end_index = fbt_env->end_index; int order_index = fbt_env->order_index, end_index = fbt_env->end_index;
int stop_index = INT_MAX; int stop_index = INT_MAX;
int cluster; int cluster;
@@ -305,9 +309,6 @@ static void walt_find_best_target(struct sched_domain *sd,
if (!cpu_active(i)) if (!cpu_active(i))
continue; continue;
if (active_candidate == -1)
active_candidate = i;
/* /*
* This CPU is the target of an active migration that's * This CPU is the target of an active migration that's
* yet to complete. Avoid placing another task on it. * yet to complete. Avoid placing another task on it.
@@ -340,6 +341,16 @@ static void walt_find_best_target(struct sched_domain *sd,
most_spare_cap_cpu = i; most_spare_cap_cpu = i;
} }
/*
* Keep track of runnables for each CPU, if none of the
* CPUs have spare capacity then use CPU with less
* number of runnables.
*/
if (cpu_rq(i)->nr_running < cpu_rq_runnable_cnt) {
cpu_rq_runnable_cnt = cpu_rq(i)->nr_running;
least_nr_cpu = i;
}
/* /*
* Ensure minimum capacity to grant the required boost. * Ensure minimum capacity to grant the required boost.
* The target CPU can be already at a capacity level higher * The target CPU can be already at a capacity level higher
@@ -451,21 +462,26 @@ static void walt_find_best_target(struct sched_domain *sd,
* We have set idle or target as long as they are valid CPUs. * We have set idle or target as long as they are valid CPUs.
* If we don't find either, then we fallback to most_spare_cap, * If we don't find either, then we fallback to most_spare_cap,
* If we don't find most spare cap, we fallback to prev_cpu, * If we don't find most spare cap, we fallback to prev_cpu,
* provided that the prev_cpu is active. * provided that the prev_cpu is active and has less than
* If the prev_cpu is not active, we fallback to active_candidate. * DIRE_STRAITS_PREV_NR_LIMIT runnables otherwise, we fallback to cpu
* with least number of runnables.
*/ */
if (unlikely(cpumask_empty(candidates))) { if (unlikely(cpumask_empty(candidates))) {
if (most_spare_cap_cpu != -1) if (most_spare_cap_cpu != -1)
cpumask_set_cpu(most_spare_cap_cpu, candidates); cpumask_set_cpu(most_spare_cap_cpu, candidates);
else if (!cpu_active(prev_cpu) && active_candidate != -1) else if (cpu_active(prev_cpu)
cpumask_set_cpu(active_candidate, candidates); && (cpu_rq(prev_cpu)->nr_running < DIRE_STRAITS_PREV_NR_LIMIT))
cpumask_set_cpu(prev_cpu, candidates);
else if (least_nr_cpu != -1)
cpumask_set_cpu(least_nr_cpu, candidates);
} }
out: out:
trace_sched_find_best_target(p, min_task_util, start_cpu, cpumask_bits(candidates)[0], trace_sched_find_best_target(p, min_task_util, start_cpu, cpumask_bits(candidates)[0],
most_spare_cap_cpu, order_index, end_index, most_spare_cap_cpu, order_index, end_index,
fbt_env->skip_cpu, task_on_rq_queued(p)); fbt_env->skip_cpu, task_on_rq_queued(p), least_nr_cpu,
cpu_rq_runnable_cnt);
} }
static inline unsigned long static inline unsigned long