diff options
author | Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> | 2023-01-25 12:34:18 +0100 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2023-02-13 17:15:42 +0100 |
commit | f9901f64536c39f699e6ed228c5e64e7e7ce8708 (patch) | |
tree | 9235f2f0f8b6d839cffc3250ab44ea5a26e0770a /drivers/cpuidle/cpuidle-psci.c | |
parent | 41204a607679ccca7eabff9f2871b969d6ef2ce3 (diff) | |
download | lwn-f9901f64536c39f699e6ed228c5e64e7e7ce8708.tar.gz lwn-f9901f64536c39f699e6ed228c5e64e7e7ce8708.zip |
cpuidle: psci: Do not suspend topology CPUs on PREEMPT_RT
The runtime Power Management of CPU topology is not compatible with
PREEMPT_RT:
1. Core cpuidle path disables IRQs.
2. Core cpuidle calls cpuidle-psci.
3. cpuidle-psci in __psci_enter_domain_idle_state() calls
pm_runtime_put_sync_suspend() and pm_runtime_get_sync() which use
spinlocks (which are sleeping on PREEMPT_RT).
Deep sleep modes are not a priority of Realtime kernels because the
latencies might become unpredictable. On the other hand the PSCI CPU
idle power domain is a parent of other devices and power domain
controllers, thus it cannot be simply skipped (e.g. on Qualcomm SM8250).
Disable the idle callbacks in cpuidle-psci and mark the domain as
always on. This is a trade-off between making PREEMPT_RT working and
still having a proper power domain hierarchy in the system.
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Adrien Thierry <athierry@redhat.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpuidle/cpuidle-psci.c')
-rw-r--r-- | drivers/cpuidle/cpuidle-psci.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/cpuidle/cpuidle-psci.c b/drivers/cpuidle/cpuidle-psci.c index 57bc3e3ae391..68467a325dcb 100644 --- a/drivers/cpuidle/cpuidle-psci.c +++ b/drivers/cpuidle/cpuidle-psci.c @@ -231,6 +231,9 @@ static int psci_dt_cpu_init_topology(struct cpuidle_driver *drv, if (!psci_has_osi_support()) return 0; + if (IS_ENABLED(CONFIG_PREEMPT_RT)) + return 0; + data->dev = psci_dt_attach_cpu(cpu); if (IS_ERR_OR_NULL(data->dev)) return PTR_ERR_OR_ZERO(data->dev); |