svn commit: r244614 - stable/9/sys/dev/acpica
Andriy Gapon
avg at FreeBSD.org
Sun Dec 23 12:06:00 UTC 2012
Author: avg
Date: Sun Dec 23 12:06:00 2012
New Revision: 244614
URL: http://svnweb.freebsd.org/changeset/base/244614
Log:
MFC r243760: acpi_cpu: change cpu_disable_idle to be a per-cpu flag
Modified:
stable/9/sys/dev/acpica/acpi_cpu.c
Directory Properties:
stable/9/sys/ (props changed)
stable/9/sys/dev/ (props changed)
Modified: stable/9/sys/dev/acpica/acpi_cpu.c
==============================================================================
--- stable/9/sys/dev/acpica/acpi_cpu.c Sun Dec 23 11:58:08 2012 (r244613)
+++ stable/9/sys/dev/acpica/acpi_cpu.c Sun Dec 23 12:06:00 2012 (r244614)
@@ -90,6 +90,7 @@ struct acpi_cpu_softc {
struct sysctl_oid *cpu_sysctl_tree;
int cpu_cx_lowest;
int cpu_cx_lowest_lim;
+ int cpu_disable_idle; /* Disable entry to idle function */
char cpu_cx_supported[64];
int cpu_rid;
};
@@ -137,9 +138,6 @@ static uint32_t cpu_smi_cmd; /* Value
static uint8_t cpu_cst_cnt; /* Indicate we are _CST aware. */
static int cpu_quirks; /* Indicate any hardware bugs. */
-/* Runtime state. */
-static int cpu_disable_idle; /* Disable entry to idle function */
-
/* Values for sysctl. */
static struct sysctl_ctx_list cpu_sysctl_ctx;
static struct sysctl_oid *cpu_sysctl_tree;
@@ -418,6 +416,39 @@ acpi_cpu_postattach(void *unused __unuse
SYSINIT(acpi_cpu, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE,
acpi_cpu_postattach, NULL);
+static void
+disable_idle(struct acpi_cpu_softc *sc)
+{
+ cpuset_t cpuset;
+
+ CPU_SETOF(sc->cpu_pcpu->pc_cpuid, &cpuset);
+ sc->cpu_disable_idle = TRUE;
+
+ /*
+ * Ensure that the CPU is not in idle state or in acpi_cpu_idle().
+ * Note that this code depends on the fact that the rendezvous IPI
+ * can not penetrate context where interrupts are disabled and acpi_cpu_idle
+ * is called and executed in such a context with interrupts being re-enabled
+ * right before return.
+ */
+ smp_rendezvous_cpus(cpuset, smp_no_rendevous_barrier, NULL,
+ smp_no_rendevous_barrier, NULL);
+}
+
+static void
+enable_idle(struct acpi_cpu_softc *sc)
+{
+
+ sc->cpu_disable_idle = FALSE;
+}
+
+static int
+is_idle_disabled(struct acpi_cpu_softc *sc)
+{
+
+ return (sc->cpu_disable_idle);
+}
+
/*
* Disable any entry to the idle function during suspend and re-enable it
* during resume.
@@ -430,7 +461,7 @@ acpi_cpu_suspend(device_t dev)
error = bus_generic_suspend(dev);
if (error)
return (error);
- cpu_disable_idle = TRUE;
+ disable_idle(device_get_softc(dev));
return (0);
}
@@ -438,7 +469,7 @@ static int
acpi_cpu_resume(device_t dev)
{
- cpu_disable_idle = FALSE;
+ enable_idle(device_get_softc(dev));
return (bus_generic_resume(dev));
}
@@ -572,12 +603,14 @@ acpi_cpu_shutdown(device_t dev)
bus_generic_shutdown(dev);
/*
- * Disable any entry to the idle function. There is a small race where
- * an idle thread have passed this check but not gone to sleep. This
- * is ok since device_shutdown() does not free the softc, otherwise
- * we'd have to be sure all threads were evicted before returning.
+ * Disable any entry to the idle function.
+ */
+ disable_idle(device_get_softc(dev));
+
+ /*
+ * CPU devices are not truely detached and remain referenced,
+ * so their resources are not freed.
*/
- cpu_disable_idle = TRUE;
return_VALUE (0);
}
@@ -860,7 +893,10 @@ acpi_cpu_startup(void *arg)
/* Take over idling from cpu_idle_default(). */
cpu_cx_lowest_lim = 0;
- cpu_disable_idle = FALSE;
+ for (i = 0; i < cpu_ndevices; i++) {
+ sc = device_get_softc(cpu_devices[i]);
+ enable_idle(sc);
+ }
cpu_idle_hook = acpi_cpu_idle;
}
@@ -926,12 +962,6 @@ acpi_cpu_idle()
uint32_t start_time, end_time;
int bm_active, cx_next_idx, i;
- /* If disabled, return immediately. */
- if (cpu_disable_idle) {
- ACPI_ENABLE_IRQS();
- return;
- }
-
/*
* Look up our CPU id to get our softc. If it's NULL, we'll use C1
* since there is no ACPI processor object for this CPU. This occurs
@@ -943,6 +973,12 @@ acpi_cpu_idle()
return;
}
+ /* If disabled, return immediately. */
+ if (is_idle_disabled(sc)) {
+ ACPI_ENABLE_IRQS();
+ return;
+ }
+
/* Find the lowest state that has small enough latency. */
cx_next_idx = 0;
if (cpu_disable_deep_sleep)
More information about the svn-src-stable-9
mailing list