Commit 6240a10d authored by Alex Shi's avatar Alex Shi Committed by Rafael J. Wysocki

cpuidle / ACPI: recover percpu ACPI processor cstate

Commit ac3ebafa "ACPI / idle: remove usage of the statedata"
changed the percpu processor cstate to a unified cstate in ACPI idle.
That caused all our NHM boxes to boot hang or panic.

2178751 Task dump for CPU 1:
	2178752 swapper/1       R  running task     6736     0      1 0x00000000
	2178753  ffff8801e8029dc8 ffffffff8101cf96 ffff8801e8029e28 ffffffff813d294b
	2178754  0000000000000f99 0000000000000003 00000000003cf654 0000000025c17d03
	2178755  ffff8801e8029e38 ffff8801e74fc000 00000002590dc5c4 ffffffff8163cdb0
	2178756 Call Trace:
	2178757  [<ffffffff8101cf96>] ? acpi_processor_ffh_cstate_enter+0x2d/0x2f
	2178758  [<ffffffff813d294b>] acpi_idle_enter_bm+0x1b1/0x236
	2178759  [<ffffffff8163cdb0>] ? disable_cpuidle+0x10/0x10
	2178760  [<ffffffff8163cdc2>] cpuidle_enter+0x12/0x14
	2178761  [<ffffffff8163d286>] cpuidle_wrap_enter+0x2f/0x6d
	2178762  [<ffffffff8163d2d4>] cpuidle_enter_tk+0x10/0x12
	2178763  [<ffffffff8163cdd6>] cpuidle_enter_state+0x12/0x3a
	2178764  [<ffffffff8163d4a7>] cpuidle_idle_call+0xe8/0x161
	2178765  [<ffffffff81008d99>] cpu_idle+0x5e/0xa4
	2178766  [<ffffffff8174c6c1>] start_secondary+0x1a9/0x1ad
	2178767 Task dump for CPU 2:

In fact, the ACPI idle is based on the assumption of difference percpu
cstate structures that are necessary for the implementation to work
cprrectly.  A unique acpi_processor_cx is not sifficient by far.

This patch is just a quick fix re-introducing the percpu cstates.

If someone really wants to unify the ACPI cstates, please make sure
that the whole software infrastructure is changed and take hardware
as well as many different kinds of BIOS settings into account.

[rjw: Changelog]
Reported-by: default avatarLKP project <lkp@linux.intel.com>
Reported-by: default avatarXie ChanglongX <changlongx.xie@intel.com>
Tested-by: default avatarYinghai Lu <yinghai@kernel.org>
Signed-off-by: default avatarAlex Shi <alex.shi@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent b34bb1ee
...@@ -66,7 +66,8 @@ module_param(latency_factor, uint, 0644); ...@@ -66,7 +66,8 @@ module_param(latency_factor, uint, 0644);
static DEFINE_PER_CPU(struct cpuidle_device *, acpi_cpuidle_device); static DEFINE_PER_CPU(struct cpuidle_device *, acpi_cpuidle_device);
static struct acpi_processor_cx *acpi_cstate[CPUIDLE_STATE_MAX]; static DEFINE_PER_CPU(struct acpi_processor_cx * [CPUIDLE_STATE_MAX],
acpi_cstate);
static int disabled_by_idle_boot_param(void) static int disabled_by_idle_boot_param(void)
{ {
...@@ -722,7 +723,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, ...@@ -722,7 +723,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int index) struct cpuidle_driver *drv, int index)
{ {
struct acpi_processor *pr; struct acpi_processor *pr;
struct acpi_processor_cx *cx = acpi_cstate[index]; struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu);
pr = __this_cpu_read(processors); pr = __this_cpu_read(processors);
...@@ -745,7 +746,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, ...@@ -745,7 +746,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
*/ */
static int acpi_idle_play_dead(struct cpuidle_device *dev, int index) static int acpi_idle_play_dead(struct cpuidle_device *dev, int index)
{ {
struct acpi_processor_cx *cx = acpi_cstate[index]; struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu);
ACPI_FLUSH_CPU_CACHE(); ACPI_FLUSH_CPU_CACHE();
...@@ -775,7 +776,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, ...@@ -775,7 +776,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int index) struct cpuidle_driver *drv, int index)
{ {
struct acpi_processor *pr; struct acpi_processor *pr;
struct acpi_processor_cx *cx = acpi_cstate[index]; struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu);
pr = __this_cpu_read(processors); pr = __this_cpu_read(processors);
...@@ -833,7 +834,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, ...@@ -833,7 +834,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int index) struct cpuidle_driver *drv, int index)
{ {
struct acpi_processor *pr; struct acpi_processor *pr;
struct acpi_processor_cx *cx = acpi_cstate[index]; struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu);
pr = __this_cpu_read(processors); pr = __this_cpu_read(processors);
...@@ -960,7 +961,7 @@ static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr, ...@@ -960,7 +961,7 @@ static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr,
!(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
continue; continue;
#endif #endif
acpi_cstate[count] = cx; per_cpu(acpi_cstate[count], dev->cpu) = cx;
count++; count++;
if (count == CPUIDLE_STATE_MAX) if (count == CPUIDLE_STATE_MAX)
......
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