aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/processor_idle.c
diff options
context:
space:
mode:
authorAlex Shi <alex.shi@intel.com>2013-04-01 19:56:54 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-04-02 09:31:28 -0400
commit6240a10dc55a954ce05a86d2f4bc27e473b6352c (patch)
tree22f72ecfd27ba4af6714c82aadac271cadec9777 /drivers/acpi/processor_idle.c
parentb34bb1ee71158d5b0f9028fb98afd026202bcfe9 (diff)
cpuidle / ACPI: recover percpu ACPI processor cstate
Commit ac3ebafa81af76d6 "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: LKP project <lkp@linux.intel.com> Reported-by: Xie ChanglongX <changlongx.xie@intel.com> Tested-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: Alex Shi <alex.shi@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/processor_idle.c')
-rw-r--r--drivers/acpi/processor_idle.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index fc95308e9a11..ee255c60bdac 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -66,7 +66,8 @@ module_param(latency_factor, uint, 0644);
66 66
67static DEFINE_PER_CPU(struct cpuidle_device *, acpi_cpuidle_device); 67static DEFINE_PER_CPU(struct cpuidle_device *, acpi_cpuidle_device);
68 68
69static struct acpi_processor_cx *acpi_cstate[CPUIDLE_STATE_MAX]; 69static DEFINE_PER_CPU(struct acpi_processor_cx * [CPUIDLE_STATE_MAX],
70 acpi_cstate);
70 71
71static int disabled_by_idle_boot_param(void) 72static int disabled_by_idle_boot_param(void)
72{ 73{
@@ -722,7 +723,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
722 struct cpuidle_driver *drv, int index) 723 struct cpuidle_driver *drv, int index)
723{ 724{
724 struct acpi_processor *pr; 725 struct acpi_processor *pr;
725 struct acpi_processor_cx *cx = acpi_cstate[index]; 726 struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu);
726 727
727 pr = __this_cpu_read(processors); 728 pr = __this_cpu_read(processors);
728 729
@@ -745,7 +746,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
745 */ 746 */
746static int acpi_idle_play_dead(struct cpuidle_device *dev, int index) 747static int acpi_idle_play_dead(struct cpuidle_device *dev, int index)
747{ 748{
748 struct acpi_processor_cx *cx = acpi_cstate[index]; 749 struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu);
749 750
750 ACPI_FLUSH_CPU_CACHE(); 751 ACPI_FLUSH_CPU_CACHE();
751 752
@@ -775,7 +776,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
775 struct cpuidle_driver *drv, int index) 776 struct cpuidle_driver *drv, int index)
776{ 777{
777 struct acpi_processor *pr; 778 struct acpi_processor *pr;
778 struct acpi_processor_cx *cx = acpi_cstate[index]; 779 struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu);
779 780
780 pr = __this_cpu_read(processors); 781 pr = __this_cpu_read(processors);
781 782
@@ -833,7 +834,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
833 struct cpuidle_driver *drv, int index) 834 struct cpuidle_driver *drv, int index)
834{ 835{
835 struct acpi_processor *pr; 836 struct acpi_processor *pr;
836 struct acpi_processor_cx *cx = acpi_cstate[index]; 837 struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu);
837 838
838 pr = __this_cpu_read(processors); 839 pr = __this_cpu_read(processors);
839 840
@@ -960,7 +961,7 @@ static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr,
960 !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) 961 !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
961 continue; 962 continue;
962#endif 963#endif
963 acpi_cstate[count] = cx; 964 per_cpu(acpi_cstate[count], dev->cpu) = cx;
964 965
965 count++; 966 count++;
966 if (count == CPUIDLE_STATE_MAX) 967 if (count == CPUIDLE_STATE_MAX)