Commit ac4e0109 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux

Pull idle update from Len Brown:
 "Add support for new Haswell-ULT CPU idle power states"

* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux:
  intel_idle: initial C8, C9, C10 support
  tools/power turbostat: display C8, C9, C10 residency
parents c4cc75c3 86239ceb
...@@ -120,6 +120,9 @@ ...@@ -120,6 +120,9 @@
#define MSR_CORE_C6_RESIDENCY 0x000003fd #define MSR_CORE_C6_RESIDENCY 0x000003fd
#define MSR_CORE_C7_RESIDENCY 0x000003fe #define MSR_CORE_C7_RESIDENCY 0x000003fe
#define MSR_PKG_C2_RESIDENCY 0x0000060d #define MSR_PKG_C2_RESIDENCY 0x0000060d
#define MSR_PKG_C8_RESIDENCY 0x00000630
#define MSR_PKG_C9_RESIDENCY 0x00000631
#define MSR_PKG_C10_RESIDENCY 0x00000632
/* Run Time Average Power Limiting (RAPL) Interface */ /* Run Time Average Power Limiting (RAPL) Interface */
......
...@@ -272,6 +272,27 @@ static struct cpuidle_state hsw_cstates[CPUIDLE_STATE_MAX] = { ...@@ -272,6 +272,27 @@ static struct cpuidle_state hsw_cstates[CPUIDLE_STATE_MAX] = {
.exit_latency = 166, .exit_latency = 166,
.target_residency = 500, .target_residency = 500,
.enter = &intel_idle }, .enter = &intel_idle },
{
.name = "C8-HSW",
.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-HSW",
.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-HSW",
.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 } .enter = NULL }
}; };
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/hrtimer.h> #include <linux/hrtimer.h>
#define CPUIDLE_STATE_MAX 8 #define CPUIDLE_STATE_MAX 10
#define CPUIDLE_NAME_LEN 16 #define CPUIDLE_NAME_LEN 16
#define CPUIDLE_DESC_LEN 32 #define CPUIDLE_DESC_LEN 32
......
...@@ -46,6 +46,7 @@ unsigned int skip_c0; ...@@ -46,6 +46,7 @@ unsigned int skip_c0;
unsigned int skip_c1; unsigned int skip_c1;
unsigned int do_nhm_cstates; unsigned int do_nhm_cstates;
unsigned int do_snb_cstates; unsigned int do_snb_cstates;
unsigned int do_c8_c9_c10;
unsigned int has_aperf; unsigned int has_aperf;
unsigned int has_epb; unsigned int has_epb;
unsigned int units = 1000000000; /* Ghz etc */ unsigned int units = 1000000000; /* Ghz etc */
...@@ -120,6 +121,9 @@ struct pkg_data { ...@@ -120,6 +121,9 @@ struct pkg_data {
unsigned long long pc3; unsigned long long pc3;
unsigned long long pc6; unsigned long long pc6;
unsigned long long pc7; unsigned long long pc7;
unsigned long long pc8;
unsigned long long pc9;
unsigned long long pc10;
unsigned int package_id; unsigned int package_id;
unsigned int energy_pkg; /* MSR_PKG_ENERGY_STATUS */ unsigned int energy_pkg; /* MSR_PKG_ENERGY_STATUS */
unsigned int energy_dram; /* MSR_DRAM_ENERGY_STATUS */ unsigned int energy_dram; /* MSR_DRAM_ENERGY_STATUS */
...@@ -282,6 +286,11 @@ void print_header(void) ...@@ -282,6 +286,11 @@ void print_header(void)
outp += sprintf(outp, " %%pc6"); outp += sprintf(outp, " %%pc6");
if (do_snb_cstates) if (do_snb_cstates)
outp += sprintf(outp, " %%pc7"); outp += sprintf(outp, " %%pc7");
if (do_c8_c9_c10) {
outp += sprintf(outp, " %%pc8");
outp += sprintf(outp, " %%pc9");
outp += sprintf(outp, " %%pc10");
}
if (do_rapl & RAPL_PKG) if (do_rapl & RAPL_PKG)
outp += sprintf(outp, " Pkg_W"); outp += sprintf(outp, " Pkg_W");
...@@ -336,6 +345,9 @@ int dump_counters(struct thread_data *t, struct core_data *c, ...@@ -336,6 +345,9 @@ int dump_counters(struct thread_data *t, struct core_data *c,
fprintf(stderr, "pc3: %016llX\n", p->pc3); fprintf(stderr, "pc3: %016llX\n", p->pc3);
fprintf(stderr, "pc6: %016llX\n", p->pc6); fprintf(stderr, "pc6: %016llX\n", p->pc6);
fprintf(stderr, "pc7: %016llX\n", p->pc7); fprintf(stderr, "pc7: %016llX\n", p->pc7);
fprintf(stderr, "pc8: %016llX\n", p->pc8);
fprintf(stderr, "pc9: %016llX\n", p->pc9);
fprintf(stderr, "pc10: %016llX\n", p->pc10);
fprintf(stderr, "Joules PKG: %0X\n", p->energy_pkg); fprintf(stderr, "Joules PKG: %0X\n", p->energy_pkg);
fprintf(stderr, "Joules COR: %0X\n", p->energy_cores); fprintf(stderr, "Joules COR: %0X\n", p->energy_cores);
fprintf(stderr, "Joules GFX: %0X\n", p->energy_gfx); fprintf(stderr, "Joules GFX: %0X\n", p->energy_gfx);
...@@ -493,6 +505,11 @@ int format_counters(struct thread_data *t, struct core_data *c, ...@@ -493,6 +505,11 @@ int format_counters(struct thread_data *t, struct core_data *c,
outp += sprintf(outp, " %6.2f", 100.0 * p->pc6/t->tsc); outp += sprintf(outp, " %6.2f", 100.0 * p->pc6/t->tsc);
if (do_snb_cstates) if (do_snb_cstates)
outp += sprintf(outp, " %6.2f", 100.0 * p->pc7/t->tsc); outp += sprintf(outp, " %6.2f", 100.0 * p->pc7/t->tsc);
if (do_c8_c9_c10) {
outp += sprintf(outp, " %6.2f", 100.0 * p->pc8/t->tsc);
outp += sprintf(outp, " %6.2f", 100.0 * p->pc9/t->tsc);
outp += sprintf(outp, " %6.2f", 100.0 * p->pc10/t->tsc);
}
/* /*
* If measurement interval exceeds minimum RAPL Joule Counter range, * If measurement interval exceeds minimum RAPL Joule Counter range,
...@@ -569,6 +586,9 @@ delta_package(struct pkg_data *new, struct pkg_data *old) ...@@ -569,6 +586,9 @@ delta_package(struct pkg_data *new, struct pkg_data *old)
old->pc3 = new->pc3 - old->pc3; old->pc3 = new->pc3 - old->pc3;
old->pc6 = new->pc6 - old->pc6; old->pc6 = new->pc6 - old->pc6;
old->pc7 = new->pc7 - old->pc7; old->pc7 = new->pc7 - old->pc7;
old->pc8 = new->pc8 - old->pc8;
old->pc9 = new->pc9 - old->pc9;
old->pc10 = new->pc10 - old->pc10;
old->pkg_temp_c = new->pkg_temp_c; old->pkg_temp_c = new->pkg_temp_c;
DELTA_WRAP32(new->energy_pkg, old->energy_pkg); DELTA_WRAP32(new->energy_pkg, old->energy_pkg);
...@@ -702,6 +722,9 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data ...@@ -702,6 +722,9 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data
p->pc3 = 0; p->pc3 = 0;
p->pc6 = 0; p->pc6 = 0;
p->pc7 = 0; p->pc7 = 0;
p->pc8 = 0;
p->pc9 = 0;
p->pc10 = 0;
p->energy_pkg = 0; p->energy_pkg = 0;
p->energy_dram = 0; p->energy_dram = 0;
...@@ -740,6 +763,9 @@ int sum_counters(struct thread_data *t, struct core_data *c, ...@@ -740,6 +763,9 @@ int sum_counters(struct thread_data *t, struct core_data *c,
average.packages.pc3 += p->pc3; average.packages.pc3 += p->pc3;
average.packages.pc6 += p->pc6; average.packages.pc6 += p->pc6;
average.packages.pc7 += p->pc7; average.packages.pc7 += p->pc7;
average.packages.pc8 += p->pc8;
average.packages.pc9 += p->pc9;
average.packages.pc10 += p->pc10;
average.packages.energy_pkg += p->energy_pkg; average.packages.energy_pkg += p->energy_pkg;
average.packages.energy_dram += p->energy_dram; average.packages.energy_dram += p->energy_dram;
...@@ -781,6 +807,10 @@ void compute_average(struct thread_data *t, struct core_data *c, ...@@ -781,6 +807,10 @@ void compute_average(struct thread_data *t, struct core_data *c,
average.packages.pc3 /= topo.num_packages; average.packages.pc3 /= topo.num_packages;
average.packages.pc6 /= topo.num_packages; average.packages.pc6 /= topo.num_packages;
average.packages.pc7 /= topo.num_packages; average.packages.pc7 /= topo.num_packages;
average.packages.pc8 /= topo.num_packages;
average.packages.pc9 /= topo.num_packages;
average.packages.pc10 /= topo.num_packages;
} }
static unsigned long long rdtsc(void) static unsigned long long rdtsc(void)
...@@ -880,6 +910,14 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) ...@@ -880,6 +910,14 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
if (get_msr(cpu, MSR_PKG_C7_RESIDENCY, &p->pc7)) if (get_msr(cpu, MSR_PKG_C7_RESIDENCY, &p->pc7))
return -12; return -12;
} }
if (do_c8_c9_c10) {
if (get_msr(cpu, MSR_PKG_C8_RESIDENCY, &p->pc8))
return -13;
if (get_msr(cpu, MSR_PKG_C9_RESIDENCY, &p->pc9))
return -13;
if (get_msr(cpu, MSR_PKG_C10_RESIDENCY, &p->pc10))
return -13;
}
if (do_rapl & RAPL_PKG) { if (do_rapl & RAPL_PKG) {
if (get_msr(cpu, MSR_PKG_ENERGY_STATUS, &msr)) if (get_msr(cpu, MSR_PKG_ENERGY_STATUS, &msr))
return -13; return -13;
...@@ -1762,6 +1800,19 @@ int is_snb(unsigned int family, unsigned int model) ...@@ -1762,6 +1800,19 @@ int is_snb(unsigned int family, unsigned int model)
return 0; return 0;
} }
int has_c8_c9_c10(unsigned int family, unsigned int model)
{
if (!genuine_intel)
return 0;
switch (model) {
case 0x45:
return 1;
}
return 0;
}
double discover_bclk(unsigned int family, unsigned int model) double discover_bclk(unsigned int family, unsigned int model)
{ {
if (is_snb(family, model)) if (is_snb(family, model))
...@@ -1918,6 +1969,7 @@ void check_cpuid() ...@@ -1918,6 +1969,7 @@ void check_cpuid()
do_nhm_cstates = genuine_intel; /* all Intel w/ non-stop TSC have NHM counters */ do_nhm_cstates = genuine_intel; /* all Intel w/ non-stop TSC have NHM counters */
do_smi = do_nhm_cstates; do_smi = do_nhm_cstates;
do_snb_cstates = is_snb(family, model); do_snb_cstates = is_snb(family, model);
do_c8_c9_c10 = has_c8_c9_c10(family, model);
bclk = discover_bclk(family, model); bclk = discover_bclk(family, model);
do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model); do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model);
...@@ -2279,7 +2331,7 @@ int main(int argc, char **argv) ...@@ -2279,7 +2331,7 @@ int main(int argc, char **argv)
cmdline(argc, argv); cmdline(argc, argv);
if (verbose) if (verbose)
fprintf(stderr, "turbostat v3.3 March 15, 2013" fprintf(stderr, "turbostat v3.4 April 17, 2013"
" - Len Brown <lenb@kernel.org>\n"); " - Len Brown <lenb@kernel.org>\n");
turbostat_init(); turbostat_init();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment