[patch] suspend problems

From: Cristian KLEIN <cristi_at_net.utcluj.ro>
Date: Thu, 12 Jul 2007 00:19:22 +0300
Hi everybody,

I have buildworld/kernel yesterday. When I try to suspend using the ACPI 
sleep button, the following errors occur.

After several suspend / resume cycles, the system repeatedly prints this 
error message:

fwohci0: device physically ejected?

On my system fwohci seems to use poll (tested using a printf), so the 
message is printed so often that the system becomes unusable. My 
solution rate-limits this message, however I don't think that the 
firewire device is resumed correctly.

--- cut here ---
diff -ur sys.orig/dev/firewire/fwohci.c sys/dev/firewire/fwohci.c
--- sys.orig/dev/firewire/fwohci.c	2007-06-08 12:04:30.000000000 +0300
+++ sys/dev/firewire/fwohci.c	2007-07-11 17:31:10.898954755 +0300
_at__at_ -2064,8 +2064,13 _at__at_

  	stat = OREAD(sc, FWOHCI_INTSTAT);
  	if (stat == 0xffffffff) {
-		device_printf(sc->fc.dev,
-			"device physically ejected?\n");
+		/* Rate limit this message */
+		static int verbose = 10;
+		if (verbose != 0) {
+			device_printf(sc->fc.dev,
+				"device physically ejected?\n");
+			verbose--;
+		}
  		return (FILTER_STRAY);
  	}
  	if (stat)
--- and here ---

After solving this problem, during resume, the kernel panics with 
something like "recursing on non-recursive mutex ". The problem seems to 
be in ACPI vendor code, which assumes that the OS supplied lock 
functions allow recursion. The following patch modifies the OS layer to 
match ACPI vendor code's assumption:

--- cut here ---
diff -ur sys.orig/dev/acpica/Osd/OsdSynch.c sys/dev/acpica/Osd/OsdSynch.c
--- sys.orig/dev/acpica/Osd/OsdSynch.c	2007-03-27 02:04:02.000000000 +0300
+++ sys/dev/acpica/Osd/OsdSynch.c	2007-07-11 17:29:47.497655148 +0300
_at__at_ -346,7 +346,7 _at__at_
  	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);
  }
--- and here ---

E.g.
* 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) aaagain 
in evgpeblk.c:237

Thanks.
Received on Wed Jul 11 2007 - 19:19:39 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:14 UTC