summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_zone.c
diff options
context:
space:
mode:
authordyson <dyson@FreeBSD.org>1997-09-21 04:24:27 +0000
committerdyson <dyson@FreeBSD.org>1997-09-21 04:24:27 +0000
commite64b1984f97c6d987d7d36b61a3afe5028a08312 (patch)
tree325bcf17de3aad0383fb86548872026a7c3d2599 /sys/vm/vm_zone.c
parent1419fcb42b4e1e5a73f4574739f4c232fde357e2 (diff)
downloadFreeBSD-src-e64b1984f97c6d987d7d36b61a3afe5028a08312.zip
FreeBSD-src-e64b1984f97c6d987d7d36b61a3afe5028a08312.tar.gz
Change the M_NAMEI allocations to use the zone allocator. This change
plus the previous changes to use the zone allocator decrease the useage of malloc by half. The Zone allocator will be upgradeable to be able to use per CPU-pools, and has more intelligent usage of SPLs. Additionally, it has reasonable stats gathering capabilities, while making most calls inline.
Diffstat (limited to 'sys/vm/vm_zone.c')
-rw-r--r--sys/vm/vm_zone.c70
1 files changed, 62 insertions, 8 deletions
diff --git a/sys/vm/vm_zone.c b/sys/vm/vm_zone.c
index 6792a4c..38c43db 100644
--- a/sys/vm/vm_zone.c
+++ b/sys/vm/vm_zone.c
@@ -18,7 +18,7 @@
* 5. Modifications may be freely made to this file if the above conditions
* are met.
*
- * $Id: vm_zone.c,v 1.5 1997/08/18 03:29:21 fsmp Exp $
+ * $Id: vm_zone.c,v 1.6 1997/09/01 03:17:32 bde Exp $
*/
#include <sys/param.h>
@@ -79,13 +79,14 @@ zinitna(vm_zone_t z, vm_object_t obj, char *name, int size,
int totsize;
if ((z->zflags & ZONE_BOOT) == 0) {
- z->zsize = size;
+ z->zsize = (size + 32 - 1) & ~(32 - 1);
simple_lock_init(&z->zlock);
z->zfreecnt = 0;
z->ztotal = 0;
z->zmax = 0;
z->zname = name;
z->znalloc = 0;
+ z->zitems = NULL;
if (zlist == 0) {
zlist = z;
@@ -183,8 +184,12 @@ zbootinit(vm_zone_t z, char *name, int size, void *item, int nitems) {
z->znalloc = 0;
simple_lock_init(&z->zlock);
+ z->zitems = NULL;
for (i = 0; i < nitems; i++) {
- * (void **) item = z->zitems;
+ ((void **) item)[0] = z->zitems;
+#if defined(DIAGNOSTIC)
+ ((void **) item)[1] = (void *) ZENTRY_FREE;
+#endif
z->zitems = item;
(char *) item += z->zsize;
}
@@ -263,9 +268,12 @@ void *
_zget(vm_zone_t z) {
int i;
vm_page_t m;
- int nitems;
+ int nitems, nbytes;
void *item;
+ if (z == NULL)
+ panic("zget: null zone");
+
if (z->zflags & ZONE_INTERRUPT) {
item = (char *) z->zkva + z->zpagecount * PAGE_SIZE;
for( i = 0; ((i < z->zalloc) && (z->zpagecount < z->zpagemax)); i++) {
@@ -280,11 +288,26 @@ _zget(vm_zone_t z) {
}
nitems = (i * PAGE_SIZE) / z->zsize;
} else {
+ nbytes = z->zalloc * PAGE_SIZE;
/*
* We can wait, so just do normal kernel map allocation
*/
- item = (void *) kmem_alloc(kernel_map, z->zalloc * PAGE_SIZE);
- nitems = (z->zalloc * PAGE_SIZE) / z->zsize;
+ item = (void *) kmem_alloc(kernel_map, nbytes);
+
+#if 0
+ if (z->zname)
+ printf("zalloc: %s, %d (0x%x --> 0x%x)\n",
+ z->zname, z->zalloc, item, (char *)item + nbytes);
+ else
+ printf("zalloc: XXX(%d), %d (0x%x --> 0x%x)\n",
+ z->zsize, z->zalloc, item, (char *)item + nbytes);
+
+ for(i=0;i<nbytes;i+=PAGE_SIZE) {
+ printf("(%x, %x)", (char *) item + i, pmap_kextract( (char *) item + i));
+ }
+ printf("\n");
+#endif
+ nitems = nbytes / z->zsize;
}
z->ztotal += nitems;
@@ -294,14 +317,22 @@ _zget(vm_zone_t z) {
if (nitems != 0) {
nitems -= 1;
for (i = 0; i < nitems; i++) {
- * (void **) item = z->zitems;
+ ((void **) item)[0] = z->zitems;
+#if defined(DIAGNOSTIC)
+ ((void **) item)[1] = (void *) ZENTRY_FREE;
+#endif
z->zitems = item;
(char *) item += z->zsize;
}
z->zfreecnt += nitems;
} else if (z->zfreecnt > 0) {
item = z->zitems;
- z->zitems = *(void **) item;
+ z->zitems = ((void **) item)[0];
+#if defined(DIAGNOSTIC)
+ if (((void **) item)[1] != (void *) ZENTRY_FREE)
+ zerror(ZONE_ERROR_NOTFREE);
+ ((void **) item)[1] = 0;
+#endif
z->zfreecnt--;
} else {
item = NULL;
@@ -356,5 +387,28 @@ sysctl_vm_zone SYSCTL_HANDLER_ARGS
return (0);
}
+#if defined(DIAGNOSTIC)
+void
+zerror(int error) {
+ char *msg;
+ switch (error) {
+case ZONE_ERROR_INVALID:
+ msg = "zone: invalid zone";
+ break;
+case ZONE_ERROR_NOTFREE:
+ msg = "zone: entry not free";
+ break;
+case ZONE_ERROR_ALREADYFREE:
+ msg = "zone: freeing free entry";
+ break;
+default:
+ msg = "zone: invalid error";
+ break;
+ }
+
+ panic(msg);
+}
+#endif
+
SYSCTL_OID(_kern, OID_AUTO, zone, CTLTYPE_STRING|CTLFLAG_RD, \
NULL, 0, sysctl_vm_zone, "A", "Zone Info");
OpenPOWER on IntegriCloud