kern/114649: [patch][acpi] panic: recursed on non-recursive mutex
Cristian KLEIN
cristi at net.utcluj.ro
Tue Jul 17 01:40:04 UTC 2007
>Number: 114649
>Category: kern
>Synopsis: [patch][acpi] panic: recursed on non-recursive mutex
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Tue Jul 17 01:40:03 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator: Cristian KLEIN
>Release: 7.0-CURRENT
>Organization:
Technical University of Cluj-Napoca
>Environment:
FreeBSD hades.local 7.0-CURRENT FreeBSD 7.0-CURRENT #11: Tue Jul 17 04:08:17 EEST 2007 cristi at hades.local:/usr/obj/usr/src/sys/GENERIC i386
(source updated immediately before compiling)
>Description:
When resuming (from S3) an IBM Thinkpad R51 laptop, KDB is entered with the following panic string (written by hand):
panic: _mtx_lock_sleep: recursed on non-recursive mutex acpi subsystem GPE lock
@ ......./OsdSynch.c:377
>How-To-Repeat:
Suspend (S3) / resume a laptop. Panic will always occur after the first resume.
>Fix:
It seems to me that ACPI vendor code was not designed to use non-recursive mutexes. For example:
* AcpiEvGpeDetect() calls AcpiOsAcquireLock(AcpiGbl_GpeLock) in contrib/dev/acpica/evgpe.c:511, then calls AcpiEvGpeDispatch()
* AcpiEvGpeDispatch() calls AcpiHwDisableAllGpes() in evgpe.c:762
* AcpiHwDisableAllGpes() calls AcpiEvWalkGpeList in hwgpe.c:487
* AcpiEvWalkGpeList() calls AcpiOsAcquireLock(AcpiGbl_GpeLock) *again* in evgpeblk.c:237
Rather that correcting contributed code (in who knows how many places) and then have problems in the future (when the ACPI vendor code is upgraded), I suggest making the ACPI GPE lock recursable. The patch below does this.
After applying this patch, I've been able to suspend / resume 20+ times.
Patch attached with submission follows:
--- sys/dev/acpica/Osd/OsdSynch.c.orig 2007-03-27 02:04:02.000000000 +0300
+++ sys/dev/acpica/Osd/OsdSynch.c 2007-07-17 04:17:37.073597342 +0300
@@ -346,7 +346,7 @@
snprintf(h->name, sizeof(h->name), "acpi subsystem HW lock");
else
snprintf(h->name, sizeof(h->name), "acpi subsys %p", OutHandle);
- mtx_init(&h->lock, h->name, NULL, MTX_DEF);
+ mtx_init(&h->lock, h->name, NULL, MTX_DEF | MTX_RECURSE);
*OutHandle = (ACPI_SPINLOCK)h;
return (AE_OK);
}
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list