Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1372822 > unrolled thread
| Started by | Len Brown <lenb@kernel.org> |
|---|---|
| First post | 2016-04-06 23:10 +0200 |
| Last post | 2016-04-06 23:10 +0200 |
| Articles | 9 — 1 participant |
Back to article view | Back to linux.kernel
[PATCH 0/13] intel_idle patches ready for upstream Len Brown <lenb@kernel.org> - 2016-04-06 23:10 +0200
[PATCH 13/13] intel_idle: Add KBL support Len Brown <lenb@kernel.org> - 2016-04-06 23:10 +0200
[PATCH 08/13] intel_idle: Setup the timer broadcast only on successful driver load. Len Brown <lenb@kernel.org> - 2016-04-06 23:10 +0200
[PATCH 07/13] intel_idle: Avoid a double free of the per-CPU data. Len Brown <lenb@kernel.org> - 2016-04-06 23:10 +0200
[PATCH 02/13] intel_idle: remove useless return from void function. Len Brown <lenb@kernel.org> - 2016-04-06 23:10 +0200
[PATCH 04/13] intel_idle: Remove redundant initialization calls. Len Brown <lenb@kernel.org> - 2016-04-06 23:10 +0200
[PATCH 06/13] intel_idle: Fix dangling registration on error path. Len Brown <lenb@kernel.org> - 2016-04-06 23:10 +0200
[PATCH 01/13] intel_idle: add BXT support Len Brown <lenb@kernel.org> - 2016-04-06 23:10 +0200
[PATCH 09/13] intel_idle: Don't overreact to a cpuidle registration failure. Len Brown <lenb@kernel.org> - 2016-04-06 23:10 +0200
| From | Len Brown <lenb@kernel.org> |
|---|---|
| Date | 2016-04-06 23:10 +0200 |
| Subject | [PATCH 0/13] intel_idle patches ready for upstream |
| Message-ID | <rl2S6-1tt-7@gated-at.bofh.it> |
Bug fixes, plus add a few more table entires for new model #'s. Some of the BXT table entries will be replaced by values read from processor configuration registers at boot-time. Let me know if you see troubles with any of these patches. They are all available on this git branch: git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux.git cpuidle thanks, -Len Brown, Intel Open Source Technology Center
[toc] | [next] | [standalone]
| From | Len Brown <lenb@kernel.org> |
|---|---|
| Date | 2016-04-06 23:10 +0200 |
| Subject | [PATCH 13/13] intel_idle: Add KBL support |
| Message-ID | <rl2S6-1tt-17@gated-at.bofh.it> |
| In reply to | #1372822 |
From: Len Brown <len.brown@intel.com>
KBL is similar to SKL
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/idle/intel_idle.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index d0ec343..c966492 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -1047,6 +1047,8 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = {
ICPU(0x56, idle_cpu_bdw),
ICPU(0x4e, 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(0x5c, idle_cpu_bxt),
--
2.8.0.rc4.16.g56331f8
[toc] | [prev] | [next] | [standalone]
| From | Len Brown <lenb@kernel.org> |
|---|---|
| Date | 2016-04-06 23:10 +0200 |
| Subject | [PATCH 08/13] intel_idle: Setup the timer broadcast only on successful driver load. |
| Message-ID | <rl2S6-1tt-21@gated-at.bofh.it> |
| In reply to | #1372822 |
From: Richard Cochran <rcochran@linutronix.de> This driver sets the broadcast tick quite early on during probe and does not clean up again in cast of failure. This patch moves the setup call after the registration, placing the on_each_cpu() calls within the global CPU lock region. Signed-off-by: Richard Cochran <rcochran@linutronix.de> Signed-off-by: Len Brown <len.brown@intel.com> --- drivers/idle/intel_idle.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 04fe4df..b5e92dd 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -1054,16 +1054,9 @@ static int __init intel_idle_probe(void) icpu = (const struct idle_cpu *)id->driver_data; 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 " 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; } @@ -1371,8 +1364,16 @@ static int __init intel_idle_init(void) } __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(); + pr_debug(PREFIX "lapic_timer_reliable_states 0x%x\n", + lapic_timer_reliable_states); + return 0; } -- 2.8.0.rc4.16.g56331f8
[toc] | [prev] | [next] | [standalone]
| From | Len Brown <lenb@kernel.org> |
|---|---|
| Date | 2016-04-06 23:10 +0200 |
| Subject | [PATCH 07/13] intel_idle: Avoid a double free of the per-CPU data. |
| Message-ID | <rl2S7-1tt-29@gated-at.bofh.it> |
| In reply to | #1372822 |
From: Richard Cochran <rcochran@linutronix.de>
The helper function, intel_idle_cpuidle_devices_uninit, frees the
globally allocated per-CPU data. However, this function is invoked
from the hot plug notifier callback at a time when freeing that data
is not safe.
If the call to cpuidle_register_driver() should fail (say, due to lack
of memory), then the driver will free its per-CPU region. On the
*next* CPU_ONLINE event, the driver will happily use the region again
and even free it again if the failure repeats.
This patch fixes the issue by moving the call to free_percpu() outside
of the helper function at the two call sites that actually need to
free the per-CPU data.
Signed-off-by: Richard Cochran <rcochran@linutronix.de>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/idle/intel_idle.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index 085538a..04fe4df 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -1069,7 +1069,7 @@ static int __init intel_idle_probe(void)
/*
* intel_idle_cpuidle_devices_uninit()
- * unregister, free cpuidle_devices
+ * Unregisters the cpuidle devices.
*/
static void intel_idle_cpuidle_devices_uninit(void)
{
@@ -1080,9 +1080,6 @@ static void intel_idle_cpuidle_devices_uninit(void)
dev = per_cpu_ptr(intel_idle_cpuidle_devices, i);
cpuidle_unregister_device(dev);
}
-
- free_percpu(intel_idle_cpuidle_devices);
- return;
}
/*
@@ -1368,6 +1365,7 @@ static int __init intel_idle_init(void)
if (retval) {
cpu_notifier_register_done();
cpuidle_unregister_driver(&intel_idle_driver);
+ free_percpu(intel_idle_cpuidle_devices);
return retval;
}
}
@@ -1390,6 +1388,7 @@ static void __exit intel_idle_exit(void)
cpu_notifier_register_done();
cpuidle_unregister_driver(&intel_idle_driver);
+ free_percpu(intel_idle_cpuidle_devices);
}
module_init(intel_idle_init);
--
2.8.0.rc4.16.g56331f8
[toc] | [prev] | [next] | [standalone]
| From | Len Brown <lenb@kernel.org> |
|---|---|
| Date | 2016-04-06 23:10 +0200 |
| Subject | [PATCH 02/13] intel_idle: remove useless return from void function. |
| Message-ID | <rl2S7-1tt-31@gated-at.bofh.it> |
| In reply to | #1372822 |
From: Richard Cochran <rcochran@linutronix.de> Signed-off-by: Richard Cochran <rcochran@linutronix.de> Signed-off-by: Len Brown <len.brown@intel.com> --- drivers/idle/intel_idle.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 012980a..6638a80 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -1397,8 +1397,6 @@ static void __exit intel_idle_exit(void) __unregister_cpu_notifier(&cpu_hotplug_notifier); cpu_notifier_register_done(); - - return; } module_init(intel_idle_init); -- 2.8.0.rc4.16.g56331f8
[toc] | [prev] | [next] | [standalone]
| From | Len Brown <lenb@kernel.org> |
|---|---|
| Date | 2016-04-06 23:10 +0200 |
| Subject | [PATCH 04/13] intel_idle: Remove redundant initialization calls. |
| Message-ID | <rl2S7-1tt-33@gated-at.bofh.it> |
| In reply to | #1372822 |
From: Richard Cochran <rcochran@linutronix.de>
The function, intel_idle_cpuidle_driver_init, makes calls on each CPU
to auto_demotion_disable() and c1e_promotion_disable(). These calls
are redundant, as intel_idle_cpu_init() does the same calls just a bit
later on. They are also premature, as the driver registration may yet
fail.
This patch removes the redundant code.
Signed-off-by: Richard Cochran <rcochran@linutronix.de>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/idle/intel_idle.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index d2e7baf..c50859d 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -1300,16 +1300,10 @@ static void __init intel_idle_cpuidle_driver_init(void)
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) {
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);
}
--
2.8.0.rc4.16.g56331f8
[toc] | [prev] | [next] | [standalone]
| From | Len Brown <lenb@kernel.org> |
|---|---|
| Date | 2016-04-06 23:10 +0200 |
| Subject | [PATCH 06/13] intel_idle: Fix dangling registration on error path. |
| Message-ID | <rl2S7-1tt-35@gated-at.bofh.it> |
| In reply to | #1372822 |
From: Richard Cochran <rcochran@linutronix.de>
In the module_init() method, if the per-CPU allocation fails, then the
active cpuidle registration is not cleaned up. This patch fixes the
issue by attempting the allocation before registration, and then
cleaning it up again on registration failure.
Signed-off-by: Richard Cochran <rcochran@linutronix.de>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/idle/intel_idle.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index 5b309e5..085538a 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -1347,19 +1347,20 @@ static int __init intel_idle_init(void)
if (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();
retval = cpuidle_register_driver(&intel_idle_driver);
if (retval) {
struct cpuidle_driver *drv = cpuidle_get_driver();
printk(KERN_DEBUG PREFIX "intel_idle yielding to %s",
drv ? drv->name : "none");
+ free_percpu(intel_idle_cpuidle_devices);
return retval;
}
- intel_idle_cpuidle_devices = alloc_percpu(struct cpuidle_device);
- if (intel_idle_cpuidle_devices == NULL)
- return -ENOMEM;
-
cpu_notifier_register_begin();
for_each_online_cpu(i) {
--
2.8.0.rc4.16.g56331f8
[toc] | [prev] | [next] | [standalone]
| From | Len Brown <lenb@kernel.org> |
|---|---|
| Date | 2016-04-06 23:10 +0200 |
| Subject | [PATCH 01/13] intel_idle: add BXT support |
| Message-ID | <rl2S7-1tt-39@gated-at.bofh.it> |
| In reply to | #1372822 |
From: Len Brown <len.brown@intel.com>
Broxton has all the HSW C-states, except C3.
BXT C-state timing is slightly different.
Here we trust the IRTL MSRs as authority
on maximum C-state latency, and override the driver's tables
with the values found in the associated IRTL MSRs.
Further we set the target_residency to 1x maximum latency,
trusting the hardware demotion logic.
Signed-off-by: Len Brown <len.brown@intel.com>
---
arch/x86/include/asm/msr-index.h | 8 +++
drivers/idle/intel_idle.c | 137 +++++++++++++++++++++++++++++++++++++++
2 files changed, 145 insertions(+)
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 2da46ac..1e81927 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -167,6 +167,14 @@
#define MSR_PKG_C9_RESIDENCY 0x00000631
#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 */
#define MSR_RAPL_POWER_UNIT 0x00000606
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index ba947df..012980a 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -737,6 +737,67 @@ static struct cpuidle_state knl_cstates[] = {
.enter = NULL }
};
+static struct cpuidle_state bxt_cstates[] = {
+ {
+ .name = "C1-BXT",
+ .desc = "MWAIT 0x00",
+ .flags = MWAIT2flg(0x00),
+ .exit_latency = 2,
+ .target_residency = 2,
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
+ {
+ .name = "C1E-BXT",
+ .desc = "MWAIT 0x01",
+ .flags = MWAIT2flg(0x01),
+ .exit_latency = 10,
+ .target_residency = 20,
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
+ {
+ .name = "C6-BXT",
+ .desc = "MWAIT 0x20",
+ .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
+ .exit_latency = 133,
+ .target_residency = 133,
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
+ {
+ .name = "C7s-BXT",
+ .desc = "MWAIT 0x31",
+ .flags = MWAIT2flg(0x31) | CPUIDLE_FLAG_TLB_FLUSHED,
+ .exit_latency = 155,
+ .target_residency = 155,
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
+ {
+ .name = "C8-BXT",
+ .desc = "MWAIT 0x40",
+ .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED,
+ .exit_latency = 1000,
+ .target_residency = 1000,
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
+ {
+ .name = "C9-BXT",
+ .desc = "MWAIT 0x50",
+ .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED,
+ .exit_latency = 2000,
+ .target_residency = 2000,
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
+ {
+ .name = "C10-BXT",
+ .desc = "MWAIT 0x60",
+ .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED,
+ .exit_latency = 10000,
+ .target_residency = 10000,
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
+ {
+ .enter = NULL }
+};
+
/**
* intel_idle
* @dev: cpuidle_device
@@ -914,6 +975,11 @@ static const struct idle_cpu idle_cpu_knl = {
.state_table = knl_cstates,
};
+static const struct idle_cpu idle_cpu_bxt = {
+ .state_table = bxt_cstates,
+ .disable_promotion_to_c1e = true,
+};
+
#define ICPU(model, cpu) \
{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&cpu }
@@ -946,6 +1012,7 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = {
ICPU(0x4e, idle_cpu_skl),
ICPU(0x5e, idle_cpu_skl),
ICPU(0x57, idle_cpu_knl),
+ ICPU(0x5c, idle_cpu_bxt),
{}
};
MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids);
@@ -1046,6 +1113,73 @@ static void ivt_idle_state_table_update(void)
/* else, 1 and 2 socket systems use default ivt_cstates */
}
+
+/*
+ * Translate IRTL (Interrupt Response Time Limit) MSR to usec
+ */
+
+static unsigned int irtl_ns_units[] = {
+ 1, 32, 1024, 32768, 1048576, 33554432, 0, 0 };
+
+static unsigned long long irtl_2_usec(unsigned long long irtl)
+{
+ unsigned long long ns;
+
+ ns = irtl_ns_units[(irtl >> 10) & 0x3];
+
+ return div64_u64((irtl & 0x3FF) * ns, 1000);
+}
+/*
+ * bxt_idle_state_table_update(void)
+ *
+ * On BXT, we trust the IRTL to show the definitive maximum latency
+ * We use the same value for target_residency.
+ */
+static void bxt_idle_state_table_update(void)
+{
+ unsigned long long msr;
+
+ rdmsrl(MSR_PKGC6_IRTL, msr);
+ if (msr) {
+ unsigned int usec = irtl_2_usec(msr);
+
+ bxt_cstates[2].exit_latency = usec;
+ bxt_cstates[2].target_residency = usec;
+ }
+
+ rdmsrl(MSR_PKGC7_IRTL, msr);
+ if (msr) {
+ unsigned int usec = irtl_2_usec(msr);
+
+ bxt_cstates[3].exit_latency = usec;
+ bxt_cstates[3].target_residency = usec;
+ }
+
+ rdmsrl(MSR_PKGC8_IRTL, msr);
+ if (msr) {
+ unsigned int usec = irtl_2_usec(msr);
+
+ bxt_cstates[4].exit_latency = usec;
+ bxt_cstates[4].target_residency = usec;
+ }
+
+ rdmsrl(MSR_PKGC9_IRTL, msr);
+ if (msr) {
+ unsigned int usec = irtl_2_usec(msr);
+
+ bxt_cstates[5].exit_latency = usec;
+ bxt_cstates[5].target_residency = usec;
+ }
+
+ rdmsrl(MSR_PKGC10_IRTL, msr);
+ if (msr) {
+ unsigned int usec = irtl_2_usec(msr);
+
+ bxt_cstates[6].exit_latency = usec;
+ bxt_cstates[6].target_residency = usec;
+ }
+
+}
/*
* sklh_idle_state_table_update(void)
*
@@ -1101,6 +1235,9 @@ static void intel_idle_state_table_update(void)
case 0x3e: /* IVT */
ivt_idle_state_table_update();
break;
+ case 0x5c: /* BXT */
+ bxt_idle_state_table_update();
+ break;
case 0x5e: /* SKL-H */
sklh_idle_state_table_update();
break;
--
2.8.0.rc4.16.g56331f8
[toc] | [prev] | [next] | [standalone]
| From | Len Brown <lenb@kernel.org> |
|---|---|
| Date | 2016-04-06 23:10 +0200 |
| Subject | [PATCH 09/13] intel_idle: Don't overreact to a cpuidle registration failure. |
| Message-ID | <rl2S7-1tt-43@gated-at.bofh.it> |
| In reply to | #1372822 |
From: Richard Cochran <rcochran@linutronix.de>
The helper function, intel_idle_cpu_init, registers one new device
with the cpuidle layer. If the registration should fail, that
function immediately calls intel_idle_cpuidle_devices_uninit() to
unregister every last CPU's device. However, it makes no sense to do
so, when called from the hot plug notifier callback.
This patch moves the call to intel_idle_cpuidle_devices_uninit()
outside of the helper function to the one call site that actually
needs to perform the de-registrations.
Signed-off-by: Richard Cochran <rcochran@linutronix.de>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/idle/intel_idle.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index b5e92dd..807be29 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -1312,7 +1312,6 @@ static int intel_idle_cpu_init(int cpu)
if (cpuidle_register_device(dev)) {
pr_debug(PREFIX "cpuidle_register_device %d failed!\n", cpu);
- intel_idle_cpuidle_devices_uninit();
return -EIO;
}
@@ -1356,6 +1355,7 @@ static int __init intel_idle_init(void)
for_each_online_cpu(i) {
retval = intel_idle_cpu_init(i);
if (retval) {
+ intel_idle_cpuidle_devices_uninit();
cpu_notifier_register_done();
cpuidle_unregister_driver(&intel_idle_driver);
free_percpu(intel_idle_cpuidle_devices);
--
2.8.0.rc4.16.g56331f8
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web