Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'pmdomain-v6.16-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm

Pull pmdomain / cpuidle-psci fixes from Ulf Hansson:
"pmdomain core:

- Respect CPU latency QoS limit in the genpd governor for CPUs

cpuidle-psci:

- Fix cpuhotplug support for PREEMPT_RT"

* tag 'pmdomain-v6.16-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm:
cpuidle: psci: Fix cpuhotplug routine with PREEMPT_RT=y
pmdomain: governor: Consider CPU latency tolerance from pm_domain_cpu_gov

+28 -13
+12 -11
drivers/cpuidle/cpuidle-psci.c
··· 45 45 static DEFINE_PER_CPU_READ_MOSTLY(struct psci_cpuidle_data, psci_cpuidle_data); 46 46 static DEFINE_PER_CPU(struct psci_cpuidle_domain_state, psci_domain_state); 47 47 static bool psci_cpuidle_use_syscore; 48 - static bool psci_cpuidle_use_cpuhp; 49 48 50 49 void psci_set_domain_state(struct generic_pm_domain *pd, unsigned int state_idx, 51 50 u32 state) ··· 123 124 { 124 125 struct device *pd_dev = __this_cpu_read(psci_cpuidle_data.dev); 125 126 126 - if (pd_dev) 127 - pm_runtime_get_sync(pd_dev); 127 + if (pd_dev) { 128 + if (!IS_ENABLED(CONFIG_PREEMPT_RT)) 129 + pm_runtime_get_sync(pd_dev); 130 + else 131 + dev_pm_genpd_resume(pd_dev); 132 + } 128 133 129 134 return 0; 130 135 } ··· 138 135 struct device *pd_dev = __this_cpu_read(psci_cpuidle_data.dev); 139 136 140 137 if (pd_dev) { 141 - pm_runtime_put_sync(pd_dev); 138 + if (!IS_ENABLED(CONFIG_PREEMPT_RT)) 139 + pm_runtime_put_sync(pd_dev); 140 + else 141 + dev_pm_genpd_suspend(pd_dev); 142 + 142 143 /* Clear domain state to start fresh at next online. */ 143 144 psci_clear_domain_state(); 144 145 } ··· 202 195 static void psci_idle_init_cpuhp(void) 203 196 { 204 197 int err; 205 - 206 - if (!psci_cpuidle_use_cpuhp) 207 - return; 208 198 209 199 err = cpuhp_setup_state_nocalls(CPUHP_AP_CPU_PM_STARTING, 210 200 "cpuidle/psci:online", ··· 263 259 * s2ram and s2idle. 264 260 */ 265 261 drv->states[state_count - 1].enter_s2idle = psci_enter_s2idle_domain_idle_state; 266 - if (!IS_ENABLED(CONFIG_PREEMPT_RT)) { 262 + if (!IS_ENABLED(CONFIG_PREEMPT_RT)) 267 263 drv->states[state_count - 1].enter = psci_enter_domain_idle_state; 268 - psci_cpuidle_use_cpuhp = true; 269 - } 270 264 271 265 return 0; 272 266 } ··· 341 339 342 340 dt_idle_detach_cpu(data->dev); 343 341 psci_cpuidle_use_syscore = false; 344 - psci_cpuidle_use_cpuhp = false; 345 342 } 346 343 347 344 static int psci_idle_init_cpu(struct device *dev, int cpu)
+16 -2
drivers/pmdomain/governor.c
··· 8 8 #include <linux/pm_domain.h> 9 9 #include <linux/pm_qos.h> 10 10 #include <linux/hrtimer.h> 11 + #include <linux/cpu.h> 11 12 #include <linux/cpuidle.h> 12 13 #include <linux/cpumask.h> 13 14 #include <linux/ktime.h> ··· 350 349 struct cpuidle_device *dev; 351 350 ktime_t domain_wakeup, next_hrtimer; 352 351 ktime_t now = ktime_get(); 352 + struct device *cpu_dev; 353 + s64 cpu_constraint, global_constraint; 353 354 s64 idle_duration_ns; 354 355 int cpu, i; 355 356 ··· 362 359 if (!(genpd->flags & GENPD_FLAG_CPU_DOMAIN)) 363 360 return true; 364 361 362 + global_constraint = cpu_latency_qos_limit(); 365 363 /* 366 364 * Find the next wakeup for any of the online CPUs within the PM domain 367 365 * and its subdomains. Note, we only need the genpd->cpus, as it already ··· 376 372 if (ktime_before(next_hrtimer, domain_wakeup)) 377 373 domain_wakeup = next_hrtimer; 378 374 } 375 + 376 + cpu_dev = get_cpu_device(cpu); 377 + if (cpu_dev) { 378 + cpu_constraint = dev_pm_qos_raw_resume_latency(cpu_dev); 379 + if (cpu_constraint < global_constraint) 380 + global_constraint = cpu_constraint; 381 + } 379 382 } 380 383 384 + global_constraint *= NSEC_PER_USEC; 381 385 /* The minimum idle duration is from now - until the next wakeup. */ 382 386 idle_duration_ns = ktime_to_ns(ktime_sub(domain_wakeup, now)); 383 387 if (idle_duration_ns <= 0) ··· 401 389 */ 402 390 i = genpd->state_idx; 403 391 do { 404 - if (idle_duration_ns >= (genpd->states[i].residency_ns + 405 - genpd->states[i].power_off_latency_ns)) { 392 + if ((idle_duration_ns >= (genpd->states[i].residency_ns + 393 + genpd->states[i].power_off_latency_ns)) && 394 + (global_constraint >= (genpd->states[i].power_on_latency_ns + 395 + genpd->states[i].power_off_latency_ns))) { 406 396 genpd->state_idx = i; 407 397 genpd->gd->last_enter = now; 408 398 genpd->gd->reflect_residency = true;