sched: walt: fix SMART_FMAX threshold based capping logic
One of the condition to remove/apply SMART_FMAX frequency capping is based on utilization of the CPU, if CPU is busy beyond 90% at the capped frequency then frequency capping is removed and re-applied whenever CPU utilization falls below 90%(after hysteresis of 1 sec). Current logic checks CPU busy time based on the current frequency and this results in a cycle of capping and uncapping. For Example: If the capping frequency is 2.8GHz and cluster's max frequency is 3.1GHz, once capping is applied CPU busy time is compared with util@2.8GHz, while once capping is removed CPU busy time is compared with util@3.1GHz, thus if system's requirement is 2.75GHz then there will be a continuous cycle of capping and uncapping. Fix this by always comparing CPU busy time against the capping frequency. While at it, remove "update_smart_fmax_capacity" function as it is no longer used. Change-Id: Iefaff1037339477396bd238a01c273af4c7706e6 Signed-off-by: Ashay Jaiswal <quic_ashayj@quicinc.com>
This commit is contained in:
parent
dd70fdd247
commit
073ad6710f
3 changed files with 14 additions and 22 deletions
|
|
@ -2551,7 +2551,6 @@ static struct walt_sched_cluster init_cluster = {
|
|||
.max_possible_freq = 1,
|
||||
.aggr_grp_load = 0,
|
||||
.found_ts = 0,
|
||||
.smart_fmax_cap = 1,
|
||||
};
|
||||
|
||||
static void init_clusters(void)
|
||||
|
|
@ -2593,7 +2592,6 @@ static struct walt_sched_cluster *alloc_new_cluster(const struct cpumask *cpus)
|
|||
raw_spin_lock_init(&cluster->load_lock);
|
||||
cluster->cpus = *cpus;
|
||||
cluster->found_ts = 0;
|
||||
cluster->smart_fmax_cap = 1;
|
||||
|
||||
return cluster;
|
||||
}
|
||||
|
|
@ -4567,7 +4565,7 @@ void walt_rotation_checkpoint(int nr_big)
|
|||
fmax_cap[HIGH_PERF_CAP][i] = FREQ_QOS_MAX_DEFAULT_VALUE;
|
||||
}
|
||||
|
||||
update_fmax_cap_capacities(HIGH_PERF_CAP);
|
||||
update_fmax_cap_capacities();
|
||||
}
|
||||
|
||||
#define WAKEUP_CTR_THRESH 50
|
||||
|
|
@ -4582,17 +4580,23 @@ bool thres_based_uncap(u64 window_start)
|
|||
|
||||
for (i = 0; i < num_sched_clusters; i++) {
|
||||
bool cluster_high_load = false;
|
||||
unsigned long fmax_capacity, tgt_cap;
|
||||
|
||||
cluster = sched_cluster[i];
|
||||
fmax_capacity = arch_scale_cpu_capacity(cpumask_first(&cluster->cpus));
|
||||
tgt_cap = mult_frac(fmax_capacity, sysctl_fmax_cap[cluster->id],
|
||||
cluster->max_possible_freq);
|
||||
|
||||
for_each_cpu(cpu, &cluster->cpus) {
|
||||
wrq = &per_cpu(walt_rq, cpu);
|
||||
if (wrq->util >= mult_frac(UTIL_THRES, cluster->smart_fmax_cap, 100)) {
|
||||
if (wrq->util >= mult_frac(tgt_cap, UTIL_THRES, 100)) {
|
||||
cluster_high_load = true;
|
||||
if (!cluster->found_ts)
|
||||
cluster->found_ts = window_start;
|
||||
else if ((window_start - cluster->found_ts) >= UNCAP_THRES)
|
||||
return true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!cluster_high_load)
|
||||
|
|
@ -4632,7 +4636,7 @@ void fmax_uncap_checkpoint(int nr_big, u64 window_start, u32 wakeup_ctr_sum)
|
|||
}
|
||||
}
|
||||
|
||||
update_fmax_cap_capacities(SMART_FMAX_CAP);
|
||||
update_fmax_cap_capacities();
|
||||
|
||||
trace_sched_fmax_uncap(nr_big, window_start, wakeup_ctr_sum,
|
||||
fmax_uncap_load_detected, fmax_uncap_timestamp);
|
||||
|
|
@ -4669,7 +4673,7 @@ void update_freq_relation(struct walt_sched_cluster *cluster)
|
|||
fmax_cap[FREQ_REL_CAP][cluster_id] = FREQ_QOS_MAX_DEFAULT_VALUE;
|
||||
|
||||
if (prev_cap != fmax_cap[FREQ_REL_CAP][cluster_id])
|
||||
update_fmax_cap_capacities(FREQ_REL_CAP);
|
||||
update_fmax_cap_capacities();
|
||||
}
|
||||
|
||||
void walt_fill_ta_data(struct core_ctl_notif_data *data)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _WALT_H
|
||||
|
|
@ -173,7 +173,6 @@ struct walt_sched_cluster {
|
|||
u64 aggr_grp_load;
|
||||
unsigned long util_to_cost[1024];
|
||||
u64 found_ts;
|
||||
unsigned int smart_fmax_cap;
|
||||
};
|
||||
|
||||
struct freq_relation_map {
|
||||
|
|
@ -1152,24 +1151,13 @@ static inline bool has_internal_freq_limit_changed(struct walt_sched_cluster *cl
|
|||
return cluster->walt_internal_freq_limit != internal_freq;
|
||||
}
|
||||
|
||||
static inline void update_smart_fmax_capacity(struct walt_sched_cluster *cluster)
|
||||
{
|
||||
unsigned long fmax_capacity = arch_scale_cpu_capacity(cpumask_first(&cluster->cpus));
|
||||
|
||||
cluster->smart_fmax_cap = mult_frac(fmax_capacity,
|
||||
fmax_cap[SMART_FMAX_CAP][cluster->id],
|
||||
cluster->max_possible_freq);
|
||||
}
|
||||
|
||||
static inline void update_fmax_cap_capacities(int type)
|
||||
static inline void update_fmax_cap_capacities(void)
|
||||
{
|
||||
struct walt_sched_cluster *cluster;
|
||||
int cpu;
|
||||
|
||||
for_each_sched_cluster(cluster) {
|
||||
if (has_internal_freq_limit_changed(cluster)) {
|
||||
if (type == SMART_FMAX_CAP)
|
||||
update_smart_fmax_capacity(cluster);
|
||||
for_each_cpu(cpu, &cluster->cpus)
|
||||
update_cpu_capacity_helper(cpu);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/cpumask.h>
|
||||
|
|
@ -288,7 +288,7 @@ void restrict_cpus_and_freq(struct cpumask *cpus)
|
|||
}
|
||||
}
|
||||
|
||||
update_fmax_cap_capacities(PARTIAL_HALT_CAP);
|
||||
update_fmax_cap_capacities();
|
||||
}
|
||||
|
||||
struct task_struct *walt_drain_thread;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue