[RFC PATCH] cpufreq: qcom-cpufreq-hw: allow work to be done on other CPU for PREEMPT_RT
From: Krzysztof Kozlowski
Date: Wed Mar 15 2023 - 12:49:25 EST
Qualcomm cpufreq driver configures interrupts with affinity to each
cluster, e.g. dcvsh-irq-0, dcvsh-irq-4 and dcvsh-irq-7 on SM8250.
Triggered interrupt will schedule delayed work, but, since workqueue
prefers local CPUs, it might get executed on a CPU dedicated to realtime
tasks causing unexpected latencies in realtime workload.
Use unbound workqueue for such case. This might come with performance
or energy penalty, e.g. because of cache miss or when other CPU is
sleeping.
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@xxxxxxxxxx>
---
drivers/cpufreq/qcom-cpufreq-hw.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
index 2f581d2d617d..c5ff8d25fabb 100644
--- a/drivers/cpufreq/qcom-cpufreq-hw.c
+++ b/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -390,7 +390,16 @@ static irqreturn_t qcom_lmh_dcvs_handle_irq(int irq, void *data)
/* Disable interrupt and enable polling */
disable_irq_nosync(c_data->throttle_irq);
- schedule_delayed_work(&c_data->throttle_work, 0);
+
+ /*
+ * Workqueue prefers local CPUs and since interrupts have set affinity,
+ * the work might execute on a CPU dedicated to realtime tasks.
+ */
+ if (IS_ENABLED(CONFIG_PREEMPT_RT))
+ queue_delayed_work_on(WORK_CPU_UNBOUND, system_unbound_wq,
+ &c_data->throttle_work, 0);
+ else
+ schedule_delayed_work(&c_data->throttle_work, 0);
if (qcom_cpufreq.soc_data->reg_intr_clr)
writel_relaxed(GT_IRQ_STATUS,
--
2.34.1