diff options
-rw-r--r-- | arch/x86/include/uapi/asm/msr-index.h | 3 | ||||
-rw-r--r-- | drivers/idle/intel_idle.c | 77 | ||||
-rw-r--r-- | tools/power/x86/turbostat/turbostat.c | 80 |
3 files changed, 119 insertions, 41 deletions
diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/asm/msr-index.h index eac9e92fe181..e21331ce368f 100644 --- a/arch/x86/include/uapi/asm/msr-index.h +++ b/arch/x86/include/uapi/asm/msr-index.h | |||
@@ -149,6 +149,9 @@ | |||
149 | 149 | ||
150 | #define MSR_CORE_C1_RES 0x00000660 | 150 | #define MSR_CORE_C1_RES 0x00000660 |
151 | 151 | ||
152 | #define MSR_CC6_DEMOTION_POLICY_CONFIG 0x00000668 | ||
153 | #define MSR_MC6_DEMOTION_POLICY_CONFIG 0x00000669 | ||
154 | |||
152 | #define MSR_AMD64_MC0_MASK 0xc0010044 | 155 | #define MSR_AMD64_MC0_MASK 0xc0010044 |
153 | 156 | ||
154 | #define MSR_IA32_MCx_CTL(x) (MSR_IA32_MC0_CTL + 4*(x)) | 157 | #define MSR_IA32_MCx_CTL(x) (MSR_IA32_MC0_CTL + 4*(x)) |
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 4d140bbbe100..9b7ee7e427df 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c | |||
@@ -89,6 +89,7 @@ struct idle_cpu { | |||
89 | * Indicate which enable bits to clear here. | 89 | * Indicate which enable bits to clear here. |
90 | */ | 90 | */ |
91 | unsigned long auto_demotion_disable_flags; | 91 | unsigned long auto_demotion_disable_flags; |
92 | bool byt_auto_demotion_disable_flag; | ||
92 | bool disable_promotion_to_c1e; | 93 | bool disable_promotion_to_c1e; |
93 | }; | 94 | }; |
94 | 95 | ||
@@ -442,6 +443,66 @@ static struct cpuidle_state hsw_cstates[] = { | |||
442 | { | 443 | { |
443 | .enter = NULL } | 444 | .enter = NULL } |
444 | }; | 445 | }; |
446 | static struct cpuidle_state bdw_cstates[] = { | ||
447 | { | ||
448 | .name = "C1-BDW", | ||
449 | .desc = "MWAIT 0x00", | ||
450 | .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID, | ||
451 | .exit_latency = 2, | ||
452 | .target_residency = 2, | ||
453 | .enter = &intel_idle }, | ||
454 | { | ||
455 | .name = "C1E-BDW", | ||
456 | .desc = "MWAIT 0x01", | ||
457 | .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_TIME_VALID, | ||
458 | .exit_latency = 10, | ||
459 | .target_residency = 20, | ||
460 | .enter = &intel_idle }, | ||
461 | { | ||
462 | .name = "C3-BDW", | ||
463 | .desc = "MWAIT 0x10", | ||
464 | .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
465 | .exit_latency = 40, | ||
466 | .target_residency = 100, | ||
467 | .enter = &intel_idle }, | ||
468 | { | ||
469 | .name = "C6-BDW", | ||
470 | .desc = "MWAIT 0x20", | ||
471 | .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
472 | .exit_latency = 133, | ||
473 | .target_residency = 400, | ||
474 | .enter = &intel_idle }, | ||
475 | { | ||
476 | .name = "C7s-BDW", | ||
477 | .desc = "MWAIT 0x32", | ||
478 | .flags = MWAIT2flg(0x32) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
479 | .exit_latency = 166, | ||
480 | .target_residency = 500, | ||
481 | .enter = &intel_idle }, | ||
482 | { | ||
483 | .name = "C8-BDW", | ||
484 | .desc = "MWAIT 0x40", | ||
485 | .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
486 | .exit_latency = 300, | ||
487 | .target_residency = 900, | ||
488 | .enter = &intel_idle }, | ||
489 | { | ||
490 | .name = "C9-BDW", | ||
491 | .desc = "MWAIT 0x50", | ||
492 | .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
493 | .exit_latency = 600, | ||
494 | .target_residency = 1800, | ||
495 | .enter = &intel_idle }, | ||
496 | { | ||
497 | .name = "C10-BDW", | ||
498 | .desc = "MWAIT 0x60", | ||
499 | .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
500 | .exit_latency = 2600, | ||
501 | .target_residency = 7700, | ||
502 | .enter = &intel_idle }, | ||
503 | { | ||
504 | .enter = NULL } | ||
505 | }; | ||
445 | 506 | ||
446 | static struct cpuidle_state atom_cstates[] = { | 507 | static struct cpuidle_state atom_cstates[] = { |
447 | { | 508 | { |
@@ -613,6 +674,7 @@ static const struct idle_cpu idle_cpu_snb = { | |||
613 | static const struct idle_cpu idle_cpu_byt = { | 674 | static const struct idle_cpu idle_cpu_byt = { |
614 | .state_table = byt_cstates, | 675 | .state_table = byt_cstates, |
615 | .disable_promotion_to_c1e = true, | 676 | .disable_promotion_to_c1e = true, |
677 | .byt_auto_demotion_disable_flag = true, | ||
616 | }; | 678 | }; |
617 | 679 | ||
618 | static const struct idle_cpu idle_cpu_ivb = { | 680 | static const struct idle_cpu idle_cpu_ivb = { |
@@ -630,6 +692,11 @@ static const struct idle_cpu idle_cpu_hsw = { | |||
630 | .disable_promotion_to_c1e = true, | 692 | .disable_promotion_to_c1e = true, |
631 | }; | 693 | }; |
632 | 694 | ||
695 | static const struct idle_cpu idle_cpu_bdw = { | ||
696 | .state_table = bdw_cstates, | ||
697 | .disable_promotion_to_c1e = true, | ||
698 | }; | ||
699 | |||
633 | static const struct idle_cpu idle_cpu_avn = { | 700 | static const struct idle_cpu idle_cpu_avn = { |
634 | .state_table = avn_cstates, | 701 | .state_table = avn_cstates, |
635 | .disable_promotion_to_c1e = true, | 702 | .disable_promotion_to_c1e = true, |
@@ -658,7 +725,10 @@ static const struct x86_cpu_id intel_idle_ids[] = { | |||
658 | ICPU(0x3f, idle_cpu_hsw), | 725 | ICPU(0x3f, idle_cpu_hsw), |
659 | ICPU(0x45, idle_cpu_hsw), | 726 | ICPU(0x45, idle_cpu_hsw), |
660 | ICPU(0x46, idle_cpu_hsw), | 727 | ICPU(0x46, idle_cpu_hsw), |
661 | ICPU(0x4D, idle_cpu_avn), | 728 | ICPU(0x4d, idle_cpu_avn), |
729 | ICPU(0x3d, idle_cpu_bdw), | ||
730 | ICPU(0x4f, idle_cpu_bdw), | ||
731 | ICPU(0x56, idle_cpu_bdw), | ||
662 | {} | 732 | {} |
663 | }; | 733 | }; |
664 | MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids); | 734 | MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids); |
@@ -814,6 +884,11 @@ static int __init intel_idle_cpuidle_driver_init(void) | |||
814 | if (icpu->auto_demotion_disable_flags) | 884 | if (icpu->auto_demotion_disable_flags) |
815 | on_each_cpu(auto_demotion_disable, NULL, 1); | 885 | on_each_cpu(auto_demotion_disable, NULL, 1); |
816 | 886 | ||
887 | if (icpu->byt_auto_demotion_disable_flag) { | ||
888 | wrmsrl(MSR_CC6_DEMOTION_POLICY_CONFIG, 0); | ||
889 | wrmsrl(MSR_MC6_DEMOTION_POLICY_CONFIG, 0); | ||
890 | } | ||
891 | |||
817 | if (icpu->disable_promotion_to_c1e) /* each-cpu is redundant */ | 892 | if (icpu->disable_promotion_to_c1e) /* each-cpu is redundant */ |
818 | on_each_cpu(c1e_promotion_disable, NULL, 1); | 893 | on_each_cpu(c1e_promotion_disable, NULL, 1); |
819 | 894 | ||
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index d0396af99fa0..5b1b807265a1 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c | |||
@@ -267,90 +267,90 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr) | |||
267 | /* | 267 | /* |
268 | * Example Format w/ field column widths: | 268 | * Example Format w/ field column widths: |
269 | * | 269 | * |
270 | * Package Core CPU Avg_MHz Bzy_MHz TSC_MHz SMI %Busy CPU_%c1 CPU_%c3 CPU_%c6 CPU_%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 PkgWatt CorWatt GFXWatt | 270 | * Package Core CPU Avg_MHz Bzy_MHz TSC_MHz SMI %Busy CPU_%c1 CPU_%c3 CPU_%c6 CPU_%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 PkgWatt CorWatt GFXWatt |
271 | * 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 | 271 | * 123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678 |
272 | */ | 272 | */ |
273 | 273 | ||
274 | void print_header(void) | 274 | void print_header(void) |
275 | { | 275 | { |
276 | if (show_pkg) | 276 | if (show_pkg) |
277 | outp += sprintf(outp, "Package "); | 277 | outp += sprintf(outp, " Package"); |
278 | if (show_core) | 278 | if (show_core) |
279 | outp += sprintf(outp, " Core "); | 279 | outp += sprintf(outp, " Core"); |
280 | if (show_cpu) | 280 | if (show_cpu) |
281 | outp += sprintf(outp, " CPU "); | 281 | outp += sprintf(outp, " CPU"); |
282 | if (has_aperf) | 282 | if (has_aperf) |
283 | outp += sprintf(outp, "Avg_MHz "); | 283 | outp += sprintf(outp, " Avg_MHz"); |
284 | if (do_nhm_cstates) | 284 | if (do_nhm_cstates) |
285 | outp += sprintf(outp, " %%Busy "); | 285 | outp += sprintf(outp, " %%Busy"); |
286 | if (has_aperf) | 286 | if (has_aperf) |
287 | outp += sprintf(outp, "Bzy_MHz "); | 287 | outp += sprintf(outp, " Bzy_MHz"); |
288 | outp += sprintf(outp, "TSC_MHz "); | 288 | outp += sprintf(outp, " TSC_MHz"); |
289 | if (do_smi) | 289 | if (do_smi) |
290 | outp += sprintf(outp, " SMI "); | 290 | outp += sprintf(outp, " SMI"); |
291 | if (extra_delta_offset32) | 291 | if (extra_delta_offset32) |
292 | outp += sprintf(outp, " count 0x%03X ", extra_delta_offset32); | 292 | outp += sprintf(outp, " count 0x%03X", extra_delta_offset32); |
293 | if (extra_delta_offset64) | 293 | if (extra_delta_offset64) |
294 | outp += sprintf(outp, " COUNT 0x%03X ", extra_delta_offset64); | 294 | outp += sprintf(outp, " COUNT 0x%03X", extra_delta_offset64); |
295 | if (extra_msr_offset32) | 295 | if (extra_msr_offset32) |
296 | outp += sprintf(outp, " MSR 0x%03X ", extra_msr_offset32); | 296 | outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset32); |
297 | if (extra_msr_offset64) | 297 | if (extra_msr_offset64) |
298 | outp += sprintf(outp, " MSR 0x%03X ", extra_msr_offset64); | 298 | outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset64); |
299 | if (do_nhm_cstates) | 299 | if (do_nhm_cstates) |
300 | outp += sprintf(outp, " CPU%%c1 "); | 300 | outp += sprintf(outp, " CPU%%c1"); |
301 | if (do_nhm_cstates && !do_slm_cstates) | 301 | if (do_nhm_cstates && !do_slm_cstates) |
302 | outp += sprintf(outp, " CPU%%c3 "); | 302 | outp += sprintf(outp, " CPU%%c3"); |
303 | if (do_nhm_cstates) | 303 | if (do_nhm_cstates) |
304 | outp += sprintf(outp, " CPU%%c6 "); | 304 | outp += sprintf(outp, " CPU%%c6"); |
305 | if (do_snb_cstates) | 305 | if (do_snb_cstates) |
306 | outp += sprintf(outp, " CPU%%c7 "); | 306 | outp += sprintf(outp, " CPU%%c7"); |
307 | 307 | ||
308 | if (do_dts) | 308 | if (do_dts) |
309 | outp += sprintf(outp, "CoreTmp "); | 309 | outp += sprintf(outp, " CoreTmp"); |
310 | if (do_ptm) | 310 | if (do_ptm) |
311 | outp += sprintf(outp, " PkgTmp "); | 311 | outp += sprintf(outp, " PkgTmp"); |
312 | 312 | ||
313 | if (do_snb_cstates) | 313 | if (do_snb_cstates) |
314 | outp += sprintf(outp, "Pkg%%pc2 "); | 314 | outp += sprintf(outp, " Pkg%%pc2"); |
315 | if (do_nhm_cstates && !do_slm_cstates) | 315 | if (do_nhm_cstates && !do_slm_cstates) |
316 | outp += sprintf(outp, "Pkg%%pc3 "); | 316 | outp += sprintf(outp, " Pkg%%pc3"); |
317 | if (do_nhm_cstates && !do_slm_cstates) | 317 | if (do_nhm_cstates && !do_slm_cstates) |
318 | outp += sprintf(outp, "Pkg%%pc6 "); | 318 | outp += sprintf(outp, " Pkg%%pc6"); |
319 | if (do_snb_cstates) | 319 | if (do_snb_cstates) |
320 | outp += sprintf(outp, "Pkg%%pc7 "); | 320 | outp += sprintf(outp, " Pkg%%pc7"); |
321 | if (do_c8_c9_c10) { | 321 | if (do_c8_c9_c10) { |
322 | outp += sprintf(outp, "Pkg%%pc8 "); | 322 | outp += sprintf(outp, " Pkg%%pc8"); |
323 | outp += sprintf(outp, "Pkg%%pc9 "); | 323 | outp += sprintf(outp, " Pkg%%pc9"); |
324 | outp += sprintf(outp, "Pk%%pc10 "); | 324 | outp += sprintf(outp, " Pk%%pc10"); |
325 | } | 325 | } |
326 | 326 | ||
327 | if (do_rapl && !rapl_joules) { | 327 | if (do_rapl && !rapl_joules) { |
328 | if (do_rapl & RAPL_PKG) | 328 | if (do_rapl & RAPL_PKG) |
329 | outp += sprintf(outp, "PkgWatt "); | 329 | outp += sprintf(outp, " PkgWatt"); |
330 | if (do_rapl & RAPL_CORES) | 330 | if (do_rapl & RAPL_CORES) |
331 | outp += sprintf(outp, "CorWatt "); | 331 | outp += sprintf(outp, " CorWatt"); |
332 | if (do_rapl & RAPL_GFX) | 332 | if (do_rapl & RAPL_GFX) |
333 | outp += sprintf(outp, "GFXWatt "); | 333 | outp += sprintf(outp, " GFXWatt"); |
334 | if (do_rapl & RAPL_DRAM) | 334 | if (do_rapl & RAPL_DRAM) |
335 | outp += sprintf(outp, "RAMWatt "); | 335 | outp += sprintf(outp, " RAMWatt"); |
336 | if (do_rapl & RAPL_PKG_PERF_STATUS) | 336 | if (do_rapl & RAPL_PKG_PERF_STATUS) |
337 | outp += sprintf(outp, " PKG_%% "); | 337 | outp += sprintf(outp, " PKG_%%"); |
338 | if (do_rapl & RAPL_DRAM_PERF_STATUS) | 338 | if (do_rapl & RAPL_DRAM_PERF_STATUS) |
339 | outp += sprintf(outp, " RAM_%% "); | 339 | outp += sprintf(outp, " RAM_%%"); |
340 | } else { | 340 | } else { |
341 | if (do_rapl & RAPL_PKG) | 341 | if (do_rapl & RAPL_PKG) |
342 | outp += sprintf(outp, " Pkg_J "); | 342 | outp += sprintf(outp, " Pkg_J"); |
343 | if (do_rapl & RAPL_CORES) | 343 | if (do_rapl & RAPL_CORES) |
344 | outp += sprintf(outp, " Cor_J "); | 344 | outp += sprintf(outp, " Cor_J"); |
345 | if (do_rapl & RAPL_GFX) | 345 | if (do_rapl & RAPL_GFX) |
346 | outp += sprintf(outp, " GFX_J "); | 346 | outp += sprintf(outp, " GFX_J"); |
347 | if (do_rapl & RAPL_DRAM) | 347 | if (do_rapl & RAPL_DRAM) |
348 | outp += sprintf(outp, " RAM_W "); | 348 | outp += sprintf(outp, " RAM_W"); |
349 | if (do_rapl & RAPL_PKG_PERF_STATUS) | 349 | if (do_rapl & RAPL_PKG_PERF_STATUS) |
350 | outp += sprintf(outp, " PKG_%% "); | 350 | outp += sprintf(outp, " PKG_%%"); |
351 | if (do_rapl & RAPL_DRAM_PERF_STATUS) | 351 | if (do_rapl & RAPL_DRAM_PERF_STATUS) |
352 | outp += sprintf(outp, " RAM_%% "); | 352 | outp += sprintf(outp, " RAM_%%"); |
353 | outp += sprintf(outp, " time "); | 353 | outp += sprintf(outp, " time"); |
354 | 354 | ||
355 | } | 355 | } |
356 | outp += sprintf(outp, "\n"); | 356 | outp += sprintf(outp, "\n"); |