Skip to content

Commit bfbfbf7

Browse files
committed
Merge tag 'pm-5.2-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull more power management updates from Rafael Wysocki: "These fix a recent regression causing kernels built with CONFIG_PM unset to crash on systems that support the Performance and Energy Bias Hint (EPB), clean up the cpufreq core and some users of transition notifiers and introduce a new power domain flag into the generic power domains framework (genpd). Specifics: - Fix recent regression causing kernels built with CONFIG_PM unset to crash on systems that support the Performance and Energy Bias Hint (EPB) by avoiding to compile the EPB-related code depending on CONFIG_PM when it is unset (Rafael Wysocki). - Clean up the transition notifier invocation code in the cpufreq core and change some users of cpufreq transition notifiers accordingly (Viresh Kumar). - Change MAINTAINERS to cover the schedutil governor as part of cpufreq (Viresh Kumar). - Simplify cpufreq_init_policy() to avoid redundant computations (Yue Hu). - Add explanatory comment to the cpufreq core (Rafael Wysocki). - Introduce a new flag, GENPD_FLAG_RPM_ALWAYS_ON, to the generic power domains (genpd) framework along with the first user of it (Leonard Crestez)" * tag 'pm-5.2-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: soc: imx: gpc: Use GENPD_FLAG_RPM_ALWAYS_ON for ERR009619 PM / Domains: Add GENPD_FLAG_RPM_ALWAYS_ON flag cpufreq: Update MAINTAINERS to include schedutil governor cpufreq: Don't find governor for setpolicy drivers in cpufreq_init_policy() cpufreq: Explain the kobject_put() in cpufreq_policy_alloc() cpufreq: Call transition notifier only once for each policy x86: intel_epb: Take CONFIG_PM into account
2 parents 88f76bc + 2a8d69f commit bfbfbf7

File tree

11 files changed

+183
-105
lines changed

11 files changed

+183
-105
lines changed

MAINTAINERS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4133,7 +4133,9 @@ F: Documentation/admin-guide/pm/intel_pstate.rst
41334133
F: Documentation/cpu-freq/
41344134
F: Documentation/devicetree/bindings/cpufreq/
41354135
F: drivers/cpufreq/
4136+
F: kernel/sched/cpufreq*.c
41364137
F: include/linux/cpufreq.h
4138+
F: include/linux/sched/cpufreq.h
41374139
F: tools/testing/selftests/cpufreq/
41384140

41394141
CPU FREQUENCY DRIVERS - ARM BIG LITTLE

arch/arm/kernel/smp.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -758,15 +758,20 @@ static int cpufreq_callback(struct notifier_block *nb,
758758
unsigned long val, void *data)
759759
{
760760
struct cpufreq_freqs *freq = data;
761-
int cpu = freq->cpu;
761+
struct cpumask *cpus = freq->policy->cpus;
762+
int cpu, first = cpumask_first(cpus);
763+
unsigned int lpj;
762764

763765
if (freq->flags & CPUFREQ_CONST_LOOPS)
764766
return NOTIFY_OK;
765767

766-
if (!per_cpu(l_p_j_ref, cpu)) {
767-
per_cpu(l_p_j_ref, cpu) =
768-
per_cpu(cpu_data, cpu).loops_per_jiffy;
769-
per_cpu(l_p_j_ref_freq, cpu) = freq->old;
768+
if (!per_cpu(l_p_j_ref, first)) {
769+
for_each_cpu(cpu, cpus) {
770+
per_cpu(l_p_j_ref, cpu) =
771+
per_cpu(cpu_data, cpu).loops_per_jiffy;
772+
per_cpu(l_p_j_ref_freq, cpu) = freq->old;
773+
}
774+
770775
if (!global_l_p_j_ref) {
771776
global_l_p_j_ref = loops_per_jiffy;
772777
global_l_p_j_ref_freq = freq->old;
@@ -778,10 +783,11 @@ static int cpufreq_callback(struct notifier_block *nb,
778783
loops_per_jiffy = cpufreq_scale(global_l_p_j_ref,
779784
global_l_p_j_ref_freq,
780785
freq->new);
781-
per_cpu(cpu_data, cpu).loops_per_jiffy =
782-
cpufreq_scale(per_cpu(l_p_j_ref, cpu),
783-
per_cpu(l_p_j_ref_freq, cpu),
784-
freq->new);
786+
787+
lpj = cpufreq_scale(per_cpu(l_p_j_ref, first),
788+
per_cpu(l_p_j_ref_freq, first), freq->new);
789+
for_each_cpu(cpu, cpus)
790+
per_cpu(cpu_data, cpu).loops_per_jiffy = lpj;
785791
}
786792
return NOTIFY_OK;
787793
}

arch/sparc/kernel/time_64.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -653,19 +653,23 @@ static int sparc64_cpufreq_notifier(struct notifier_block *nb, unsigned long val
653653
void *data)
654654
{
655655
struct cpufreq_freqs *freq = data;
656-
unsigned int cpu = freq->cpu;
657-
struct freq_table *ft = &per_cpu(sparc64_freq_table, cpu);
656+
unsigned int cpu;
657+
struct freq_table *ft;
658658

659-
if (!ft->ref_freq) {
660-
ft->ref_freq = freq->old;
661-
ft->clock_tick_ref = cpu_data(cpu).clock_tick;
662-
}
663-
if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) ||
664-
(val == CPUFREQ_POSTCHANGE && freq->old > freq->new)) {
665-
cpu_data(cpu).clock_tick =
666-
cpufreq_scale(ft->clock_tick_ref,
667-
ft->ref_freq,
668-
freq->new);
659+
for_each_cpu(cpu, freq->policy->cpus) {
660+
ft = &per_cpu(sparc64_freq_table, cpu);
661+
662+
if (!ft->ref_freq) {
663+
ft->ref_freq = freq->old;
664+
ft->clock_tick_ref = cpu_data(cpu).clock_tick;
665+
}
666+
667+
if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) ||
668+
(val == CPUFREQ_POSTCHANGE && freq->old > freq->new)) {
669+
cpu_data(cpu).clock_tick =
670+
cpufreq_scale(ft->clock_tick_ref, ft->ref_freq,
671+
freq->new);
672+
}
669673
}
670674

671675
return 0;

arch/x86/kernel/cpu/intel_epb.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ static void intel_epb_restore(void)
9797
wrmsrl(MSR_IA32_ENERGY_PERF_BIAS, (epb & ~EPB_MASK) | val);
9898
}
9999

100+
#ifdef CONFIG_PM
100101
static struct syscore_ops intel_epb_syscore_ops = {
101102
.suspend = intel_epb_save,
102103
.resume = intel_epb_restore,
@@ -193,6 +194,25 @@ static int intel_epb_offline(unsigned int cpu)
193194
return 0;
194195
}
195196

197+
static inline void register_intel_ebp_syscore_ops(void)
198+
{
199+
register_syscore_ops(&intel_epb_syscore_ops);
200+
}
201+
#else /* !CONFIG_PM */
202+
static int intel_epb_online(unsigned int cpu)
203+
{
204+
intel_epb_restore();
205+
return 0;
206+
}
207+
208+
static int intel_epb_offline(unsigned int cpu)
209+
{
210+
return intel_epb_save();
211+
}
212+
213+
static inline void register_intel_ebp_syscore_ops(void) {}
214+
#endif
215+
196216
static __init int intel_epb_init(void)
197217
{
198218
int ret;
@@ -206,7 +226,7 @@ static __init int intel_epb_init(void)
206226
if (ret < 0)
207227
goto err_out_online;
208228

209-
register_syscore_ops(&intel_epb_syscore_ops);
229+
register_intel_ebp_syscore_ops();
210230
return 0;
211231

212232
err_out_online:

arch/x86/kernel/tsc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -979,7 +979,7 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
979979
if (!(freq->flags & CPUFREQ_CONST_LOOPS))
980980
mark_tsc_unstable("cpufreq changes");
981981

982-
set_cyc2ns_scale(tsc_khz, freq->cpu, rdtsc());
982+
set_cyc2ns_scale(tsc_khz, freq->policy->cpu, rdtsc());
983983
}
984984

985985
return 0;

arch/x86/kvm/x86.c

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6698,10 +6698,8 @@ static void kvm_hyperv_tsc_notifier(void)
66986698
}
66996699
#endif
67006700

6701-
static int kvmclock_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
6702-
void *data)
6701+
static void __kvmclock_cpufreq_notifier(struct cpufreq_freqs *freq, int cpu)
67036702
{
6704-
struct cpufreq_freqs *freq = data;
67056703
struct kvm *kvm;
67066704
struct kvm_vcpu *vcpu;
67076705
int i, send_ipi = 0;
@@ -6745,17 +6743,12 @@ static int kvmclock_cpufreq_notifier(struct notifier_block *nb, unsigned long va
67456743
*
67466744
*/
67476745

6748-
if (val == CPUFREQ_PRECHANGE && freq->old > freq->new)
6749-
return 0;
6750-
if (val == CPUFREQ_POSTCHANGE && freq->old < freq->new)
6751-
return 0;
6752-
6753-
smp_call_function_single(freq->cpu, tsc_khz_changed, freq, 1);
6746+
smp_call_function_single(cpu, tsc_khz_changed, freq, 1);
67546747

67556748
spin_lock(&kvm_lock);
67566749
list_for_each_entry(kvm, &vm_list, vm_list) {
67576750
kvm_for_each_vcpu(i, vcpu, kvm) {
6758-
if (vcpu->cpu != freq->cpu)
6751+
if (vcpu->cpu != cpu)
67596752
continue;
67606753
kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
67616754
if (vcpu->cpu != smp_processor_id())
@@ -6777,8 +6770,24 @@ static int kvmclock_cpufreq_notifier(struct notifier_block *nb, unsigned long va
67776770
* guest context is entered kvmclock will be updated,
67786771
* so the guest will not see stale values.
67796772
*/
6780-
smp_call_function_single(freq->cpu, tsc_khz_changed, freq, 1);
6773+
smp_call_function_single(cpu, tsc_khz_changed, freq, 1);
67816774
}
6775+
}
6776+
6777+
static int kvmclock_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
6778+
void *data)
6779+
{
6780+
struct cpufreq_freqs *freq = data;
6781+
int cpu;
6782+
6783+
if (val == CPUFREQ_PRECHANGE && freq->old > freq->new)
6784+
return 0;
6785+
if (val == CPUFREQ_POSTCHANGE && freq->old < freq->new)
6786+
return 0;
6787+
6788+
for_each_cpu(cpu, freq->policy->cpus)
6789+
__kvmclock_cpufreq_notifier(freq, cpu);
6790+
67826791
return 0;
67836792
}
67846793

drivers/base/power/domain.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ static const struct genpd_lock_ops genpd_spin_ops = {
128128
#define genpd_is_always_on(genpd) (genpd->flags & GENPD_FLAG_ALWAYS_ON)
129129
#define genpd_is_active_wakeup(genpd) (genpd->flags & GENPD_FLAG_ACTIVE_WAKEUP)
130130
#define genpd_is_cpu_domain(genpd) (genpd->flags & GENPD_FLAG_CPU_DOMAIN)
131+
#define genpd_is_rpm_always_on(genpd) (genpd->flags & GENPD_FLAG_RPM_ALWAYS_ON)
131132

132133
static inline bool irq_safe_dev_in_no_sleep_domain(struct device *dev,
133134
const struct generic_pm_domain *genpd)
@@ -515,7 +516,9 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on,
515516
* (1) The domain is configured as always on.
516517
* (2) When the domain has a subdomain being powered on.
517518
*/
518-
if (genpd_is_always_on(genpd) || atomic_read(&genpd->sd_count) > 0)
519+
if (genpd_is_always_on(genpd) ||
520+
genpd_is_rpm_always_on(genpd) ||
521+
atomic_read(&genpd->sd_count) > 0)
519522
return -EBUSY;
520523

521524
list_for_each_entry(pdd, &genpd->dev_list, list_node) {
@@ -1812,7 +1815,8 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
18121815
}
18131816

18141817
/* Always-on domains must be powered on at initialization. */
1815-
if (genpd_is_always_on(genpd) && !genpd_status_on(genpd))
1818+
if ((genpd_is_always_on(genpd) || genpd_is_rpm_always_on(genpd)) &&
1819+
!genpd_status_on(genpd))
18161820
return -EINVAL;
18171821

18181822
if (genpd_is_cpu_domain(genpd) &&

0 commit comments

Comments
 (0)