diff options
author | dyson <dyson@FreeBSD.org> | 1997-09-21 04:24:27 +0000 |
---|---|---|
committer | dyson <dyson@FreeBSD.org> | 1997-09-21 04:24:27 +0000 |
commit | e64b1984f97c6d987d7d36b61a3afe5028a08312 (patch) | |
tree | 325bcf17de3aad0383fb86548872026a7c3d2599 /sys/vm/vm_zone.c | |
parent | 1419fcb42b4e1e5a73f4574739f4c232fde357e2 (diff) | |
download | FreeBSD-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.c | 70 |
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"); |