From 4d2b6e4a9ebc2907e4a64fa240d8b67c7051e997 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Wed, 25 Mar 2015 22:16:24 +0100 Subject: thermal/intel_powerclamp: add __init / __exit annotations Mark the module init / exit functions with __init / __exit accodingly. This allows making the intel_powerclamp_ids[] array __initconst, too, as it only gets referenced from powerclamp_probe(). This is safe as file2alias doesn't care about the section, but the symbol name for the MODULE_DEVICE_TABLE alias. Cc: Arjan van de Ven Cc: Jacob Pan Signed-off-by: Mathias Krause Acked-by: Jacob Pan Acked-by: Jacob Pan Signed-off-by: Zhang Rui --- drivers/thermal/intel_powerclamp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/thermal/intel_powerclamp.c') diff --git a/drivers/thermal/intel_powerclamp.c b/drivers/thermal/intel_powerclamp.c index 12623bc02f46..b0f7ced5c3ef 100644 --- a/drivers/thermal/intel_powerclamp.c +++ b/drivers/thermal/intel_powerclamp.c @@ -667,7 +667,7 @@ static struct thermal_cooling_device_ops powerclamp_cooling_ops = { }; /* runs on Nehalem and later */ -static const struct x86_cpu_id intel_powerclamp_ids[] = { +static const struct x86_cpu_id intel_powerclamp_ids[] __initconst = { { X86_VENDOR_INTEL, 6, 0x1a}, { X86_VENDOR_INTEL, 6, 0x1c}, { X86_VENDOR_INTEL, 6, 0x1e}, @@ -694,7 +694,7 @@ static const struct x86_cpu_id intel_powerclamp_ids[] = { }; MODULE_DEVICE_TABLE(x86cpu, intel_powerclamp_ids); -static int powerclamp_probe(void) +static int __init powerclamp_probe(void) { if (!x86_match_cpu(intel_powerclamp_ids)) { pr_err("Intel powerclamp does not run on family %d model %d\n", @@ -760,7 +760,7 @@ file_error: debugfs_remove_recursive(debug_dir); } -static int powerclamp_init(void) +static int __init powerclamp_init(void) { int retval; int bitmap_size; @@ -809,7 +809,7 @@ exit_free: } module_init(powerclamp_init); -static void powerclamp_exit(void) +static void __exit powerclamp_exit(void) { unregister_hotcpu_notifier(&powerclamp_cpu_notifier); end_power_clamp(); -- cgit v1.2.3 From f09bfdb6670e08b004959de727eeec73baa753a2 Mon Sep 17 00:00:00 2001 From: Jacob Pan Date: Tue, 7 Apr 2015 05:47:26 -0700 Subject: thermal/intel_powerclamp: add id for broadwell server Broadwell server has support for package C-states, idle injection works as expected on this platform. Signed-off-by: Jacob Pan Signed-off-by: Zhang Rui --- drivers/thermal/intel_powerclamp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/thermal/intel_powerclamp.c') diff --git a/drivers/thermal/intel_powerclamp.c b/drivers/thermal/intel_powerclamp.c index b0f7ced5c3ef..9b02d19ce1a4 100644 --- a/drivers/thermal/intel_powerclamp.c +++ b/drivers/thermal/intel_powerclamp.c @@ -689,6 +689,7 @@ static const struct x86_cpu_id intel_powerclamp_ids[] __initconst = { { X86_VENDOR_INTEL, 6, 0x46}, { X86_VENDOR_INTEL, 6, 0x4c}, { X86_VENDOR_INTEL, 6, 0x4d}, + { X86_VENDOR_INTEL, 6, 0x4f}, { X86_VENDOR_INTEL, 6, 0x56}, {} }; -- cgit v1.2.3 From d81861138898ce8d83bc78f0d558ac3984225e2b Mon Sep 17 00:00:00 2001 From: Jacob Pan Date: Thu, 7 May 2015 09:03:59 -0700 Subject: thermal/powerclamp: fix missing newer package c-states Package C8 to C10 was introduced in newer Intel CPUs, we need to include them in the package c-state residency calculation. Otherwise, idle injection target is not accurately maintained by the closed control loop. Also cleaned up the code to make it scale better with large number of c-states. Reported-by: Kristen Carlson Accardi Signed-off-by: Jacob Pan Signed-off-by: Zhang Rui --- drivers/thermal/intel_powerclamp.c | 80 ++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 37 deletions(-) (limited to 'drivers/thermal/intel_powerclamp.c') diff --git a/drivers/thermal/intel_powerclamp.c b/drivers/thermal/intel_powerclamp.c index 9b02d19ce1a4..725718e97a0b 100644 --- a/drivers/thermal/intel_powerclamp.c +++ b/drivers/thermal/intel_powerclamp.c @@ -206,51 +206,57 @@ static void find_target_mwait(void) } +struct pkg_cstate_info { + bool skip; + int msr_index; + int cstate_id; +}; + +#define PKG_CSTATE_INIT(id) { \ + .msr_index = MSR_PKG_C##id##_RESIDENCY, \ + .cstate_id = id \ + } + +static struct pkg_cstate_info pkg_cstates[] = { + PKG_CSTATE_INIT(2), + PKG_CSTATE_INIT(3), + PKG_CSTATE_INIT(6), + PKG_CSTATE_INIT(7), + PKG_CSTATE_INIT(8), + PKG_CSTATE_INIT(9), + PKG_CSTATE_INIT(10), + {NULL}, +}; + 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); + u64 val; + struct pkg_cstate_info *info = pkg_cstates; + + /* check if any one of the counter msrs exists */ + while (info->msr_index) { + if (!rdmsrl_safe(info->msr_index, &val)) + return true; + info++; + } + + return false; } static u64 pkg_state_counter(void) { u64 val; u64 count = 0; - - static bool skip_c2; - static bool skip_c3; - static bool skip_c6; - static bool skip_c7; - - if (!skip_c2) { - if (!rdmsrl_safe(MSR_PKG_C2_RESIDENCY, &val)) - count += val; - else - skip_c2 = true; - } - - if (!skip_c3) { - if (!rdmsrl_safe(MSR_PKG_C3_RESIDENCY, &val)) - count += val; - else - skip_c3 = true; - } - - if (!skip_c6) { - if (!rdmsrl_safe(MSR_PKG_C6_RESIDENCY, &val)) - count += val; - else - skip_c6 = true; - } - - if (!skip_c7) { - if (!rdmsrl_safe(MSR_PKG_C7_RESIDENCY, &val)) - count += val; - else - skip_c7 = true; + struct pkg_cstate_info *info = pkg_cstates; + + while (info->msr_index) { + if (!info->skip) { + if (!rdmsrl_safe(info->msr_index, &val)) + count += val; + else + info->skip = true; + } + info++; } return count; -- cgit v1.2.3