Fix for GPE livelock on HPs
Nate Lawson
nate at root.org
Sat Jan 12 14:57:19 PST 2008
I've committed the below patch and want to MFC it to 7.0. To do this, I
need people to test this quickly. It probably has no effect in 6.x and
probably doesn't apply cleanly there.
Please try this patch if you have a laptop and 7.x. If you have
-current, just cvsup. I'd like to make sure there is no regression.
I'm already aware that it fixes things for some HP users.
Thanks for your time,
Nate
-------- Original Message --------
Subject: cvs commit: src/sys/dev/acpica/Osd OsdSchedule.c
src/sys/contrib/dev/acpica evgpe.c
Date: Sat, 12 Jan 2008 22:13:18 +0000 (UTC)
From: Nate Lawson <njl at FreeBSD.org>
To: njl at FreeBSD.ORG
njl 2008-01-12 22:13:12 UTC
FreeBSD src repository
Modified files:
sys/dev/acpica/Osd OsdSchedule.c
Modified files: (Branch: INTEL)
sys/contrib/dev/acpica evgpe.c
Log:
Fix GPE livelock that occurs on HP/Compaq laptops, mostly in the thermal
zone code. The GPE handler method (i.e. _L00) generates various Notify
events that need to be run to completion before the GPE is re-enabled.
In ACPI-CA, we queue an asynch callback at the same priority as a Notify
so that it will only run after all Notify handlers have completed. The
callback re-enables the GPE afterwards. We also changed the priority of
Notifies to be the same as GPEs, given the possibility that another GPE
could arrive before the Notifies have completed and we don't want it to
get queued ahead of the rest.
The ACPI-CA change was submitted by Alexey Starikovskiy (SUSE) and will
appear in a later release. Special thanks to him for helping track this
bug down.
MFC after: 1 week
Tested by: jhb, Yousif Hassan <yousif / alumni.jmu.edu>
Revision Changes Path
1.1.1.13 +19 -3 src/sys/contrib/dev/acpica/evgpe.c
1.40 +7 -3 src/sys/dev/acpica/Osd/OsdSchedule.c
Index: src/sys/contrib/dev/acpica/evgpe.c
diff -u src/sys/contrib/dev/acpica/evgpe.c:1.1.1.12
src/sys/contrib/dev/acpica/evgpe.c:1.1.1.13
--- src/sys/contrib/dev/acpica/evgpe.c:1.1.1.12 Thu Mar 22 17:23:30 2007
+++ src/sys/contrib/dev/acpica/evgpe.c Sat Jan 12 22:13:12 2008
@@ -123,6 +123,10 @@
/* Local prototypes */
+static void
+AcpiEvAsynchEnableGpe (
+ void *Context);
+
static void ACPI_SYSTEM_XFACE
AcpiEvAsynchExecuteGpeMethod (
void *Context);
@@ -684,14 +688,26 @@
}
}
- if ((LocalGpeEventInfo.Flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
+ /* Defer enabling of GPE until all notify handlers are done */
+ AcpiOsExecute(OSL_NOTIFY_HANDLER, AcpiEvAsynchEnableGpe, GpeEventInfo);
+ return_VOID;
+}
+
+static void
+AcpiEvAsynchEnableGpe (
+ void *Context)
+{
+ ACPI_GPE_EVENT_INFO *GpeEventInfo = (void *) Context;
+ ACPI_STATUS Status;
+
+ if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
ACPI_GPE_LEVEL_TRIGGERED)
{
/*
* GPE is level-triggered, we clear the GPE status bit after
* handling the event.
*/
- Status = AcpiHwClearGpe (&LocalGpeEventInfo);
+ Status = AcpiHwClearGpe (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
return_VOID;
@@ -700,7 +716,7 @@
/* Enable this GPE */
- (void) AcpiHwWriteGpeEnableReg (&LocalGpeEventInfo);
+ (void) AcpiHwWriteGpeEnableReg (GpeEventInfo);
return_VOID;
}
Index: src/sys/dev/acpica/Osd/OsdSchedule.c
diff -u src/sys/dev/acpica/Osd/OsdSchedule.c:1.39
src/sys/dev/acpica/Osd/OsdSchedule.c:1.40
--- src/sys/dev/acpica/Osd/OsdSchedule.c:1.39 Thu Mar 22 18:16:41 2007
+++ src/sys/dev/acpica/Osd/OsdSchedule.c Sat Jan 12 22:13:12 2008
@@ -106,6 +106,13 @@
at->at_context = Context;
switch (Type) {
case OSL_GPE_HANDLER:
+ case OSL_NOTIFY_HANDLER:
+ /*
+ * Run GPEs and Notifies at the same priority. This allows
+ * Notifies that are generated by running a GPE's method (e.g., _L00)
+ * to not be pre-empted by a later GPE that arrives during the
+ * Notify handler execution.
+ */
pri = 10;
break;
case OSL_GLOBAL_LOCK_HANDLER:
@@ -113,9 +120,6 @@
case OSL_EC_BURST_HANDLER:
pri = 5;
break;
- case OSL_NOTIFY_HANDLER:
- pri = 3;
- break;
case OSL_DEBUGGER_THREAD:
pri = 0;
break;
More information about the freebsd-current
mailing list