[issue568] ACPI(?) double-free on shutdown (More K9AGM fun)

Matthew Dillon dillon at apollo.backplane.com
Tue Mar 6 09:03:17 PST 2007


:SMP dmesg uploaded to the bug-tracker.
:
:The dirty filesystem is from a lazy press of the reset button and has nothi=
:ng to
:do with this bug.
:
:I'll try to check with a UP kernel soon.
:
:-Thanks,
:-Floid

    Hmm. ACPI is probably calling AcpiOsReleaseObject() twice for the same
    object sometime prior to the call to AcpiOsDeleteCache().

    Lets see if we can catch it in the act.  Try this patch and get a
    backtrace when you get the (hopefully new) panic.

    If we can catch it in the act earlier and get a good backtrace we may
    have enough information to fix the bug or, if messing with the contrib
    code is too messy, just ignore the error instead of panicing.

					-Matt

Index: dev/acpica5/Osd/OsdCache.c
===================================================================
RCS file: /cvs/src/sys/dev/acpica5/Osd/OsdCache.c,v
retrieving revision 1.2
diff -u -r1.2 OsdCache.c
--- dev/acpica5/Osd/OsdCache.c	19 Jan 2007 23:58:53 -0000	1.2
+++ dev/acpica5/Osd/OsdCache.c	6 Mar 2007 16:52:41 -0000
@@ -39,6 +39,20 @@
 	struct objcache_malloc_args args;
 };
 
+/*
+ * Add some magic numbers to catch double-frees earlier rather
+ * then later.
+ */
+struct acpiobjhead {
+	int state;
+	int unused;
+};
+
+#define TRACK_ALLOCATED	0x7AF45533
+#define TRACK_FREED	0x7B056644
+
+#define OBJHEADSIZE	sizeof(struct acpiobjhead)
+
 #include "acpi.h"
 
 #ifndef ACPI_USE_LOCAL_CACHE
@@ -50,7 +64,7 @@
 	ACPI_CACHE_T *cache;
 
 	cache = kmalloc(sizeof(*cache), M_TEMP, M_WAITOK);
-	cache->args.objsize = ObjectSize;
+	cache->args.objsize = OBJHEADSIZE + ObjectSize;
 	cache->args.mtype = M_CACHE;
 	cache->cache = objcache_create(CacheName, 0, 0, NULL, NULL,
 	    NULL, objcache_malloc_alloc, objcache_malloc_free, &cache->args);
@@ -79,17 +93,29 @@
 void *
 AcpiOsAcquireObject(ACPI_CACHE_T *Cache)
 {
+	struct acpiobjhead *head;
 	void *Object;
 
-	Object = objcache_get(Cache->cache, M_WAITOK);
-	bzero(Object, Cache->args.objsize);
-	return Object;
+	head = objcache_get(Cache->cache, M_WAITOK);
+	bzero(head, Cache->args.objsize);
+	head->state = TRACK_ALLOCATED;
+	return (head + 1);
 }
 
 ACPI_STATUS
 AcpiOsReleaseObject(ACPI_CACHE_T *Cache, void *Object)
 {
-	objcache_put(Cache->cache, Object);
+	struct acpiobjhead *head = (void *)((char *)Object - OBJHEADSIZE);
+
+	if (head->state != TRACK_ALLOCATED) {
+		if (head->state == TRACK_FREED)
+			panic("AcpiOsReleaseObject: Double Free %p (%08x)", Object, head->state);
+		else
+			panic("AcpiOsReleaseObject: Bad object %p (%08x)", Object, head->state);
+	}
+	head->state = TRACK_FREED;
+
+	objcache_put(Cache->cache, head);
 	return AE_OK;
 }
 





More information about the Bugs mailing list