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