aboutsummaryrefslogtreecommitdiff
path: root/drivers/thermal/intel_powerclamp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/thermal/intel_powerclamp.c')
-rw-r--r--drivers/thermal/intel_powerclamp.c48
1 files changed, 40 insertions, 8 deletions
diff --git a/drivers/thermal/intel_powerclamp.c b/drivers/thermal/intel_powerclamp.c
index b40b37cd25e..95cb7fc20e1 100644
--- a/drivers/thermal/intel_powerclamp.c
+++ b/drivers/thermal/intel_powerclamp.c
@@ -206,6 +206,15 @@ static void find_target_mwait(void)
}
+static bool has_pkg_state_counter(void)
+{
+ u64 tmp;
+ return !rdmsrl_safe(MSR_PKG_C2_RESIDENCY, &tmp) ||
+ !rdmsrl_safe(MSR_PKG_C3_RESIDENCY, &tmp) ||
+ !rdmsrl_safe(MSR_PKG_C6_RESIDENCY, &tmp) ||
+ !rdmsrl_safe(MSR_PKG_C7_RESIDENCY, &tmp);
+}
+
static u64 pkg_state_counter(void)
{
u64 val;
@@ -438,14 +447,12 @@ static int clamp_thread(void *arg)
*/
local_touch_nmi();
stop_critical_timings();
- __monitor((void *)&current_thread_info()->flags, 0, 0);
- cpu_relax(); /* allow HT sibling to run */
- __mwait(eax, ecx);
+ mwait_idle_with_hints(eax, ecx);
start_critical_timings();
atomic_inc(&idle_wakeup_counter);
}
tick_nohz_idle_exit();
- preempt_enable_no_resched();
+ preempt_enable();
}
del_timer_sync(&wakeup_timer);
clear_bit(cpunr, cpu_clamping_mask);
@@ -500,7 +507,7 @@ static int start_power_clamp(void)
struct task_struct *thread;
/* check if pkg cstate counter is completely 0, abort in this case */
- if (!pkg_state_counter()) {
+ if (!has_pkg_state_counter()) {
pr_err("pkg cstate counter not functional, abort\n");
return -EINVAL;
}
@@ -674,7 +681,14 @@ static const struct x86_cpu_id intel_powerclamp_ids[] = {
{ X86_VENDOR_INTEL, 6, 0x2d},
{ X86_VENDOR_INTEL, 6, 0x2e},
{ X86_VENDOR_INTEL, 6, 0x2f},
+ { X86_VENDOR_INTEL, 6, 0x37},
{ X86_VENDOR_INTEL, 6, 0x3a},
+ { X86_VENDOR_INTEL, 6, 0x3c},
+ { X86_VENDOR_INTEL, 6, 0x3d},
+ { X86_VENDOR_INTEL, 6, 0x3e},
+ { X86_VENDOR_INTEL, 6, 0x3f},
+ { X86_VENDOR_INTEL, 6, 0x45},
+ { X86_VENDOR_INTEL, 6, 0x46},
{}
};
MODULE_DEVICE_TABLE(x86cpu, intel_powerclamp_ids);
@@ -758,21 +772,39 @@ static int powerclamp_init(void)
/* probe cpu features and ids here */
retval = powerclamp_probe();
if (retval)
- return retval;
+ goto exit_free;
+
/* set default limit, maybe adjusted during runtime based on feedback */
window_size = 2;
register_hotcpu_notifier(&powerclamp_cpu_notifier);
+
powerclamp_thread = alloc_percpu(struct task_struct *);
+ if (!powerclamp_thread) {
+ retval = -ENOMEM;
+ goto exit_unregister;
+ }
+
cooling_dev = thermal_cooling_device_register("intel_powerclamp", NULL,
&powerclamp_cooling_ops);
- if (IS_ERR(cooling_dev))
- return -ENODEV;
+ if (IS_ERR(cooling_dev)) {
+ retval = -ENODEV;
+ goto exit_free_thread;
+ }
if (!duration)
duration = jiffies_to_msecs(DEFAULT_DURATION_JIFFIES);
+
powerclamp_create_debug_files();
return 0;
+
+exit_free_thread:
+ free_percpu(powerclamp_thread);
+exit_unregister:
+ unregister_hotcpu_notifier(&powerclamp_cpu_notifier);
+exit_free:
+ kfree(cpu_clamping_mask);
+ return retval;
}
module_init(powerclamp_init);