[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