Commit 40bca9db authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pm+acpi-4.6-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull power management and ACPI fixes from Rafael Wysocki:
 "Fixes for some issues discovered after recent changes and for some
  that have just been found lately regardless of those changes
  (intel_pstate, intel_idle, PM core, mailbox/pcc, turbostat) plus
  support for some new CPU models (intel_idle, Intel RAPL driver,
  turbostat) and documentation updates (intel_pstate, PM core).

  Specifics:

   - intel_pstate fixes for two issues exposed by the recent switch over
     from using timers and for one issue introduced during the 4.4 cycle
     plus new comments describing data structures used by the driver
     (Rafael Wysocki, Srinivas Pandruvada).

   - intel_idle fixes related to CPU offline/online (Richard Cochran).

   - intel_idle support (new CPU IDs and state definitions mostly) for
     Skylake-X and Kabylake processors (Len Brown).

   - PCC mailbox driver fix for an out-of-bounds memory access that may
     cause the kernel to panic() (Shanker Donthineni).

   - New (missing) CPU ID for one apparently overlooked Haswell model in
     the Intel RAPL power capping driver (Srinivas Pandruvada).

   - Fix for the PM core's wakeup IRQs framework to make it work after
     wakeup settings reconfiguration from sysfs (Grygorii Strashko).

   - Runtime PM documentation update to make it describe what needs to
     be done during device removal more precisely (Krzysztof Kozlowski).

   - Stale comment removal cleanup in the cpufreq-dt driver (Viresh
     Kumar).

   - turbostat utility fixes and support for Broxton, Skylake-X and
     Kabylake processors (Len Brown)"

* tag 'pm+acpi-4.6-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (28 commits)
  PM / wakeirq: fix wakeirq setting after wakup re-configuration from sysfs
  tools/power turbostat: work around RC6 counter wrap
  tools/power turbostat: initial KBL support
  tools/power turbostat: initial SKX support
  tools/power turbostat: decode BXT TSC frequency via CPUID
  tools/power turbostat: initial BXT support
  tools/power turbostat: print IRTL MSRs
  tools/power turbostat: SGX state should print only if --debug
  intel_idle: Add KBL support
  intel_idle: Add SKX support
  intel_idle: Clean up all registered devices on exit.
  intel_idle: Propagate hot plug errors.
  intel_idle: Don't overreact to a cpuidle registration failure.
  intel_idle: Setup the timer broadcast only on successful driver load.
  intel_idle: Avoid a double free of the per-CPU data.
  intel_idle: Fix dangling registration on error path.
  intel_idle: Fix deallocation order on the driver exit path.
  intel_idle: Remove redundant initialization calls.
  intel_idle: Fix a helper function's return value.
  intel_idle: remove useless return from void function.
  ...
parents 9ef11ceb 73659be7
...@@ -586,6 +586,10 @@ drivers to make their ->remove() callbacks avoid races with runtime PM directly, ...@@ -586,6 +586,10 @@ drivers to make their ->remove() callbacks avoid races with runtime PM directly,
but also it allows of more flexibility in the handling of devices during the but also it allows of more flexibility in the handling of devices during the
removal of their drivers. removal of their drivers.
Drivers in ->remove() callback should undo the runtime PM changes done
in ->probe(). Usually this means calling pm_runtime_disable(),
pm_runtime_dont_use_autosuspend() etc.
The user space can effectively disallow the driver of the device to power manage The user space can effectively disallow the driver of the device to power manage
it at run time by changing the value of its /sys/devices/.../power/control it at run time by changing the value of its /sys/devices/.../power/control
attribute to "on", which causes pm_runtime_forbid() to be called. In principle, attribute to "on", which causes pm_runtime_forbid() to be called. In principle,
......
...@@ -167,6 +167,14 @@ ...@@ -167,6 +167,14 @@
#define MSR_PKG_C9_RESIDENCY 0x00000631 #define MSR_PKG_C9_RESIDENCY 0x00000631
#define MSR_PKG_C10_RESIDENCY 0x00000632 #define MSR_PKG_C10_RESIDENCY 0x00000632
/* Interrupt Response Limit */
#define MSR_PKGC3_IRTL 0x0000060a
#define MSR_PKGC6_IRTL 0x0000060b
#define MSR_PKGC7_IRTL 0x0000060c
#define MSR_PKGC8_IRTL 0x00000633
#define MSR_PKGC9_IRTL 0x00000634
#define MSR_PKGC10_IRTL 0x00000635
/* Run Time Average Power Limiting (RAPL) Interface */ /* Run Time Average Power Limiting (RAPL) Interface */
#define MSR_RAPL_POWER_UNIT 0x00000606 #define MSR_RAPL_POWER_UNIT 0x00000606
......
...@@ -246,6 +246,8 @@ static int device_wakeup_attach(struct device *dev, struct wakeup_source *ws) ...@@ -246,6 +246,8 @@ static int device_wakeup_attach(struct device *dev, struct wakeup_source *ws)
return -EEXIST; return -EEXIST;
} }
dev->power.wakeup = ws; dev->power.wakeup = ws;
if (dev->power.wakeirq)
device_wakeup_attach_irq(dev, dev->power.wakeirq);
spin_unlock_irq(&dev->power.lock); spin_unlock_irq(&dev->power.lock);
return 0; return 0;
} }
......
...@@ -4,9 +4,6 @@ ...@@ -4,9 +4,6 @@
* Copyright (C) 2014 Linaro. * Copyright (C) 2014 Linaro.
* Viresh Kumar <viresh.kumar@linaro.org> * Viresh Kumar <viresh.kumar@linaro.org>
* *
* The OPP code in function set_target() is reused from
* drivers/cpufreq/omap-cpufreq.c
*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
......
This diff is collapsed.
...@@ -660,6 +660,35 @@ static struct cpuidle_state skl_cstates[] = { ...@@ -660,6 +660,35 @@ static struct cpuidle_state skl_cstates[] = {
.enter = NULL } .enter = NULL }
}; };
static struct cpuidle_state skx_cstates[] = {
{
.name = "C1-SKX",
.desc = "MWAIT 0x00",
.flags = MWAIT2flg(0x00),
.exit_latency = 2,
.target_residency = 2,
.enter = &intel_idle,
.enter_freeze = intel_idle_freeze, },
{
.name = "C1E-SKX",
.desc = "MWAIT 0x01",
.flags = MWAIT2flg(0x01),
.exit_latency = 10,
.target_residency = 20,
.enter = &intel_idle,
.enter_freeze = intel_idle_freeze, },
{
.name = "C6-SKX",
.desc = "MWAIT 0x20",
.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 133,
.target_residency = 600,
.enter = &intel_idle,
.enter_freeze = intel_idle_freeze, },
{
.enter = NULL }
};
static struct cpuidle_state atom_cstates[] = { static struct cpuidle_state atom_cstates[] = {
{ {
.name = "C1E-ATM", .name = "C1E-ATM",
...@@ -818,8 +847,11 @@ static int cpu_hotplug_notify(struct notifier_block *n, ...@@ -818,8 +847,11 @@ static int cpu_hotplug_notify(struct notifier_block *n,
* driver in this case * driver in this case
*/ */
dev = per_cpu_ptr(intel_idle_cpuidle_devices, hotcpu); dev = per_cpu_ptr(intel_idle_cpuidle_devices, hotcpu);
if (!dev->registered) if (dev->registered)
intel_idle_cpu_init(hotcpu); break;
if (intel_idle_cpu_init(hotcpu))
return NOTIFY_BAD;
break; break;
} }
...@@ -904,6 +936,10 @@ static const struct idle_cpu idle_cpu_skl = { ...@@ -904,6 +936,10 @@ static const struct idle_cpu idle_cpu_skl = {
.disable_promotion_to_c1e = true, .disable_promotion_to_c1e = true,
}; };
static const struct idle_cpu idle_cpu_skx = {
.state_table = skx_cstates,
.disable_promotion_to_c1e = true,
};
static const struct idle_cpu idle_cpu_avn = { static const struct idle_cpu idle_cpu_avn = {
.state_table = avn_cstates, .state_table = avn_cstates,
...@@ -945,6 +981,9 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = { ...@@ -945,6 +981,9 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = {
ICPU(0x56, idle_cpu_bdw), ICPU(0x56, idle_cpu_bdw),
ICPU(0x4e, idle_cpu_skl), ICPU(0x4e, idle_cpu_skl),
ICPU(0x5e, idle_cpu_skl), ICPU(0x5e, idle_cpu_skl),
ICPU(0x8e, idle_cpu_skl),
ICPU(0x9e, idle_cpu_skl),
ICPU(0x55, idle_cpu_skx),
ICPU(0x57, idle_cpu_knl), ICPU(0x57, idle_cpu_knl),
{} {}
}; };
...@@ -987,22 +1026,15 @@ static int __init intel_idle_probe(void) ...@@ -987,22 +1026,15 @@ static int __init intel_idle_probe(void)
icpu = (const struct idle_cpu *)id->driver_data; icpu = (const struct idle_cpu *)id->driver_data;
cpuidle_state_table = icpu->state_table; cpuidle_state_table = icpu->state_table;
if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */
lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE;
else
on_each_cpu(__setup_broadcast_timer, (void *)true, 1);
pr_debug(PREFIX "v" INTEL_IDLE_VERSION pr_debug(PREFIX "v" INTEL_IDLE_VERSION
" model 0x%X\n", boot_cpu_data.x86_model); " model 0x%X\n", boot_cpu_data.x86_model);
pr_debug(PREFIX "lapic_timer_reliable_states 0x%x\n",
lapic_timer_reliable_states);
return 0; return 0;
} }
/* /*
* intel_idle_cpuidle_devices_uninit() * intel_idle_cpuidle_devices_uninit()
* unregister, free cpuidle_devices * Unregisters the cpuidle devices.
*/ */
static void intel_idle_cpuidle_devices_uninit(void) static void intel_idle_cpuidle_devices_uninit(void)
{ {
...@@ -1013,9 +1045,6 @@ static void intel_idle_cpuidle_devices_uninit(void) ...@@ -1013,9 +1045,6 @@ static void intel_idle_cpuidle_devices_uninit(void)
dev = per_cpu_ptr(intel_idle_cpuidle_devices, i); dev = per_cpu_ptr(intel_idle_cpuidle_devices, i);
cpuidle_unregister_device(dev); cpuidle_unregister_device(dev);
} }
free_percpu(intel_idle_cpuidle_devices);
return;
} }
/* /*
...@@ -1111,7 +1140,7 @@ static void intel_idle_state_table_update(void) ...@@ -1111,7 +1140,7 @@ static void intel_idle_state_table_update(void)
* intel_idle_cpuidle_driver_init() * intel_idle_cpuidle_driver_init()
* allocate, initialize cpuidle_states * allocate, initialize cpuidle_states
*/ */
static int __init intel_idle_cpuidle_driver_init(void) static void __init intel_idle_cpuidle_driver_init(void)
{ {
int cstate; int cstate;
struct cpuidle_driver *drv = &intel_idle_driver; struct cpuidle_driver *drv = &intel_idle_driver;
...@@ -1163,18 +1192,10 @@ static int __init intel_idle_cpuidle_driver_init(void) ...@@ -1163,18 +1192,10 @@ static int __init intel_idle_cpuidle_driver_init(void)
drv->state_count += 1; drv->state_count += 1;
} }
if (icpu->auto_demotion_disable_flags)
on_each_cpu(auto_demotion_disable, NULL, 1);
if (icpu->byt_auto_demotion_disable_flag) { if (icpu->byt_auto_demotion_disable_flag) {
wrmsrl(MSR_CC6_DEMOTION_POLICY_CONFIG, 0); wrmsrl(MSR_CC6_DEMOTION_POLICY_CONFIG, 0);
wrmsrl(MSR_MC6_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);
return 0;
} }
...@@ -1193,7 +1214,6 @@ static int intel_idle_cpu_init(int cpu) ...@@ -1193,7 +1214,6 @@ static int intel_idle_cpu_init(int cpu)
if (cpuidle_register_device(dev)) { if (cpuidle_register_device(dev)) {
pr_debug(PREFIX "cpuidle_register_device %d failed!\n", cpu); pr_debug(PREFIX "cpuidle_register_device %d failed!\n", cpu);
intel_idle_cpuidle_devices_uninit();
return -EIO; return -EIO;
} }
...@@ -1218,40 +1238,51 @@ static int __init intel_idle_init(void) ...@@ -1218,40 +1238,51 @@ static int __init intel_idle_init(void)
if (retval) if (retval)
return retval; return retval;
intel_idle_cpuidle_devices = alloc_percpu(struct cpuidle_device);
if (intel_idle_cpuidle_devices == NULL)
return -ENOMEM;
intel_idle_cpuidle_driver_init(); intel_idle_cpuidle_driver_init();
retval = cpuidle_register_driver(&intel_idle_driver); retval = cpuidle_register_driver(&intel_idle_driver);
if (retval) { if (retval) {
struct cpuidle_driver *drv = cpuidle_get_driver(); struct cpuidle_driver *drv = cpuidle_get_driver();
printk(KERN_DEBUG PREFIX "intel_idle yielding to %s", printk(KERN_DEBUG PREFIX "intel_idle yielding to %s",
drv ? drv->name : "none"); drv ? drv->name : "none");
free_percpu(intel_idle_cpuidle_devices);
return retval; return retval;
} }
intel_idle_cpuidle_devices = alloc_percpu(struct cpuidle_device);
if (intel_idle_cpuidle_devices == NULL)
return -ENOMEM;
cpu_notifier_register_begin(); cpu_notifier_register_begin();
for_each_online_cpu(i) { for_each_online_cpu(i) {
retval = intel_idle_cpu_init(i); retval = intel_idle_cpu_init(i);
if (retval) { if (retval) {
intel_idle_cpuidle_devices_uninit();
cpu_notifier_register_done(); cpu_notifier_register_done();
cpuidle_unregister_driver(&intel_idle_driver); cpuidle_unregister_driver(&intel_idle_driver);
free_percpu(intel_idle_cpuidle_devices);
return retval; return retval;
} }
} }
__register_cpu_notifier(&cpu_hotplug_notifier); __register_cpu_notifier(&cpu_hotplug_notifier);
if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */
lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE;
else
on_each_cpu(__setup_broadcast_timer, (void *)true, 1);
cpu_notifier_register_done(); cpu_notifier_register_done();
pr_debug(PREFIX "lapic_timer_reliable_states 0x%x\n",
lapic_timer_reliable_states);
return 0; return 0;
} }
static void __exit intel_idle_exit(void) static void __exit intel_idle_exit(void)
{ {
intel_idle_cpuidle_devices_uninit(); struct cpuidle_device *dev;
cpuidle_unregister_driver(&intel_idle_driver); int i;
cpu_notifier_register_begin(); cpu_notifier_register_begin();
...@@ -1259,9 +1290,15 @@ static void __exit intel_idle_exit(void) ...@@ -1259,9 +1290,15 @@ static void __exit intel_idle_exit(void)
on_each_cpu(__setup_broadcast_timer, (void *)false, 1); on_each_cpu(__setup_broadcast_timer, (void *)false, 1);
__unregister_cpu_notifier(&cpu_hotplug_notifier); __unregister_cpu_notifier(&cpu_hotplug_notifier);
for_each_possible_cpu(i) {
dev = per_cpu_ptr(intel_idle_cpuidle_devices, i);
cpuidle_unregister_device(dev);
}
cpu_notifier_register_done(); cpu_notifier_register_done();
return; cpuidle_unregister_driver(&intel_idle_driver);
free_percpu(intel_idle_cpuidle_devices);
} }
module_init(intel_idle_init); module_init(intel_idle_init);
......
...@@ -361,8 +361,6 @@ static int __init acpi_pcc_probe(void) ...@@ -361,8 +361,6 @@ static int __init acpi_pcc_probe(void)
struct acpi_generic_address *db_reg; struct acpi_generic_address *db_reg;
struct acpi_pcct_hw_reduced *pcct_ss; struct acpi_pcct_hw_reduced *pcct_ss;
pcc_mbox_channels[i].con_priv = pcct_entry; pcc_mbox_channels[i].con_priv = pcct_entry;
pcct_entry = (struct acpi_subtable_header *)
((unsigned long) pcct_entry + pcct_entry->length);
/* If doorbell is in system memory cache the virt address */ /* If doorbell is in system memory cache the virt address */
pcct_ss = (struct acpi_pcct_hw_reduced *)pcct_entry; pcct_ss = (struct acpi_pcct_hw_reduced *)pcct_entry;
...@@ -370,6 +368,8 @@ static int __init acpi_pcc_probe(void) ...@@ -370,6 +368,8 @@ static int __init acpi_pcc_probe(void)
if (db_reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) if (db_reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
pcc_doorbell_vaddr[i] = acpi_os_ioremap(db_reg->address, pcc_doorbell_vaddr[i] = acpi_os_ioremap(db_reg->address,
db_reg->bit_width/8); db_reg->bit_width/8);
pcct_entry = (struct acpi_subtable_header *)
((unsigned long) pcct_entry + pcct_entry->length);
} }
pcc_mbox_ctrl.num_chans = count; pcc_mbox_ctrl.num_chans = count;
......
...@@ -1091,6 +1091,7 @@ static const struct x86_cpu_id rapl_ids[] __initconst = { ...@@ -1091,6 +1091,7 @@ static const struct x86_cpu_id rapl_ids[] __initconst = {
RAPL_CPU(0x3f, rapl_defaults_hsw_server),/* Haswell servers */ RAPL_CPU(0x3f, rapl_defaults_hsw_server),/* Haswell servers */
RAPL_CPU(0x4f, rapl_defaults_hsw_server),/* Broadwell servers */ RAPL_CPU(0x4f, rapl_defaults_hsw_server),/* Broadwell servers */
RAPL_CPU(0x45, rapl_defaults_core),/* Haswell ULT */ RAPL_CPU(0x45, rapl_defaults_core),/* Haswell ULT */
RAPL_CPU(0x46, rapl_defaults_core),/* Haswell */
RAPL_CPU(0x47, rapl_defaults_core),/* Broadwell-H */ RAPL_CPU(0x47, rapl_defaults_core),/* Broadwell-H */
RAPL_CPU(0x4E, rapl_defaults_core),/* Skylake */ RAPL_CPU(0x4E, rapl_defaults_core),/* Skylake */
RAPL_CPU(0x4C, rapl_defaults_cht),/* Braswell/Cherryview */ RAPL_CPU(0x4C, rapl_defaults_cht),/* Braswell/Cherryview */
......
...@@ -66,6 +66,8 @@ unsigned int do_slm_cstates; ...@@ -66,6 +66,8 @@ unsigned int do_slm_cstates;
unsigned int use_c1_residency_msr; unsigned int use_c1_residency_msr;
unsigned int has_aperf; unsigned int has_aperf;
unsigned int has_epb; unsigned int has_epb;
unsigned int do_irtl_snb;
unsigned int do_irtl_hsw;
unsigned int units = 1000000; /* MHz etc */ unsigned int units = 1000000; /* MHz etc */
unsigned int genuine_intel; unsigned int genuine_intel;
unsigned int has_invariant_tsc; unsigned int has_invariant_tsc;
...@@ -187,7 +189,7 @@ struct pkg_data { ...@@ -187,7 +189,7 @@ struct pkg_data {
unsigned long long pkg_any_core_c0; unsigned long long pkg_any_core_c0;
unsigned long long pkg_any_gfxe_c0; unsigned long long pkg_any_gfxe_c0;
unsigned long long pkg_both_core_gfxe_c0; unsigned long long pkg_both_core_gfxe_c0;
unsigned long long gfx_rc6_ms; long long gfx_rc6_ms;
unsigned int gfx_mhz; unsigned int gfx_mhz;
unsigned int package_id; unsigned int package_id;
unsigned int energy_pkg; /* MSR_PKG_ENERGY_STATUS */ unsigned int energy_pkg; /* MSR_PKG_ENERGY_STATUS */
...@@ -621,8 +623,14 @@ int format_counters(struct thread_data *t, struct core_data *c, ...@@ -621,8 +623,14 @@ int format_counters(struct thread_data *t, struct core_data *c,
outp += sprintf(outp, "%8d", p->pkg_temp_c); outp += sprintf(outp, "%8d", p->pkg_temp_c);
/* GFXrc6 */ /* GFXrc6 */
if (do_gfx_rc6_ms) if (do_gfx_rc6_ms) {
outp += sprintf(outp, "%8.2f", 100.0 * p->gfx_rc6_ms / 1000.0 / interval_float); if (p->gfx_rc6_ms == -1) { /* detect counter reset */
outp += sprintf(outp, " ***.**");
} else {
outp += sprintf(outp, "%8.2f",
p->gfx_rc6_ms / 10.0 / interval_float);
}
}
/* GFXMHz */ /* GFXMHz */
if (do_gfx_mhz) if (do_gfx_mhz)
...@@ -766,7 +774,12 @@ delta_package(struct pkg_data *new, struct pkg_data *old) ...@@ -766,7 +774,12 @@ delta_package(struct pkg_data *new, struct pkg_data *old)
old->pc10 = new->pc10 - old->pc10; old->pc10 = new->pc10 - old->pc10;
old->pkg_temp_c = new->pkg_temp_c; old->pkg_temp_c = new->pkg_temp_c;
/* flag an error when rc6 counter resets/wraps */
if (old->gfx_rc6_ms > new->gfx_rc6_ms)
old->gfx_rc6_ms = -1;
else
old->gfx_rc6_ms = new->gfx_rc6_ms - old->gfx_rc6_ms; old->gfx_rc6_ms = new->gfx_rc6_ms - old->gfx_rc6_ms;
old->gfx_mhz = new->gfx_mhz; old->gfx_mhz = new->gfx_mhz;
DELTA_WRAP32(new->energy_pkg, old->energy_pkg); DELTA_WRAP32(new->energy_pkg, old->energy_pkg);
...@@ -1296,6 +1309,7 @@ int hsw_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL__3, PCL__6, PCL__7, PCL_7S, ...@@ -1296,6 +1309,7 @@ int hsw_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL__3, PCL__6, PCL__7, PCL_7S,
int slv_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCLRSV, PCLRSV, PCL__4, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; int slv_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCLRSV, PCLRSV, PCL__4, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
int amt_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCL__2, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; int amt_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCL__2, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
int phi_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; int phi_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
int bxt_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
static void static void
...@@ -1579,6 +1593,47 @@ dump_config_tdp(void) ...@@ -1579,6 +1593,47 @@ dump_config_tdp(void)
fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1); fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1);
fprintf(outf, ")\n"); fprintf(outf, ")\n");
} }
unsigned int irtl_time_units[] = {1, 32, 1024, 32768, 1048576, 33554432, 0, 0 };
void print_irtl(void)
{
unsigned long long msr;
get_msr(base_cpu, MSR_PKGC3_IRTL, &msr);
fprintf(outf, "cpu%d: MSR_PKGC3_IRTL: 0x%08llx (", base_cpu, msr);
fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
(msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
get_msr(base_cpu, MSR_PKGC6_IRTL, &msr);
fprintf(outf, "cpu%d: MSR_PKGC6_IRTL: 0x%08llx (", base_cpu, msr);
fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
(msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
get_msr(base_cpu, MSR_PKGC7_IRTL, &msr);
fprintf(outf, "cpu%d: MSR_PKGC7_IRTL: 0x%08llx (", base_cpu, msr);
fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
(msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
if (!do_irtl_hsw)
return;
get_msr(base_cpu, MSR_PKGC8_IRTL, &msr);
fprintf(outf, "cpu%d: MSR_PKGC8_IRTL: 0x%08llx (", base_cpu, msr);
fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
(msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
get_msr(base_cpu, MSR_PKGC9_IRTL, &msr);
fprintf(outf, "cpu%d: MSR_PKGC9_IRTL: 0x%08llx (", base_cpu, msr);
fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
(msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
get_msr(base_cpu, MSR_PKGC10_IRTL, &msr);
fprintf(outf, "cpu%d: MSR_PKGC10_IRTL: 0x%08llx (", base_cpu, msr);
fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
(msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
}
void free_fd_percpu(void) void free_fd_percpu(void)
{ {
int i; int i;
...@@ -2144,6 +2199,9 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) ...@@ -2144,6 +2199,9 @@ int probe_nhm_msrs(unsigned int family, unsigned int model)
case 0x56: /* BDX-DE */ case 0x56: /* BDX-DE */
case 0x4E: /* SKL */ case 0x4E: /* SKL */
case 0x5E: /* SKL */ case 0x5E: /* SKL */
case 0x8E: /* KBL */
case 0x9E: /* KBL */
case 0x55: /* SKX */
pkg_cstate_limits = hsw_pkg_cstate_limits; pkg_cstate_limits = hsw_pkg_cstate_limits;
break; break;
case 0x37: /* BYT */ case 0x37: /* BYT */
...@@ -2156,6 +2214,9 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) ...@@ -2156,6 +2214,9 @@ int probe_nhm_msrs(unsigned int family, unsigned int model)
case 0x57: /* PHI */ case 0x57: /* PHI */
pkg_cstate_limits = phi_pkg_cstate_limits; pkg_cstate_limits = phi_pkg_cstate_limits;
break; break;
case 0x5C: /* BXT */
pkg_cstate_limits = bxt_pkg_cstate_limits;
break;
default: default:
return 0; return 0;
} }
...@@ -2248,6 +2309,9 @@ int has_config_tdp(unsigned int family, unsigned int model) ...@@ -2248,6 +2309,9 @@ int has_config_tdp(unsigned int family, unsigned int model)
case 0x56: /* BDX-DE */ case 0x56: /* BDX-DE */
case 0x4E: /* SKL */ case 0x4E: /* SKL */
case 0x5E: /* SKL */ case 0x5E: /* SKL */
case 0x8E: /* KBL */
case 0x9E: /* KBL */
case 0x55: /* SKX */
case 0x57: /* Knights Landing */ case 0x57: /* Knights Landing */
return 1; return 1;
...@@ -2585,13 +2649,19 @@ void rapl_probe(unsigned int family, unsigned int model) ...@@ -2585,13 +2649,19 @@ void rapl_probe(unsigned int family, unsigned int model)
case 0x47: /* BDW */ case 0x47: /* BDW */
do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO; do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO;
break; break;
case 0x5C: /* BXT */
do_rapl = RAPL_PKG | RAPL_PKG_POWER_INFO;
break;
case 0x4E: /* SKL */ case 0x4E: /* SKL */
case 0x5E: /* SKL */ case 0x5E: /* SKL */
case 0x8E: /* KBL */
case 0x9E: /* KBL */
do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO; do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO;
break; break;
case 0x3F: /* HSX */ case 0x3F: /* HSX */
case 0x4F: /* BDX */ case 0x4F: /* BDX */
case 0x56: /* BDX-DE */ case 0x56: /* BDX-DE */
case 0x55: /* SKX */
case 0x57: /* KNL */ case 0x57: /* KNL */
do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO; do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO;
break; break;
...@@ -2871,6 +2941,10 @@ int has_snb_msrs(unsigned int family, unsigned int model) ...@@ -2871,6 +2941,10 @@ int has_snb_msrs(unsigned int family, unsigned int model)
case 0x56: /* BDX-DE */ case 0x56: /* BDX-DE */
case 0x4E: /* SKL */ case 0x4E: /* SKL */
case 0x5E: /* SKL */ case 0x5E: /* SKL */
case 0x8E: /* KBL */
case 0x9E: /* KBL */
case 0x55: /* SKX */
case 0x5C: /* BXT */
return 1; return 1;
} }
return 0; return 0;
...@@ -2882,6 +2956,11 @@ int has_snb_msrs(unsigned int family, unsigned int model) ...@@ -2882,6 +2956,11 @@ int has_snb_msrs(unsigned int family, unsigned int model)
* MSR_PKG_C8_RESIDENCY 0x00000630 * MSR_PKG_C8_RESIDENCY 0x00000630
* MSR_PKG_C9_RESIDENCY 0x00000631 * MSR_PKG_C9_RESIDENCY 0x00000631
* MSR_PKG_C10_RESIDENCY 0x00000632 * MSR_PKG_C10_RESIDENCY 0x00000632
*
* MSR_PKGC8_IRTL 0x00000633
* MSR_PKGC9_IRTL 0x00000634
* MSR_PKGC10_IRTL 0x00000635
*
*/ */
int has_hsw_msrs(unsigned int family, unsigned int model) int has_hsw_msrs(unsigned int family, unsigned int model)
{ {
...@@ -2893,6 +2972,9 @@ int has_hsw_msrs(unsigned int family, unsigned int model) ...@@ -2893,6 +2972,9 @@ int has_hsw_msrs(unsigned int family, unsigned int model)
case 0x3D: /* BDW */ case 0x3D: /* BDW */
case 0x4E: /* SKL */ case 0x4E: /* SKL */
case 0x5E: /* SKL */ case 0x5E: /* SKL */
case 0x8E: /* KBL */
case 0x9E: /* KBL */
case 0x5C: /* BXT */
return 1; return 1;
} }
return 0; return 0;
...@@ -2914,6 +2996,8 @@ int has_skl_msrs(unsigned int family, unsigned int model) ...@@ -2914,6 +2996,8 @@ int has_skl_msrs(unsigned int family, unsigned int model)
switch (model) { switch (model) {
case 0x4E: /* SKL */ case 0x4E: /* SKL */
case 0x5E: /* SKL */ case 0x5E: /* SKL */
case 0x8E: /* KBL */
case 0x9E: /* KBL */
return 1; return 1;
} }
return 0; return 0;
...@@ -3187,7 +3271,7 @@ void process_cpuid() ...@@ -3187,7 +3271,7 @@ void process_cpuid()
if (debug) if (debug)
decode_misc_enable_msr(); decode_misc_enable_msr();
if (max_level >= 0x7) { if (max_level >= 0x7 && debug) {
int has_sgx; int has_sgx;
ecx = 0; ecx = 0;
...@@ -3221,7 +3305,15 @@ void process_cpuid() ...@@ -3221,7 +3305,15 @@ void process_cpuid()
switch(model) { switch(model) {
case 0x4E: /* SKL */ case 0x4E: /* SKL */
case 0x5E: /* SKL */ case 0x5E: /* SKL */
crystal_hz = 24000000; /* 24 MHz */ case 0x8E: /* KBL */
case 0x9E: /* KBL */
crystal_hz = 24000000; /* 24.0 MHz */
break;
case 0x55: /* SKX */
crystal_hz = 25000000; /* 25.0 MHz */
break;
case 0x5C: /* BXT */
crystal_hz = 19200000; /* 19.2 MHz */
break; break;
default: default:
crystal_hz = 0; crystal_hz = 0;
...@@ -3254,11 +3346,13 @@ void process_cpuid() ...@@ -3254,11 +3346,13 @@ void process_cpuid()
do_nhm_platform_info = do_nhm_cstates = do_smi = probe_nhm_msrs(family, model); do_nhm_platform_info = do_nhm_cstates = do_smi = probe_nhm_msrs(family, model);
do_snb_cstates = has_snb_msrs(family, model); do_snb_cstates = has_snb_msrs(family, model);
do_irtl_snb = has_snb_msrs(family, model);
do_pc2 = do_snb_cstates && (pkg_cstate_limit >= PCL__2); do_pc2 = do_snb_cstates && (pkg_cstate_limit >= PCL__2);
do_pc3 = (pkg_cstate_limit >= PCL__3); do_pc3 = (pkg_cstate_limit >= PCL__3);
do_pc6 = (pkg_cstate_limit >= PCL__6); do_pc6 = (pkg_cstate_limit >= PCL__6);
do_pc7 = do_snb_cstates && (pkg_cstate_limit >= PCL__7); do_pc7 = do_snb_cstates && (pkg_cstate_limit >= PCL__7);
do_c8_c9_c10 = has_hsw_msrs(family, model); do_c8_c9_c10 = has_hsw_msrs(family, model);
do_irtl_hsw = has_hsw_msrs(family, model);
do_skl_residency = has_skl_msrs(family, model); do_skl_residency = has_skl_msrs(family, model);
do_slm_cstates = is_slm(family, model); do_slm_cstates = is_slm(family, model);
do_knl_cstates = is_knl(family, model); do_knl_cstates = is_knl(family, model);
...@@ -3564,6 +3658,9 @@ void turbostat_init() ...@@ -3564,6 +3658,9 @@ void turbostat_init()
if (debug) if (debug)
for_all_cpus(print_thermal, ODD_COUNTERS); for_all_cpus(print_thermal, ODD_COUNTERS);
if (debug && do_irtl_snb)
print_irtl();
} }
int fork_it(char **argv) int fork_it(char **argv)
...@@ -3629,7 +3726,7 @@ int get_and_dump_counters(void) ...@@ -3629,7 +3726,7 @@ int get_and_dump_counters(void)
} }
void print_version() { void print_version() {
fprintf(outf, "turbostat version 4.11 27 Feb 2016" fprintf(outf, "turbostat version 4.12 5 Apr 2016"
" - Len Brown <lenb@kernel.org>\n"); " - Len Brown <lenb@kernel.org>\n");
} }
......
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