Skip to content

Commit ddf18a0

Browse files
committed
Merge branches 'pm-cpufreq' and 'powercap' into linux-next
* pm-cpufreq: cpufreq: acpi-cpufreq: drop rdmsr_on_cpus() usage cpufreq: acpi-cpufreq: Convert to hotplug state machine * powercap: powercap/intel_rapl: fix and tidy up error handling
3 parents 3e0b766 + a3605c4 + cb43f81 commit ddf18a0

File tree

2 files changed

+72
-70
lines changed

2 files changed

+72
-70
lines changed

drivers/cpufreq/acpi-cpufreq.c

Lines changed: 48 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ static inline struct acpi_processor_performance *to_perf_data(struct acpi_cpufre
8484
static struct cpufreq_driver acpi_cpufreq_driver;
8585

8686
static unsigned int acpi_pstate_strict;
87-
static struct msr __percpu *msrs;
8887

8988
static bool boost_state(unsigned int cpu)
9089
{
@@ -104,11 +103,10 @@ static bool boost_state(unsigned int cpu)
104103
return false;
105104
}
106105

107-
static void boost_set_msrs(bool enable, const struct cpumask *cpumask)
106+
static int boost_set_msr(bool enable)
108107
{
109-
u32 cpu;
110108
u32 msr_addr;
111-
u64 msr_mask;
109+
u64 msr_mask, val;
112110

113111
switch (boot_cpu_data.x86_vendor) {
114112
case X86_VENDOR_INTEL:
@@ -120,26 +118,31 @@ static void boost_set_msrs(bool enable, const struct cpumask *cpumask)
120118
msr_mask = MSR_K7_HWCR_CPB_DIS;
121119
break;
122120
default:
123-
return;
121+
return -EINVAL;
124122
}
125123

126-
rdmsr_on_cpus(cpumask, msr_addr, msrs);
124+
rdmsrl(msr_addr, val);
127125

128-
for_each_cpu(cpu, cpumask) {
129-
struct msr *reg = per_cpu_ptr(msrs, cpu);
130-
if (enable)
131-
reg->q &= ~msr_mask;
132-
else
133-
reg->q |= msr_mask;
134-
}
126+
if (enable)
127+
val &= ~msr_mask;
128+
else
129+
val |= msr_mask;
130+
131+
wrmsrl(msr_addr, val);
132+
return 0;
133+
}
134+
135+
static void boost_set_msr_each(void *p_en)
136+
{
137+
bool enable = (bool) p_en;
135138

136-
wrmsr_on_cpus(cpumask, msr_addr, msrs);
139+
boost_set_msr(enable);
137140
}
138141

139142
static int set_boost(int val)
140143
{
141144
get_online_cpus();
142-
boost_set_msrs(val, cpu_online_mask);
145+
on_each_cpu(boost_set_msr_each, (void *)(long)val, 1);
143146
put_online_cpus();
144147
pr_debug("Core Boosting %sabled.\n", val ? "en" : "dis");
145148

@@ -536,46 +539,24 @@ static void free_acpi_perf_data(void)
536539
free_percpu(acpi_perf_data);
537540
}
538541

539-
static int boost_notify(struct notifier_block *nb, unsigned long action,
540-
void *hcpu)
542+
static int cpufreq_boost_online(unsigned int cpu)
541543
{
542-
unsigned cpu = (long)hcpu;
543-
const struct cpumask *cpumask;
544-
545-
cpumask = get_cpu_mask(cpu);
544+
/*
545+
* On the CPU_UP path we simply keep the boost-disable flag
546+
* in sync with the current global state.
547+
*/
548+
return boost_set_msr(acpi_cpufreq_driver.boost_enabled);
549+
}
546550

551+
static int cpufreq_boost_down_prep(unsigned int cpu)
552+
{
547553
/*
548554
* Clear the boost-disable bit on the CPU_DOWN path so that
549-
* this cpu cannot block the remaining ones from boosting. On
550-
* the CPU_UP path we simply keep the boost-disable flag in
551-
* sync with the current global state.
555+
* this cpu cannot block the remaining ones from boosting.
552556
*/
553-
554-
switch (action) {
555-
case CPU_DOWN_FAILED:
556-
case CPU_DOWN_FAILED_FROZEN:
557-
case CPU_ONLINE:
558-
case CPU_ONLINE_FROZEN:
559-
boost_set_msrs(acpi_cpufreq_driver.boost_enabled, cpumask);
560-
break;
561-
562-
case CPU_DOWN_PREPARE:
563-
case CPU_DOWN_PREPARE_FROZEN:
564-
boost_set_msrs(1, cpumask);
565-
break;
566-
567-
default:
568-
break;
569-
}
570-
571-
return NOTIFY_OK;
557+
return boost_set_msr(1);
572558
}
573559

574-
575-
static struct notifier_block boost_nb = {
576-
.notifier_call = boost_notify,
577-
};
578-
579560
/*
580561
* acpi_cpufreq_early_init - initialize ACPI P-States library
581562
*
@@ -922,37 +903,35 @@ static struct cpufreq_driver acpi_cpufreq_driver = {
922903
.attr = acpi_cpufreq_attr,
923904
};
924905

906+
static enum cpuhp_state acpi_cpufreq_online;
907+
925908
static void __init acpi_cpufreq_boost_init(void)
926909
{
927-
if (boot_cpu_has(X86_FEATURE_CPB) || boot_cpu_has(X86_FEATURE_IDA)) {
928-
msrs = msrs_alloc();
929-
930-
if (!msrs)
931-
return;
932-
933-
acpi_cpufreq_driver.set_boost = set_boost;
934-
acpi_cpufreq_driver.boost_enabled = boost_state(0);
935-
936-
cpu_notifier_register_begin();
910+
int ret;
937911

938-
/* Force all MSRs to the same value */
939-
boost_set_msrs(acpi_cpufreq_driver.boost_enabled,
940-
cpu_online_mask);
912+
if (!(boot_cpu_has(X86_FEATURE_CPB) || boot_cpu_has(X86_FEATURE_IDA)))
913+
return;
941914

942-
__register_cpu_notifier(&boost_nb);
915+
acpi_cpufreq_driver.set_boost = set_boost;
916+
acpi_cpufreq_driver.boost_enabled = boost_state(0);
943917

944-
cpu_notifier_register_done();
918+
/*
919+
* This calls the online callback on all online cpu and forces all
920+
* MSRs to the same value.
921+
*/
922+
ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "cpufreq/acpi:online",
923+
cpufreq_boost_online, cpufreq_boost_down_prep);
924+
if (ret < 0) {
925+
pr_err("acpi_cpufreq: failed to register hotplug callbacks\n");
926+
return;
945927
}
928+
acpi_cpufreq_online = ret;
946929
}
947930

948931
static void acpi_cpufreq_boost_exit(void)
949932
{
950-
if (msrs) {
951-
unregister_cpu_notifier(&boost_nb);
952-
953-
msrs_free(msrs);
954-
msrs = NULL;
955-
}
933+
if (acpi_cpufreq_online >= 0)
934+
cpuhp_remove_state_nocalls(acpi_cpufreq_online);
956935
}
957936

958937
static int __init acpi_cpufreq_init(void)

drivers/powercap/intel_rapl.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ static int contraint_to_pl(struct rapl_domain *rd, int cid)
429429
return i;
430430
}
431431
}
432+
pr_err("Cannot find matching power limit for constraint %d\n", cid);
432433

433434
return -EINVAL;
434435
}
@@ -444,6 +445,10 @@ static int set_power_limit(struct powercap_zone *power_zone, int cid,
444445
get_online_cpus();
445446
rd = power_zone_to_rapl_domain(power_zone);
446447
id = contraint_to_pl(rd, cid);
448+
if (id < 0) {
449+
ret = id;
450+
goto set_exit;
451+
}
447452

448453
rp = rd->rp;
449454

@@ -483,6 +488,11 @@ static int get_current_power_limit(struct powercap_zone *power_zone, int cid,
483488
get_online_cpus();
484489
rd = power_zone_to_rapl_domain(power_zone);
485490
id = contraint_to_pl(rd, cid);
491+
if (id < 0) {
492+
ret = id;
493+
goto get_exit;
494+
}
495+
486496
switch (rd->rpl[id].prim_id) {
487497
case PL1_ENABLE:
488498
prim = POWER_LIMIT1;
@@ -499,6 +509,7 @@ static int get_current_power_limit(struct powercap_zone *power_zone, int cid,
499509
else
500510
*data = val;
501511

512+
get_exit:
502513
put_online_cpus();
503514

504515
return ret;
@@ -514,6 +525,10 @@ static int set_time_window(struct powercap_zone *power_zone, int cid,
514525
get_online_cpus();
515526
rd = power_zone_to_rapl_domain(power_zone);
516527
id = contraint_to_pl(rd, cid);
528+
if (id < 0) {
529+
ret = id;
530+
goto set_time_exit;
531+
}
517532

518533
switch (rd->rpl[id].prim_id) {
519534
case PL1_ENABLE:
@@ -525,6 +540,8 @@ static int set_time_window(struct powercap_zone *power_zone, int cid,
525540
default:
526541
ret = -EINVAL;
527542
}
543+
544+
set_time_exit:
528545
put_online_cpus();
529546
return ret;
530547
}
@@ -539,6 +556,10 @@ static int get_time_window(struct powercap_zone *power_zone, int cid, u64 *data)
539556
get_online_cpus();
540557
rd = power_zone_to_rapl_domain(power_zone);
541558
id = contraint_to_pl(rd, cid);
559+
if (id < 0) {
560+
ret = id;
561+
goto get_time_exit;
562+
}
542563

543564
switch (rd->rpl[id].prim_id) {
544565
case PL1_ENABLE:
@@ -553,6 +574,8 @@ static int get_time_window(struct powercap_zone *power_zone, int cid, u64 *data)
553574
}
554575
if (!ret)
555576
*data = val;
577+
578+
get_time_exit:
556579
put_online_cpus();
557580

558581
return ret;
@@ -694,7 +717,7 @@ static u64 rapl_unit_xlate(struct rapl_domain *rd, enum unit_type type,
694717
case ENERGY_UNIT:
695718
scale = ENERGY_UNIT_SCALE;
696719
/* per domain unit takes precedence */
697-
if (rd && rd->domain_energy_unit)
720+
if (rd->domain_energy_unit)
698721
units = rd->domain_energy_unit;
699722
else
700723
units = rp->energy_unit;

0 commit comments

Comments
 (0)