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 @@ #define MSR_CORE_C1_RES 0x00000660 +#define MSR_CC6_DEMOTION_POLICY_CONFIG 0x00000668 +#define MSR_MC6_DEMOTION_POLICY_CONFIG 0x00000669 + #define MSR_AMD64_MC0_MASK 0xc0010044 #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 { * Indicate which enable bits to clear here. */ unsigned long auto_demotion_disable_flags; + bool byt_auto_demotion_disable_flag; bool disable_promotion_to_c1e; }; @@ -442,6 +443,66 @@ static struct cpuidle_state hsw_cstates[] = { { .enter = NULL } }; +static struct cpuidle_state bdw_cstates[] = { + { + .name = "C1-BDW", + .desc = "MWAIT 0x00", + .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID, + .exit_latency = 2, + .target_residency = 2, + .enter = &intel_idle }, + { + .name = "C1E-BDW", + .desc = "MWAIT 0x01", + .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_TIME_VALID, + .exit_latency = 10, + .target_residency = 20, + .enter = &intel_idle }, + { + .name = "C3-BDW", + .desc = "MWAIT 0x10", + .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, + .exit_latency = 40, + .target_residency = 100, + .enter = &intel_idle }, + { + .name = "C6-BDW", + .desc = "MWAIT 0x20", + .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, + .exit_latency = 133, + .target_residency = 400, + .enter = &intel_idle }, + { + .name = "C7s-BDW", + .desc = "MWAIT 0x32", + .flags = MWAIT2flg(0x32) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, + .exit_latency = 166, + .target_residency = 500, + .enter = &intel_idle }, + { + .name = "C8-BDW", + .desc = "MWAIT 0x40", + .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, + .exit_latency = 300, + .target_residency = 900, + .enter = &intel_idle }, + { + .name = "C9-BDW", + .desc = "MWAIT 0x50", + .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, + .exit_latency = 600, + .target_residency = 1800, + .enter = &intel_idle }, + { + .name = "C10-BDW", + .desc = "MWAIT 0x60", + .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, + .exit_latency = 2600, + .target_residency = 7700, + .enter = &intel_idle }, + { + .enter = NULL } +}; static struct cpuidle_state atom_cstates[] = { { @@ -613,6 +674,7 @@ static const struct idle_cpu idle_cpu_snb = { static const struct idle_cpu idle_cpu_byt = { .state_table = byt_cstates, .disable_promotion_to_c1e = true, + .byt_auto_demotion_disable_flag = true, }; static const struct idle_cpu idle_cpu_ivb = { @@ -630,6 +692,11 @@ static const struct idle_cpu idle_cpu_hsw = { .disable_promotion_to_c1e = true, }; +static const struct idle_cpu idle_cpu_bdw = { + .state_table = bdw_cstates, + .disable_promotion_to_c1e = true, +}; + static const struct idle_cpu idle_cpu_avn = { .state_table = avn_cstates, .disable_promotion_to_c1e = true, @@ -658,7 +725,10 @@ static const struct x86_cpu_id intel_idle_ids[] = { ICPU(0x3f, idle_cpu_hsw), ICPU(0x45, idle_cpu_hsw), ICPU(0x46, idle_cpu_hsw), - ICPU(0x4D, idle_cpu_avn), + ICPU(0x4d, idle_cpu_avn), + ICPU(0x3d, idle_cpu_bdw), + ICPU(0x4f, idle_cpu_bdw), + ICPU(0x56, idle_cpu_bdw), {} }; MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids); @@ -814,6 +884,11 @@ static int __init intel_idle_cpuidle_driver_init(void) if (icpu->auto_demotion_disable_flags) on_each_cpu(auto_demotion_disable, NULL, 1); + if (icpu->byt_auto_demotion_disable_flag) { + wrmsrl(MSR_CC6_DEMOTION_POLICY_CONFIG, 0); + wrmsrl(MSR_MC6_DEMOTION_POLICY_CONFIG, 0); + } + if (icpu->disable_promotion_to_c1e) /* each-cpu is redundant */ on_each_cpu(c1e_promotion_disable, NULL, 1); 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) /* * Example Format w/ field column widths: * - * 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 - * 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 + * 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 + * 123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678 */ void print_header(void) { if (show_pkg) - outp += sprintf(outp, "Package "); + outp += sprintf(outp, " Package"); if (show_core) - outp += sprintf(outp, " Core "); + outp += sprintf(outp, " Core"); if (show_cpu) - outp += sprintf(outp, " CPU "); + outp += sprintf(outp, " CPU"); if (has_aperf) - outp += sprintf(outp, "Avg_MHz "); + outp += sprintf(outp, " Avg_MHz"); if (do_nhm_cstates) - outp += sprintf(outp, " %%Busy "); + outp += sprintf(outp, " %%Busy"); if (has_aperf) - outp += sprintf(outp, "Bzy_MHz "); - outp += sprintf(outp, "TSC_MHz "); + outp += sprintf(outp, " Bzy_MHz"); + outp += sprintf(outp, " TSC_MHz"); if (do_smi) - outp += sprintf(outp, " SMI "); + outp += sprintf(outp, " SMI"); if (extra_delta_offset32) - outp += sprintf(outp, " count 0x%03X ", extra_delta_offset32); + outp += sprintf(outp, " count 0x%03X", extra_delta_offset32); if (extra_delta_offset64) - outp += sprintf(outp, " COUNT 0x%03X ", extra_delta_offset64); + outp += sprintf(outp, " COUNT 0x%03X", extra_delta_offset64); if (extra_msr_offset32) - outp += sprintf(outp, " MSR 0x%03X ", extra_msr_offset32); + outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset32); if (extra_msr_offset64) - outp += sprintf(outp, " MSR 0x%03X ", extra_msr_offset64); + outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset64); if (do_nhm_cstates) - outp += sprintf(outp, " CPU%%c1 "); + outp += sprintf(outp, " CPU%%c1"); if (do_nhm_cstates && !do_slm_cstates) - outp += sprintf(outp, " CPU%%c3 "); + outp += sprintf(outp, " CPU%%c3"); if (do_nhm_cstates) - outp += sprintf(outp, " CPU%%c6 "); + outp += sprintf(outp, " CPU%%c6"); if (do_snb_cstates) - outp += sprintf(outp, " CPU%%c7 "); + outp += sprintf(outp, " CPU%%c7"); if (do_dts) - outp += sprintf(outp, "CoreTmp "); + outp += sprintf(outp, " CoreTmp"); if (do_ptm) - outp += sprintf(outp, " PkgTmp "); + outp += sprintf(outp, " PkgTmp"); if (do_snb_cstates) - outp += sprintf(outp, "Pkg%%pc2 "); + outp += sprintf(outp, " Pkg%%pc2"); if (do_nhm_cstates && !do_slm_cstates) - outp += sprintf(outp, "Pkg%%pc3 "); + outp += sprintf(outp, " Pkg%%pc3"); if (do_nhm_cstates && !do_slm_cstates) - outp += sprintf(outp, "Pkg%%pc6 "); + outp += sprintf(outp, " Pkg%%pc6"); if (do_snb_cstates) - outp += sprintf(outp, "Pkg%%pc7 "); + outp += sprintf(outp, " Pkg%%pc7"); if (do_c8_c9_c10) { - outp += sprintf(outp, "Pkg%%pc8 "); - outp += sprintf(outp, "Pkg%%pc9 "); - outp += sprintf(outp, "Pk%%pc10 "); + outp += sprintf(outp, " Pkg%%pc8"); + outp += sprintf(outp, " Pkg%%pc9"); + outp += sprintf(outp, " Pk%%pc10"); } if (do_rapl && !rapl_joules) { if (do_rapl & RAPL_PKG) - outp += sprintf(outp, "PkgWatt "); + outp += sprintf(outp, " PkgWatt"); if (do_rapl & RAPL_CORES) - outp += sprintf(outp, "CorWatt "); + outp += sprintf(outp, " CorWatt"); if (do_rapl & RAPL_GFX) - outp += sprintf(outp, "GFXWatt "); + outp += sprintf(outp, " GFXWatt"); if (do_rapl & RAPL_DRAM) - outp += sprintf(outp, "RAMWatt "); + outp += sprintf(outp, " RAMWatt"); if (do_rapl & RAPL_PKG_PERF_STATUS) - outp += sprintf(outp, " PKG_%% "); + outp += sprintf(outp, " PKG_%%"); if (do_rapl & RAPL_DRAM_PERF_STATUS) - outp += sprintf(outp, " RAM_%% "); + outp += sprintf(outp, " RAM_%%"); } else { if (do_rapl & RAPL_PKG) - outp += sprintf(outp, " Pkg_J "); + outp += sprintf(outp, " Pkg_J"); if (do_rapl & RAPL_CORES) - outp += sprintf(outp, " Cor_J "); + outp += sprintf(outp, " Cor_J"); if (do_rapl & RAPL_GFX) - outp += sprintf(outp, " GFX_J "); + outp += sprintf(outp, " GFX_J"); if (do_rapl & RAPL_DRAM) - outp += sprintf(outp, " RAM_W "); + outp += sprintf(outp, " RAM_W"); if (do_rapl & RAPL_PKG_PERF_STATUS) - outp += sprintf(outp, " PKG_%% "); + outp += sprintf(outp, " PKG_%%"); if (do_rapl & RAPL_DRAM_PERF_STATUS) - outp += sprintf(outp, " RAM_%% "); - outp += sprintf(outp, " time "); + outp += sprintf(outp, " RAM_%%"); + outp += sprintf(outp, " time"); } outp += sprintf(outp, "\n"); |