xref: /dragonfly/sys/dev/acpica/Osd/OsdCache.c (revision 8a7a7510)
15db2f26eSSascha Wildner /*
25db2f26eSSascha Wildner  * Copyright (c) 2006 Jeffrey M. Hsu.  All rights reserved.
35db2f26eSSascha Wildner  *
45db2f26eSSascha Wildner  * This code is derived from software contributed to The DragonFly Project
55db2f26eSSascha Wildner  * by Jeffrey M. Hsu.
65db2f26eSSascha Wildner  *
75db2f26eSSascha Wildner  * Redistribution and use in source and binary forms, with or without
85db2f26eSSascha Wildner  * modification, are permitted provided that the following conditions
95db2f26eSSascha Wildner  * are met:
105db2f26eSSascha Wildner  * 1. Redistributions of source code must retain the above copyright
115db2f26eSSascha Wildner  *    notice, this list of conditions and the following disclaimer.
125db2f26eSSascha Wildner  * 2. Redistributions in binary form must reproduce the above copyright
135db2f26eSSascha Wildner  *    notice, this list of conditions and the following disclaimer in the
145db2f26eSSascha Wildner  *    documentation and/or other materials provided with the distribution.
155db2f26eSSascha Wildner  * 3. Neither the name of The DragonFly Project nor the names of its
165db2f26eSSascha Wildner  *    contributors may be used to endorse or promote products derived
175db2f26eSSascha Wildner  *    from this software without specific, prior written permission.
185db2f26eSSascha Wildner  *
195db2f26eSSascha Wildner  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
205db2f26eSSascha Wildner  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
215db2f26eSSascha Wildner  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
225db2f26eSSascha Wildner  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
235db2f26eSSascha Wildner  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
245db2f26eSSascha Wildner  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
255db2f26eSSascha Wildner  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
265db2f26eSSascha Wildner  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
275db2f26eSSascha Wildner  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
285db2f26eSSascha Wildner  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
295db2f26eSSascha Wildner  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
305db2f26eSSascha Wildner  * SUCH DAMAGE.
315db2f26eSSascha Wildner  */
325db2f26eSSascha Wildner 
336354fc0fSzrj #include <sys/types.h>
346354fc0fSzrj #include <sys/malloc.h>
355db2f26eSSascha Wildner #include <sys/objcache.h>
365db2f26eSSascha Wildner 
375db2f26eSSascha Wildner struct acpicache {
385db2f26eSSascha Wildner 	struct objcache *cache;
395db2f26eSSascha Wildner 	struct objcache_malloc_args args;
405db2f26eSSascha Wildner };
415db2f26eSSascha Wildner 
425db2f26eSSascha Wildner /*
435db2f26eSSascha Wildner  * Add some magic numbers to catch double-frees earlier rather
445db2f26eSSascha Wildner  * then later.
455db2f26eSSascha Wildner  */
465db2f26eSSascha Wildner struct acpiobjhead {
475db2f26eSSascha Wildner 	int state;
485db2f26eSSascha Wildner 	void *cache;
495db2f26eSSascha Wildner 	const char *func;
505db2f26eSSascha Wildner 	int line;
515db2f26eSSascha Wildner 	int unused;
525db2f26eSSascha Wildner };
535db2f26eSSascha Wildner 
545db2f26eSSascha Wildner #define TRACK_ALLOCATED	0x7AF45533
555db2f26eSSascha Wildner #define TRACK_FREED	0x7B056644
565db2f26eSSascha Wildner 
575db2f26eSSascha Wildner #define OBJHEADSIZE	sizeof(struct acpiobjhead)
585db2f26eSSascha Wildner 
595db2f26eSSascha Wildner #include "acpi.h"
605db2f26eSSascha Wildner 
615db2f26eSSascha Wildner ACPI_STATUS
AcpiOsCreateCache(char * CacheName,UINT16 ObjectSize,UINT16 MaxDepth,ACPI_CACHE_T ** ReturnCache)625db2f26eSSascha Wildner AcpiOsCreateCache(char *CacheName, UINT16 ObjectSize, UINT16 MaxDepth,
635db2f26eSSascha Wildner     ACPI_CACHE_T **ReturnCache)
645db2f26eSSascha Wildner {
655db2f26eSSascha Wildner 	ACPI_CACHE_T *cache;
665db2f26eSSascha Wildner 
675db2f26eSSascha Wildner 	cache = kmalloc(sizeof(*cache), M_TEMP, M_WAITOK);
685db2f26eSSascha Wildner 	cache->args.objsize = OBJHEADSIZE + ObjectSize;
695db2f26eSSascha Wildner 	cache->args.mtype = M_CACHE;
705db2f26eSSascha Wildner 	cache->cache = objcache_create(CacheName, 0, 0, NULL, NULL,
715db2f26eSSascha Wildner 	    NULL, objcache_malloc_alloc, objcache_malloc_free, &cache->args);
725db2f26eSSascha Wildner 	*ReturnCache = cache;
735db2f26eSSascha Wildner 	return AE_OK;
745db2f26eSSascha Wildner }
755db2f26eSSascha Wildner 
765db2f26eSSascha Wildner ACPI_STATUS
AcpiOsDeleteCache(ACPI_CACHE_T * Cache)775db2f26eSSascha Wildner AcpiOsDeleteCache(ACPI_CACHE_T *Cache)
785db2f26eSSascha Wildner {
795db2f26eSSascha Wildner 	objcache_destroy(Cache->cache);
805db2f26eSSascha Wildner 	kfree(Cache, M_TEMP);
815db2f26eSSascha Wildner 	return AE_OK;
825db2f26eSSascha Wildner }
835db2f26eSSascha Wildner 
845db2f26eSSascha Wildner 
855db2f26eSSascha Wildner ACPI_STATUS
AcpiOsPurgeCache(ACPI_CACHE_T * Cache)865db2f26eSSascha Wildner AcpiOsPurgeCache(ACPI_CACHE_T *Cache)
875db2f26eSSascha Wildner {
885db2f26eSSascha Wildner 	struct objcache *reclaimlist[] = { Cache->cache };
895db2f26eSSascha Wildner 
90*8a7a7510SAaron LI 	objcache_reclaimlist(reclaimlist, 1);
915db2f26eSSascha Wildner 	return AE_OK;
925db2f26eSSascha Wildner }
935db2f26eSSascha Wildner 
945db2f26eSSascha Wildner void *
AcpiOsAcquireObject(ACPI_CACHE_T * Cache)955db2f26eSSascha Wildner AcpiOsAcquireObject(ACPI_CACHE_T *Cache)
965db2f26eSSascha Wildner {
975db2f26eSSascha Wildner 	struct acpiobjhead *head;
985db2f26eSSascha Wildner 
995db2f26eSSascha Wildner 	head = objcache_get(Cache->cache, M_WAITOK);
1005db2f26eSSascha Wildner 	bzero(head, Cache->args.objsize);
1015db2f26eSSascha Wildner 	head->state = TRACK_ALLOCATED;
1026af96acdSSascha Wildner #ifdef ACPI_DEBUG_CACHE
1035db2f26eSSascha Wildner 	head->cache = Cache;
1045db2f26eSSascha Wildner 	head->func = "nowhere";
1055db2f26eSSascha Wildner 	head->line = 0;
1065db2f26eSSascha Wildner #endif
1075db2f26eSSascha Wildner 	return (head + 1);
1085db2f26eSSascha Wildner }
1095db2f26eSSascha Wildner 
1105db2f26eSSascha Wildner ACPI_STATUS
1116af96acdSSascha Wildner #ifdef ACPI_DEBUG_CACHE
_AcpiOsReleaseObject(ACPI_CACHE_T * Cache,void * Object,const char * func,int line)1125db2f26eSSascha Wildner _AcpiOsReleaseObject(ACPI_CACHE_T *Cache, void *Object,
1135db2f26eSSascha Wildner     const char *func, int line)
1145db2f26eSSascha Wildner #else
1155db2f26eSSascha Wildner AcpiOsReleaseObject(ACPI_CACHE_T *Cache, void *Object)
1165db2f26eSSascha Wildner #endif
1175db2f26eSSascha Wildner {
1185db2f26eSSascha Wildner 	struct acpiobjhead *head = (void *)((char *)Object - OBJHEADSIZE);
1195db2f26eSSascha Wildner 
1206af96acdSSascha Wildner #ifdef ACPI_DEBUG_CACHE
1215db2f26eSSascha Wildner 	if (head->cache != Cache) {
1225db2f26eSSascha Wildner 		kprintf("%s: object %p belongs to %p, not %p\n",
1235db2f26eSSascha Wildner 			__func__, Object, head->cache, Cache);
1245db2f26eSSascha Wildner 	}
1255db2f26eSSascha Wildner #endif
1265db2f26eSSascha Wildner 	if (head->state != TRACK_ALLOCATED) {
1275db2f26eSSascha Wildner 		if (head->state == TRACK_FREED) {
1286af96acdSSascha Wildner #ifdef ACPI_DEBUG_CACHE
1295db2f26eSSascha Wildner 			kprintf("%s: Double Free %p, %s:%d, first %s:%d\n",
1305db2f26eSSascha Wildner 				__func__, Object, func, line, head->func,
1315db2f26eSSascha Wildner 				head->line);
1325db2f26eSSascha Wildner #else
1335db2f26eSSascha Wildner 			kprintf("%s: Double Free %p\n", __func__, Object);
1345db2f26eSSascha Wildner #endif
1355db2f26eSSascha Wildner 		} else
1365db2f26eSSascha Wildner 			kprintf("AcpiOsReleaseObject: Bad object %p (%08x)\n",
1375db2f26eSSascha Wildner 				Object, head->state);
1385db2f26eSSascha Wildner 		return AE_OK;
1395db2f26eSSascha Wildner 	}
1405db2f26eSSascha Wildner 	head->state = TRACK_FREED;
1416af96acdSSascha Wildner #ifdef ACPI_DEBUG_CACHE
1425db2f26eSSascha Wildner 	head->func = func;
1435db2f26eSSascha Wildner 	head->line = line;
1445db2f26eSSascha Wildner #endif
1455db2f26eSSascha Wildner 	objcache_put(Cache->cache, head);
1465db2f26eSSascha Wildner 	return AE_OK;
1475db2f26eSSascha Wildner }
148