aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Pan <jacob.jun.pan@linux.intel.com>2015-05-07 12:03:59 -0400
committerZhang Rui <rui.zhang@intel.com>2015-05-09 01:36:57 -0400
commitd81861138898ce8d83bc78f0d558ac3984225e2b (patch)
tree48762b68a0212357464468ac4026dd148330d724
parentf09bfdb6670e08b004959de727eeec73baa753a2 (diff)
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 <kristen@linux.intel.com> Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com> Signed-off-by: Zhang Rui <rui.zhang@intel.com>
-rw-r--r--drivers/thermal/intel_powerclamp.c80
1 files changed, 43 insertions, 37 deletions
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)
206 206
207} 207}
208 208
209struct pkg_cstate_info {
210 bool skip;
211 int msr_index;
212 int cstate_id;
213};
214
215#define PKG_CSTATE_INIT(id) { \
216 .msr_index = MSR_PKG_C##id##_RESIDENCY, \
217 .cstate_id = id \
218 }
219
220static struct pkg_cstate_info pkg_cstates[] = {
221 PKG_CSTATE_INIT(2),
222 PKG_CSTATE_INIT(3),
223 PKG_CSTATE_INIT(6),
224 PKG_CSTATE_INIT(7),
225 PKG_CSTATE_INIT(8),
226 PKG_CSTATE_INIT(9),
227 PKG_CSTATE_INIT(10),
228 {NULL},
229};
230
209static bool has_pkg_state_counter(void) 231static bool has_pkg_state_counter(void)
210{ 232{
211 u64 tmp; 233 u64 val;
212 return !rdmsrl_safe(MSR_PKG_C2_RESIDENCY, &tmp) || 234 struct pkg_cstate_info *info = pkg_cstates;
213 !rdmsrl_safe(MSR_PKG_C3_RESIDENCY, &tmp) || 235
214 !rdmsrl_safe(MSR_PKG_C6_RESIDENCY, &tmp) || 236 /* check if any one of the counter msrs exists */
215 !rdmsrl_safe(MSR_PKG_C7_RESIDENCY, &tmp); 237 while (info->msr_index) {
238 if (!rdmsrl_safe(info->msr_index, &val))
239 return true;
240 info++;
241 }
242
243 return false;
216} 244}
217 245
218static u64 pkg_state_counter(void) 246static u64 pkg_state_counter(void)
219{ 247{
220 u64 val; 248 u64 val;
221 u64 count = 0; 249 u64 count = 0;
222 250 struct pkg_cstate_info *info = pkg_cstates;
223 static bool skip_c2; 251
224 static bool skip_c3; 252 while (info->msr_index) {
225 static bool skip_c6; 253 if (!info->skip) {
226 static bool skip_c7; 254 if (!rdmsrl_safe(info->msr_index, &val))
227 255 count += val;
228 if (!skip_c2) { 256 else
229 if (!rdmsrl_safe(MSR_PKG_C2_RESIDENCY, &val)) 257 info->skip = true;
230 count += val; 258 }
231 else 259 info++;
232 skip_c2 = true;
233 }
234
235 if (!skip_c3) {
236 if (!rdmsrl_safe(MSR_PKG_C3_RESIDENCY, &val))
237 count += val;
238 else
239 skip_c3 = true;
240 }
241
242 if (!skip_c6) {
243 if (!rdmsrl_safe(MSR_PKG_C6_RESIDENCY, &val))
244 count += val;
245 else
246 skip_c6 = true;
247 }
248
249 if (!skip_c7) {
250 if (!rdmsrl_safe(MSR_PKG_C7_RESIDENCY, &val))
251 count += val;
252 else
253 skip_c7 = true;
254 } 260 }
255 261
256 return count; 262 return count;