aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>2013-12-20 13:47:26 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-01-10 19:26:49 -0500
commit7ca380f60626d90cdd17cc60de5e756422e35b2a (patch)
tree6d7301a6da09d0804f948fcb9860d69c34926c98 /drivers/acpi
parent7f74dc0f4f5fdb745d62ab2e8f6c60cd9e59a1ac (diff)
ACPI / cpuidle: fix max idle state handling with hotplug CPU support
acpi_processor_hotplug() calls acpi_processor_setup_cpuidle_cx() without calling acpi_processor_setup_cpuidle_states() first so it is possible that dev->state_count becomes different from drv->state_count (in case of SMP system with unsupported C2/C3 states + enabled CPU hotplug and num_online_cpus() becoming > 1). The driver code assumes that cpuidle core will handle such cases but currently this is untrue (dev->state_count is used only for handling cpuidle state sysfs entries and drv->state_count is used for all other cases) and will not be fixed in the future as dev->state_count is planned to be removed. Fix the issue by checking for the max supported idle state in C2/C3 state's ->enter handler (acpi_idle_enter_simple() for C2/C3 and acpi_idle_enter_bm() for C3 + bm_check flag set) and setting the C1 state (instead of higher states) when needed. Also remove no longer needed max idle state checks from acpi_processor_setup_cpuidle_[states,cx](). Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Cc: Len Brown <lenb@kernel.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/processor_idle.c27
1 files changed, 14 insertions, 13 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 644516d9bde6..45e3b81d6c29 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -785,6 +785,13 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
785 if (unlikely(!pr)) 785 if (unlikely(!pr))
786 return -EINVAL; 786 return -EINVAL;
787 787
788#ifdef CONFIG_HOTPLUG_CPU
789 if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) &&
790 !pr->flags.has_cst &&
791 !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
792 return acpi_idle_enter_c1(dev, drv, CPUIDLE_DRIVER_STATE_START);
793#endif
794
788 if (cx->entry_method == ACPI_CSTATE_FFH) { 795 if (cx->entry_method == ACPI_CSTATE_FFH) {
789 if (current_set_polling_and_test()) 796 if (current_set_polling_and_test())
790 return -EINVAL; 797 return -EINVAL;
@@ -831,6 +838,13 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
831 if (unlikely(!pr)) 838 if (unlikely(!pr))
832 return -EINVAL; 839 return -EINVAL;
833 840
841#ifdef CONFIG_HOTPLUG_CPU
842 if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) &&
843 !pr->flags.has_cst &&
844 !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
845 return acpi_idle_enter_c1(dev, drv, CPUIDLE_DRIVER_STATE_START);
846#endif
847
834 if (!cx->bm_sts_skip && acpi_idle_bm_check()) { 848 if (!cx->bm_sts_skip && acpi_idle_bm_check()) {
835 if (drv->safe_state_index >= 0) { 849 if (drv->safe_state_index >= 0) {
836 return drv->states[drv->safe_state_index].enter(dev, 850 return drv->states[drv->safe_state_index].enter(dev,
@@ -932,12 +946,6 @@ static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr,
932 if (!cx->valid) 946 if (!cx->valid)
933 continue; 947 continue;
934 948
935#ifdef CONFIG_HOTPLUG_CPU
936 if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) &&
937 !pr->flags.has_cst &&
938 !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
939 continue;
940#endif
941 per_cpu(acpi_cstate[count], dev->cpu) = cx; 949 per_cpu(acpi_cstate[count], dev->cpu) = cx;
942 950
943 count++; 951 count++;
@@ -987,13 +995,6 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr)
987 if (!cx->valid) 995 if (!cx->valid)
988 continue; 996 continue;
989 997
990#ifdef CONFIG_HOTPLUG_CPU
991 if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) &&
992 !pr->flags.has_cst &&
993 !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
994 continue;
995#endif
996
997 state = &drv->states[count]; 998 state = &drv->states[count];
998 snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i); 999 snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i);
999 strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN); 1000 strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN);