From 06bad29583b8418222117adadcfc0bcd097a3744 Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Fri, 8 Nov 2019 00:15:38 -0800 Subject: [PATCH] drivers: arch_topology: wire up thermal limit for arch_scale_max_freq_capacity before patch and "echo 50000 > /sys/class/thermal/tz-by-name/sdm-therm/emul_temp" com.android.uibench.janktests.UiBenchJankTests#testInvalidateTree: PASSED (02m6.247s) gfx-avg-slow-ui-thread: 0.07110321338664297 gfx-avg-missed-vsync: 0.0 gfx-avg-high-input-latency: 74.25140826299423 gfx-max-frame-time-50: 12 gfx-min-total-frames: 2250 gfx-avg-frame-time-99: 11.8 gfx-avg-num-frame-deadline-missed: 1.6 gfx-avg-frame-time-50: 9.6 gfx-max-high-input-latency: 99.86666666666667 gfx-avg-frame-time-90: 11.0 gfx-avg-frame-time-95: 11.0 gfx-max-frame-time-95: 13 gfx-max-frame-time-90: 13 gfx-max-slow-draw: 0.0 gfx-max-frame-time-99: 13 gfx-avg-slow-draw: 0.0 gfx-max-total-frames: 2251 gfx-avg-jank: 43.678000000000004 gfx-max-slow-bitmap-uploads: 0.0 gfx-max-missed-vsync: 0.0 gfx-avg-total-frames: 2250 gfx-max-jank: 96.67 gfx-max-slow-ui-thread: 0.13333333333333333 gfx-max-num-frame-deadline-missed: 3 gfx-avg-slow-bitmap-uploads: 0.0 aefore patch and "echo 50000 > /sys/class/thermal/tz-by-name/sdm-therm/emul_temp" google/perf/jank/UIBench/UIBench (1 Test) ---------------------------------------- [1/1] com.android.uibench.janktests.UiBenchJankTests#testInvalidateTree: PASSED (02m7.027s) gfx-avg-slow-ui-thread: 0.0 gfx-avg-missed-vsync: 0.0 gfx-avg-high-input-latency: 11.53777777777778 gfx-max-frame-time-50: 7 gfx-min-total-frames: 2250 gfx-avg-frame-time-99: 8.0 gfx-avg-num-frame-deadline-missed: 0.0 gfx-avg-frame-time-50: 7.0 gfx-max-high-input-latency: 41.15555555555556 gfx-avg-frame-time-90: 7.2 gfx-avg-frame-time-95: 7.8 gfx-max-frame-time-95: 8 gfx-max-frame-time-90: 8 gfx-max-slow-draw: 0.0 gfx-max-frame-time-99: 8 gfx-avg-slow-draw: 0.0 gfx-max-total-frames: 2250 gfx-avg-jank: 0.0 gfx-max-slow-bitmap-uploads: 0.0 gfx-max-missed-vsync: 0.0 gfx-avg-total-frames: 2250 gfx-max-jank: 0.0 gfx-max-slow-ui-thread: 0.0 gfx-max-num-frame-deadline-missed: 0 gfx-avg-slow-bitmap-uploads: 0.0 Bug: 143162654 Test: use emul_temp to change thermal condition and see capacity changed Change-Id: Idbf943f9c831c288db40d820682583ade3bbf05e Signed-off-by: Wei Wang Signed-off-by: Danny Lin --- drivers/base/arch_topology.c | 44 +++++++++++++++++++++++++++++ drivers/thermal/qcom/msm_lmh_dcvs.c | 1 + include/linux/arch_topology.h | 4 ++- include/linux/cpufreq.h | 3 +- 4 files changed, 50 insertions(+), 2 deletions(-) diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index b5f61f2840d0..cef7ebc9c05a 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -21,6 +21,50 @@ DEFINE_PER_CPU(unsigned long, freq_scale) = SCHED_CAPACITY_SCALE; DEFINE_PER_CPU(unsigned long, max_cpu_freq); DEFINE_PER_CPU(unsigned long, max_freq_scale) = SCHED_CAPACITY_SCALE; +/* + * Per-cpu for maximum available cap due to thermal events. + */ +DEFINE_PER_CPU(unsigned long, max_thermal_scale) = SCHED_CAPACITY_SCALE; + +/* + * Per-cpu for cached maximum available freq due to thermal events. + */ +static DEFINE_PER_CPU(unsigned long, max_cpu_thermal_freq); + +/* + * spin lock to update thermal freq cap. + */ +static DEFINE_SPINLOCK(max_thermal_freq_lock); + +void arch_set_max_thermal_scale(struct cpumask *cpus, + unsigned long max_thermal_freq) +{ + unsigned long flags, scale, max_freq, scale_freq; + int cpu = cpumask_first(cpus); + + if (cpu > nr_cpu_ids) + return; + + spin_lock_irqsave(&max_thermal_freq_lock, flags); + for_each_cpu(cpu, cpus) { + if (per_cpu(max_cpu_thermal_freq, cpu) != max_thermal_freq) { + max_freq = per_cpu(max_cpu_freq, cpu); + /* skip if cpuinfo max unknown */ + if (!max_freq) + continue; + /* cache thermal max raw freq */ + per_cpu(max_cpu_thermal_freq, cpu) = max_thermal_freq; + /* cap thermal max freq with cpuinfo max */ + scale_freq = min(max_thermal_freq, max_freq); + /* calc thermal max freq scale */ + scale = (scale_freq << SCHED_CAPACITY_SHIFT) / max_freq; + /* update thermal max freq scale */ + per_cpu(max_thermal_scale, cpu) = scale; + } + } + spin_unlock_irqrestore(&max_thermal_freq_lock, flags); +} + void arch_set_freq_scale(struct cpumask *cpus, unsigned long cur_freq, unsigned long max_freq) { diff --git a/drivers/thermal/qcom/msm_lmh_dcvs.c b/drivers/thermal/qcom/msm_lmh_dcvs.c index 835a53fb6425..96e091d2e389 100644 --- a/drivers/thermal/qcom/msm_lmh_dcvs.c +++ b/drivers/thermal/qcom/msm_lmh_dcvs.c @@ -182,6 +182,7 @@ static unsigned long limits_mitigation_notify(struct limits_dcvs_hw *hw) if (max_cpu_ct == cpumask_weight(&hw->core_map)) max_limit = max_cpu_limit; sched_update_cpu_freq_min_max(&hw->core_map, 0, max_limit); + arch_set_max_thermal_scale(&hw->core_map, max_limit); pr_debug("CPU:%d max limit:%lu\n", cpumask_first(&hw->core_map), max_limit); trace_lmh_dcvs_freq(cpumask_first(&hw->core_map), max_limit); diff --git a/include/linux/arch_topology.h b/include/linux/arch_topology.h index 7e5a33ea8df0..134798544bf5 100644 --- a/include/linux/arch_topology.h +++ b/include/linux/arch_topology.h @@ -34,11 +34,13 @@ unsigned long topology_get_freq_scale(int cpu) } DECLARE_PER_CPU(unsigned long, max_freq_scale); +DECLARE_PER_CPU(unsigned long, max_thermal_scale); static inline unsigned long topology_get_max_freq_scale(struct sched_domain *sd, int cpu) { - return per_cpu(max_freq_scale, cpu); + return min(per_cpu(max_freq_scale, cpu), + per_cpu(max_thermal_scale, cpu)); } #endif /* _LINUX_ARCH_TOPOLOGY_H_ */ diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 12cec9cd4dc0..52ba843aa4cf 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -947,7 +947,8 @@ extern void arch_set_freq_scale(struct cpumask *cpus, unsigned long cur_freq, unsigned long max_freq); extern void arch_set_max_freq_scale(struct cpumask *cpus, unsigned long policy_max_freq); - +extern void arch_set_max_thermal_scale(struct cpumask *cpus, + unsigned long max_thermal_freq); /* the following are really really optional */ extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs; extern struct freq_attr cpufreq_freq_attr_scaling_boost_freqs;