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