scx_lavd: dynamically decide autopilot's low watermark

A single threshold for a low watermark does not work well across systems
with various numbers of cores and core types. Instead of using a single
low watermark value, we dynamically decide the low watermark: 1) until
one little core is fully utilized or 2) until two big cores are fully
utilized. This works better across systems.

Signed-off-by: Changwoo Min <changwoo@igalia.com>
This commit is contained in:
Changwoo Min 2024-08-31 22:58:44 +09:00
parent 4a7b806dd2
commit 5ca4501139
2 changed files with 29 additions and 7 deletions

View File

@ -80,18 +80,17 @@ enum consts {
LAVD_PREEMPT_KICK_MARGIN = (1ULL * NSEC_PER_MSEC), LAVD_PREEMPT_KICK_MARGIN = (1ULL * NSEC_PER_MSEC),
LAVD_PREEMPT_TICK_MARGIN = (100ULL * NSEC_PER_USEC), LAVD_PREEMPT_TICK_MARGIN = (100ULL * NSEC_PER_USEC),
LAVD_SYS_STAT_INTERVAL_NS = (25ULL * NSEC_PER_MSEC), LAVD_SYS_STAT_INTERVAL_NS = (50ULL * NSEC_PER_MSEC),
LAVD_CC_PER_CORE_MAX_CTUIL = 500, /* maximum per-core CPU utilization */ LAVD_CC_PER_CORE_MAX_CTUIL = 500, /* maximum per-core CPU utilization */
LAVD_CC_PER_TURBO_CORE_MAX_CTUIL = 750, /* maximum per-core CPU utilization for a turbo core */ LAVD_CC_PER_TURBO_CORE_MAX_CTUIL = 750, /* maximum per-core CPU utilization for a turbo core */
LAVD_CC_NR_ACTIVE_MIN = 1, /* num of mininum active cores */ LAVD_CC_NR_ACTIVE_MIN = 1, /* num of mininum active cores */
LAVD_CC_NR_OVRFLW = 1, /* num of overflow cores */ LAVD_CC_NR_OVRFLW = 1, /* num of overflow cores */
LAVD_CC_CPU_PIN_INTERVAL = (3ULL * LAVD_TIME_ONE_SEC), LAVD_CC_CPU_PIN_INTERVAL = (2ULL * LAVD_TIME_ONE_SEC),
LAVD_CC_CPU_PIN_INTERVAL_DIV = (LAVD_CC_CPU_PIN_INTERVAL / LAVD_CC_CPU_PIN_INTERVAL_DIV = (LAVD_CC_CPU_PIN_INTERVAL /
LAVD_SYS_STAT_INTERVAL_NS), LAVD_SYS_STAT_INTERVAL_NS),
LAVD_AP_LOW_UTIL = 50, /* powersave mode when cpu util <= 5% */ LAVD_AP_HIGH_UTIL = 700, /* balanced mode when 10% < cpu util <= 40%,
LAVD_AP_HIGH_UTIL = 300, /* balanced mode when 5% < cpu util <= 30%, performance mode when cpu util > 40% */
performance mode when cpu util > 30% */
LAVD_CPDOM_MAX_NR = 32, /* maximum number of compute domain */ LAVD_CPDOM_MAX_NR = 32, /* maximum number of compute domain */
LAVD_CPDOM_MAX_DIST = 4, /* maximum distance from one compute domain to another */ LAVD_CPDOM_MAX_DIST = 4, /* maximum distance from one compute domain to another */

View File

@ -207,6 +207,8 @@ private(LAVD) struct bpf_cpumask __kptr *active_cpumask; /* CPU mask for active
private(LAVD) struct bpf_cpumask __kptr *ovrflw_cpumask; /* CPU mask for overflow CPUs */ private(LAVD) struct bpf_cpumask __kptr *ovrflw_cpumask; /* CPU mask for overflow CPUs */
private(LAVD) struct bpf_cpumask cpdom_cpumask[LAVD_CPDOM_MAX_NR]; /* CPU mask for each compute domain */ private(LAVD) struct bpf_cpumask cpdom_cpumask[LAVD_CPDOM_MAX_NR]; /* CPU mask for each compute domain */
static u64 LAVD_AP_LOW_UTIL;
/* /*
* CPU topology * CPU topology
*/ */
@ -1517,7 +1519,6 @@ static s32 pick_idle_cpu(struct task_struct *p, struct task_ctx *taskc,
* Pick an idle core among turbo boost-enabled CPUs with a matching * Pick an idle core among turbo boost-enabled CPUs with a matching
* core type. * core type.
*/ */
start_turbo_mask:
if (no_prefer_turbo_core || !turbo_cpumask) if (no_prefer_turbo_core || !turbo_cpumask)
goto start_llc_mask; goto start_llc_mask;
@ -1559,7 +1560,6 @@ start_tmask:
/* /*
* Pick a idle core among active CPUs. * Pick a idle core among active CPUs.
*/ */
start_amask:
cpu_id = pick_idle_cpu_in(a_cpumask); cpu_id = pick_idle_cpu_in(a_cpumask);
if (cpu_id >= 0) { if (cpu_id >= 0) {
*is_idle = true; *is_idle = true;
@ -3171,6 +3171,24 @@ static s32 init_sys_stat(u64 now)
return 0; return 0;
} }
static void init_autopilot_low_util(void)
{
if (nr_cpus_big < nr_cpus_onln) {
/*
* When there are little cores, we move up to the balanced mode
* if one little core is fully utilized.
*/
LAVD_AP_LOW_UTIL = 1000 / nr_cpus_onln;
}
else {
/*
* When there are only big cores, we move up to the balanced
* mode if two big cores are fully utilized.
*/
LAVD_AP_LOW_UTIL = (2 * 1000) / nr_cpus_onln;
}
}
s32 BPF_STRUCT_OPS_SLEEPABLE(lavd_init) s32 BPF_STRUCT_OPS_SLEEPABLE(lavd_init)
{ {
u64 now = bpf_ktime_get_ns(); u64 now = bpf_ktime_get_ns();
@ -3208,6 +3226,11 @@ s32 BPF_STRUCT_OPS_SLEEPABLE(lavd_init)
if (err) if (err)
return err; return err;
/*
* Initialize the low cpu watermark for autopilot mode.
*/
init_autopilot_low_util();
/* /*
* Initilize the current logical clock and service time. * Initilize the current logical clock and service time.
*/ */