Skip to content

Commit 88e9c0b

Browse files
committed
Merge branches 'pm-cpufreq', 'pm-cpu' and 'pm-em'
* pm-cpufreq: cpufreq: intel_pstate: Process HWP Guaranteed change notification thermal: intel: Allow processing of HWP interrupt cpufreq: schedutil: Use kobject release() method to free sugov_tunables cpufreq: Replace deprecated CPU-hotplug functions * pm-cpu: notifier: Remove atomic_notifier_call_chain_robust() PM: cpu: Make notifier chain use a raw_spinlock_t * pm-em: PM: EM: Increase energy calculation precision
4 parents 7ee5fd1 + d0e936a + 15538a2 + 7fcc17d commit 88e9c0b

File tree

14 files changed

+130
-54
lines changed

14 files changed

+130
-54
lines changed

drivers/cpufreq/acpi-cpufreq.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,9 @@ static ssize_t store_cpb(struct cpufreq_policy *policy, const char *buf,
163163
if (ret || val > 1)
164164
return -EINVAL;
165165

166-
get_online_cpus();
166+
cpus_read_lock();
167167
set_boost(policy, val);
168-
put_online_cpus();
168+
cpus_read_unlock();
169169

170170
return count;
171171
}

drivers/cpufreq/cpufreq.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2654,18 +2654,18 @@ int cpufreq_boost_trigger_state(int state)
26542654
cpufreq_driver->boost_enabled = state;
26552655
write_unlock_irqrestore(&cpufreq_driver_lock, flags);
26562656

2657-
get_online_cpus();
2657+
cpus_read_lock();
26582658
for_each_active_policy(policy) {
26592659
ret = cpufreq_driver->set_boost(policy, state);
26602660
if (ret)
26612661
goto err_reset_state;
26622662
}
2663-
put_online_cpus();
2663+
cpus_read_unlock();
26642664

26652665
return 0;
26662666

26672667
err_reset_state:
2668-
put_online_cpus();
2668+
cpus_read_unlock();
26692669

26702670
write_lock_irqsave(&cpufreq_driver_lock, flags);
26712671
cpufreq_driver->boost_enabled = !state;

drivers/cpufreq/cpufreq_ondemand.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ static void od_set_powersave_bias(unsigned int powersave_bias)
418418
default_powersave_bias = powersave_bias;
419419
cpumask_clear(&done);
420420

421-
get_online_cpus();
421+
cpus_read_lock();
422422
for_each_online_cpu(cpu) {
423423
struct cpufreq_policy *policy;
424424
struct policy_dbs_info *policy_dbs;
@@ -442,7 +442,7 @@ static void od_set_powersave_bias(unsigned int powersave_bias)
442442
od_tuners = dbs_data->tuners;
443443
od_tuners->powersave_bias = default_powersave_bias;
444444
}
445-
put_online_cpus();
445+
cpus_read_unlock();
446446
}
447447

448448
void od_register_powersave_bias_handler(unsigned int (*f)

drivers/cpufreq/intel_pstate.c

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <asm/cpu_device_id.h>
3333
#include <asm/cpufeature.h>
3434
#include <asm/intel-family.h>
35+
#include "../drivers/thermal/intel/thermal_interrupt.h"
3536

3637
#define INTEL_PSTATE_SAMPLING_INTERVAL (10 * NSEC_PER_MSEC)
3738

@@ -219,6 +220,7 @@ struct global_params {
219220
* @sched_flags: Store scheduler flags for possible cross CPU update
220221
* @hwp_boost_min: Last HWP boosted min performance
221222
* @suspended: Whether or not the driver has been suspended.
223+
* @hwp_notify_work: workqueue for HWP notifications.
222224
*
223225
* This structure stores per CPU instance data for all CPUs.
224226
*/
@@ -257,6 +259,7 @@ struct cpudata {
257259
unsigned int sched_flags;
258260
u32 hwp_boost_min;
259261
bool suspended;
262+
struct delayed_work hwp_notify_work;
260263
};
261264

262265
static struct cpudata **all_cpu_data;
@@ -1625,6 +1628,40 @@ static void intel_pstate_sysfs_hide_hwp_dynamic_boost(void)
16251628

16261629
/************************** sysfs end ************************/
16271630

1631+
static void intel_pstate_notify_work(struct work_struct *work)
1632+
{
1633+
mutex_lock(&intel_pstate_driver_lock);
1634+
cpufreq_update_policy(smp_processor_id());
1635+
wrmsrl(MSR_HWP_STATUS, 0);
1636+
mutex_unlock(&intel_pstate_driver_lock);
1637+
}
1638+
1639+
void notify_hwp_interrupt(void)
1640+
{
1641+
unsigned int this_cpu = smp_processor_id();
1642+
struct cpudata *cpudata;
1643+
u64 value;
1644+
1645+
if (!hwp_active || !boot_cpu_has(X86_FEATURE_HWP_NOTIFY))
1646+
return;
1647+
1648+
rdmsrl(MSR_HWP_STATUS, value);
1649+
if (!(value & 0x01))
1650+
return;
1651+
1652+
cpudata = all_cpu_data[this_cpu];
1653+
schedule_delayed_work_on(this_cpu, &cpudata->hwp_notify_work, msecs_to_jiffies(10));
1654+
}
1655+
1656+
static void intel_pstate_enable_hwp_interrupt(struct cpudata *cpudata)
1657+
{
1658+
/* Enable HWP notification interrupt for guaranteed performance change */
1659+
if (boot_cpu_has(X86_FEATURE_HWP_NOTIFY)) {
1660+
INIT_DELAYED_WORK(&cpudata->hwp_notify_work, intel_pstate_notify_work);
1661+
wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_INTERRUPT, 0x01);
1662+
}
1663+
}
1664+
16281665
static void intel_pstate_hwp_enable(struct cpudata *cpudata)
16291666
{
16301667
/* First disable HWP notification interrupt as we don't process them */
@@ -1634,6 +1671,8 @@ static void intel_pstate_hwp_enable(struct cpudata *cpudata)
16341671
wrmsrl_on_cpu(cpudata->cpu, MSR_PM_ENABLE, 0x1);
16351672
if (cpudata->epp_default == -EINVAL)
16361673
cpudata->epp_default = intel_pstate_get_epp(cpudata, 0);
1674+
1675+
intel_pstate_enable_hwp_interrupt(cpudata);
16371676
}
16381677

16391678
static int atom_get_min_pstate(void)
@@ -2969,7 +3008,7 @@ static void intel_pstate_driver_cleanup(void)
29693008
{
29703009
unsigned int cpu;
29713010

2972-
get_online_cpus();
3011+
cpus_read_lock();
29733012
for_each_online_cpu(cpu) {
29743013
if (all_cpu_data[cpu]) {
29753014
if (intel_pstate_driver == &intel_pstate)
@@ -2979,7 +3018,7 @@ static void intel_pstate_driver_cleanup(void)
29793018
all_cpu_data[cpu] = NULL;
29803019
}
29813020
}
2982-
put_online_cpus();
3021+
cpus_read_unlock();
29833022

29843023
intel_pstate_driver = NULL;
29853024
}

drivers/cpufreq/powernow-k8.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,18 +1180,18 @@ static int powernowk8_init(void)
11801180
if (!x86_match_cpu(powernow_k8_ids))
11811181
return -ENODEV;
11821182

1183-
get_online_cpus();
1183+
cpus_read_lock();
11841184
for_each_online_cpu(i) {
11851185
smp_call_function_single(i, check_supported_cpu, &ret, 1);
11861186
if (!ret)
11871187
supported_cpus++;
11881188
}
11891189

11901190
if (supported_cpus != num_online_cpus()) {
1191-
put_online_cpus();
1191+
cpus_read_unlock();
11921192
return -ENODEV;
11931193
}
1194-
put_online_cpus();
1194+
cpus_read_unlock();
11951195

11961196
ret = cpufreq_register_driver(&cpufreq_amd64_driver);
11971197
if (ret)

drivers/cpufreq/powernv-cpufreq.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,7 @@ static void powernv_cpufreq_work_fn(struct work_struct *work)
918918
unsigned int cpu;
919919
cpumask_t mask;
920920

921-
get_online_cpus();
921+
cpus_read_lock();
922922
cpumask_and(&mask, &chip->mask, cpu_online_mask);
923923
smp_call_function_any(&mask,
924924
powernv_cpufreq_throttle_check, NULL, 0);
@@ -939,7 +939,7 @@ static void powernv_cpufreq_work_fn(struct work_struct *work)
939939
cpufreq_cpu_put(policy);
940940
}
941941
out:
942-
put_online_cpus();
942+
cpus_read_unlock();
943943
}
944944

945945
static int powernv_cpufreq_occ_msg(struct notifier_block *nb,

drivers/thermal/intel/therm_throt.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,13 +569,18 @@ static void notify_thresholds(__u64 msr_val)
569569
platform_thermal_notify(msr_val);
570570
}
571571

572+
void __weak notify_hwp_interrupt(void)
573+
{
574+
wrmsrl_safe(MSR_HWP_STATUS, 0);
575+
}
576+
572577
/* Thermal transition interrupt handler */
573578
void intel_thermal_interrupt(void)
574579
{
575580
__u64 msr_val;
576581

577582
if (static_cpu_has(X86_FEATURE_HWP))
578-
wrmsrl_safe(MSR_HWP_STATUS, 0);
583+
notify_hwp_interrupt();
579584

580585
rdmsrl(MSR_IA32_THERM_STATUS, msr_val);
581586

drivers/thermal/intel/thermal_interrupt.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,7 @@ extern int (*platform_thermal_notify)(__u64 msr_val);
1212
* callback has rate control */
1313
extern bool (*platform_thermal_package_rate_control)(void);
1414

15+
/* Handle HWP interrupt */
16+
extern void notify_hwp_interrupt(void);
17+
1518
#endif /* _INTEL_THERMAL_INTERRUPT_H */

include/linux/energy_model.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,22 @@ struct em_perf_domain {
5353
#ifdef CONFIG_ENERGY_MODEL
5454
#define EM_MAX_POWER 0xFFFF
5555

56+
/*
57+
* Increase resolution of energy estimation calculations for 64-bit
58+
* architectures. The extra resolution improves decision made by EAS for the
59+
* task placement when two Performance Domains might provide similar energy
60+
* estimation values (w/o better resolution the values could be equal).
61+
*
62+
* We increase resolution only if we have enough bits to allow this increased
63+
* resolution (i.e. 64-bit). The costs for increasing resolution when 32-bit
64+
* are pretty high and the returns do not justify the increased costs.
65+
*/
66+
#ifdef CONFIG_64BIT
67+
#define em_scale_power(p) ((p) * 1000)
68+
#else
69+
#define em_scale_power(p) (p)
70+
#endif
71+
5672
struct em_data_callback {
5773
/**
5874
* active_power() - Provide power at the next performance state of

include/linux/notifier.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,6 @@ extern int raw_notifier_call_chain(struct raw_notifier_head *nh,
168168
extern int srcu_notifier_call_chain(struct srcu_notifier_head *nh,
169169
unsigned long val, void *v);
170170

171-
extern int atomic_notifier_call_chain_robust(struct atomic_notifier_head *nh,
172-
unsigned long val_up, unsigned long val_down, void *v);
173171
extern int blocking_notifier_call_chain_robust(struct blocking_notifier_head *nh,
174172
unsigned long val_up, unsigned long val_down, void *v);
175173
extern int raw_notifier_call_chain_robust(struct raw_notifier_head *nh,

0 commit comments

Comments
 (0)