? compile/STELLA ? i386/conf/BUNKO.hints ? i386/conf/BUNKO ? i386/conf/STELLA ? kern/.nfsA7cad4.4 Index: i386/i386/machdep.c =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/machdep.c,v retrieving revision 1.424 diff -u -r1.424 machdep.c --- i386/i386/machdep.c 2000/12/05 00:35:56 1.424 +++ i386/i386/machdep.c 2000/12/12 02:46:53 @@ -260,6 +260,7 @@ vm_size_t size = 0; int firstaddr; vm_offset_t minaddr; + int physmem_est; if (boothowto & RB_VERBOSE) bootverbose++; @@ -329,6 +330,18 @@ valloc(callwheel, struct callout_tailq, callwheelsize); /* + * Discount the physical memory larger than the size of kernel_map + * to avoid eating up all of KVA space. + * + * XXX We should check all of the free entries. + */ + if (kernel_map->first_free == NULL) { + printf("Warning: no free entries in kernel_map.\n"); + physmem_est = physmem; + } else + physmem_est = min(physmem, kernel_map->max_offset - kernel_map->min_offset); + + /* * The nominal buffer size (and minimum KVA allocation) is BKVASIZE. * For the first 64MB of ram nominally allocate sufficient buffers to * cover 1/4 of our ram. Beyond the first 64MB allocate additional @@ -340,10 +353,10 @@ int factor = 4 * BKVASIZE / PAGE_SIZE; nbuf = 50; - if (physmem > 1024) - nbuf += min((physmem - 1024) / factor, 16384 / factor); - if (physmem > 16384) - nbuf += (physmem - 16384) * 2 / (factor * 5); + if (physmem_est > 1024) + nbuf += min((physmem_est - 1024) / factor, 16384 / factor); + if (physmem_est > 16384) + nbuf += (physmem_est - 16384) * 2 / (factor * 5); } /* Index: kern/vfs_subr.c =================================================================== RCS file: /home/ncvs/src/sys/kern/vfs_subr.c,v retrieving revision 1.296 diff -u -r1.296 vfs_subr.c --- kern/vfs_subr.c 2000/12/08 21:50:37 1.296 +++ kern/vfs_subr.c 2000/12/12 02:46:57 @@ -75,6 +75,7 @@ #include #include #include +#include #include #include #include Index: ufs/ffs/ffs_vfsops.c =================================================================== RCS file: /home/ncvs/src/sys/ufs/ffs/ffs_vfsops.c,v retrieving revision 1.133 diff -u -r1.133 ffs_vfsops.c --- ufs/ffs/ffs_vfsops.c 2000/12/08 21:51:03 1.133 +++ ufs/ffs/ffs_vfsops.c 2000/12/12 02:47:14 @@ -1012,6 +1012,22 @@ * done by the calling routine. */ static int ffs_inode_hash_lock; +/* + * ffs_inode_hash_lock is a variable to manage mutual exclusion + * of vnode allocation and intertion to the hash, especially to + * avoid holding more than one vnodes for the same inode in the + * hash table. ffs_inode_hash_lock must hence be tested-and-set + * or cleared atomically, accomplished by ffs_inode_hash_mtx. + * + * As vnode allocation may block during MALLOC() and zone + * allocation, we should also do msleep() to give away the CPU + * if anyone else is allocating a vnode. lockmgr is not suitable + * here because someone else may insert to the hash table the + * vnode we are trying to allocate during our sleep, in which + * case the hash table needs to be examined once again after + * waking up. + */ +static struct mtx ffs_inode_hash_mtx; int ffs_vget(mp, ino, vpp) @@ -1039,14 +1055,17 @@ * case getnewvnode() or MALLOC() blocks, otherwise a duplicate * may occur! */ + mtx_enter(&ffs_inode_hash_mtx, MTX_DEF); if (ffs_inode_hash_lock) { while (ffs_inode_hash_lock) { ffs_inode_hash_lock = -1; - tsleep(&ffs_inode_hash_lock, PVM, "ffsvgt", 0); + msleep(&ffs_inode_hash_lock, &ffs_inode_hash_mtx, PVM, "ffsvgt", 0); } + mtx_exit(&ffs_inode_hash_mtx, MTX_DEF); goto restart; } ffs_inode_hash_lock = 1; + mtx_exit(&ffs_inode_hash_mtx, MTX_DEF); /* * If this MALLOC() is performed after the getnewvnode() @@ -1061,9 +1080,11 @@ /* Allocate a new vnode/inode. */ error = getnewvnode(VT_UFS, mp, ffs_vnodeop_p, &vp); if (error) { + mtx_enter(&ffs_inode_hash_mtx, MTX_DEF); if (ffs_inode_hash_lock < 0) wakeup(&ffs_inode_hash_lock); ffs_inode_hash_lock = 0; + mtx_exit(&ffs_inode_hash_mtx, MTX_DEF); *vpp = NULL; FREE(ip, ump->um_malloctype); return (error); @@ -1094,9 +1115,11 @@ */ ufs_ihashins(ip); + mtx_enter(&ffs_inode_hash_mtx, MTX_DEF); if (ffs_inode_hash_lock < 0) wakeup(&ffs_inode_hash_lock); ffs_inode_hash_lock = 0; + mtx_exit(&ffs_inode_hash_mtx, MTX_DEF); /* Read in the disk contents for the inode, copy into the inode. */ error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)), @@ -1213,6 +1236,7 @@ { softdep_initialize(); + mtx_init(&ffs_inode_hash_mtx, "ifsvgt", MTX_DEF); return (ufs_init(vfsp)); } Index: ufs/ifs/ifs_vfsops.c =================================================================== RCS file: /home/ncvs/src/sys/ufs/ifs/ifs_vfsops.c,v retrieving revision 1.2 diff -u -r1.2 ifs_vfsops.c --- ufs/ifs/ifs_vfsops.c 2000/10/29 14:54:54 1.2 +++ ufs/ifs/ifs_vfsops.c 2000/12/12 02:47:14 @@ -101,6 +101,7 @@ ifs_init(vfsp) struct vfsconf *vfsp; { + mtx_init(&ifs_inode_hash_mtx, "ifsvgt", MTX_DEF); return (ufs_init(vfsp)); } @@ -132,6 +133,22 @@ * done by the calling routine. */ static int ifs_inode_hash_lock; +/* + * ifs_inode_hash_lock is a variable to manage mutual exclusion + * of vnode allocation and intertion to the hash, especially to + * avoid holding more than one vnodes for the same inode in the + * hash table. ifs_inode_hash_lock must hence be tested-and-set + * or cleared atomically, accomplished by ifs_inode_hash_mtx. + * + * As vnode allocation may block during MALLOC() and zone + * allocation, we should also do msleep() to give away the CPU + * if anyone else is allocating a vnode. lockmgr is not suitable + * here because someone else may insert to the hash table the + * vnode we are trying to allocate during our sleep, in which + * case the hash table needs to be examined once again after + * waking up. + */ +static struct mtx ifs_inode_hash_mtx; int ifs_vget(mp, ino, vpp) @@ -159,14 +176,17 @@ * case getnewvnode() or MALLOC() blocks, otherwise a duplicate * may occur! */ + mtx_enter(&ifs_inode_hash_mtx, MTX_DEF); if (ifs_inode_hash_lock) { while (ifs_inode_hash_lock) { ifs_inode_hash_lock = -1; - tsleep(&ifs_inode_hash_lock, PVM, "ifsvgt", 0); + msleep(&ifs_inode_hash_lock, &ifs_inode_hash_mtx, PVM, "ifsvgt", 0); } + mtx_exit(&ifs_inode_hash_mtx, MTX_DEF); goto restart; } ifs_inode_hash_lock = 1; + mtx_exit(&ifs_inode_hash_mtx, MTX_DEF); /* * If this MALLOC() is performed after the getnewvnode() @@ -181,9 +201,11 @@ /* Allocate a new vnode/inode. */ error = getnewvnode(VT_UFS, mp, ifs_vnodeop_p, &vp); if (error) { + mtx_enter(&ifs_inode_hash_mtx, MTX_DEF); if (ifs_inode_hash_lock < 0) wakeup(&ifs_inode_hash_lock); ifs_inode_hash_lock = 0; + mtx_exit(&ifs_inode_hash_mtx, MTX_DEF); *vpp = NULL; FREE(ip, ump->um_malloctype); return (error); @@ -214,9 +236,11 @@ */ ufs_ihashins(ip); + mtx_enter(&ifs_inode_hash_mtx, MTX_DEF); if (ifs_inode_hash_lock < 0) wakeup(&ifs_inode_hash_lock); ifs_inode_hash_lock = 0; + mtx_exit(&ifs_inode_hash_mtx, MTX_DEF); /* Read in the disk contents for the inode, copy into the inode. */ error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)), Index: vm/default_pager.c =================================================================== RCS file: /home/ncvs/src/sys/vm/default_pager.c,v retrieving revision 1.25 diff -u -r1.25 default_pager.c --- vm/default_pager.c 2000/03/27 20:41:14 1.25 +++ vm/default_pager.c 2000/12/12 02:47:14 @@ -46,6 +46,7 @@ #include #include #include +#include #include static vm_object_t default_pager_alloc __P((void *, vm_ooffset_t, vm_prot_t, Index: vm/swap_pager.c =================================================================== RCS file: /home/ncvs/src/sys/vm/swap_pager.c,v retrieving revision 1.149 diff -u -r1.149 swap_pager.c --- vm/swap_pager.c 2000/12/08 21:51:06 1.149 +++ vm/swap_pager.c 2000/12/12 02:47:15 @@ -90,13 +90,16 @@ #include "opt_swap.h" #include +#include +#include +#include #include #include #include #include +#include #include #include -#include #define SWM_FREE 0x02 /* free, period */ #define SWM_POP 0x04 /* pop out */ @@ -273,7 +276,7 @@ void swap_pager_swap_init() { - int n; + int n, n2; /* * Number of in-transit swap bp operations. Don't @@ -311,15 +314,23 @@ * can hold 16 pages, so this is probably overkill. */ - n = cnt.v_page_count * 2; + n = min(cnt.v_page_count, (kernel_map->max_offset - kernel_map->min_offset) / PAGE_SIZE) * 2; + n2 = n; - swap_zone = zinit( - "SWAPMETA", - sizeof(struct swblock), - n, - ZONE_INTERRUPT, - 1 - ); + while (n > 0 + && (swap_zone = zinit( + "SWAPMETA", + sizeof(struct swblock), + n, + ZONE_INTERRUPT, + 1 + )) == NULL) + n >>= 1; + if (swap_zone == NULL) + printf("WARNING: failed to init swap_zone!\n"); + if (n2 != n) + printf("Swap zone entries reduced to %d.\n", n); + n2 = n; /* * Initialize our meta-data hash table. The swapper does not need to @@ -330,7 +341,7 @@ * swhash_mask: hash table index mask */ - for (n = 1; n < cnt.v_page_count / 4; n <<= 1) + for (n = 1; n < n2 ; n <<= 1) ; swhash = malloc(sizeof(struct swblock *) * n, M_VMPGDATA, M_WAITOK | M_ZERO); Index: vm/swap_pager.h =================================================================== RCS file: /home/ncvs/src/sys/vm/swap_pager.h,v retrieving revision 1.29 diff -u -r1.29 swap_pager.h --- vm/swap_pager.h 2000/10/13 16:44:34 1.29 +++ vm/swap_pager.h 2000/12/12 02:47:15 @@ -84,6 +84,7 @@ extern struct pagerlst swap_pager_un_object_list; extern int swap_pager_full; extern struct blist *swapblist; +extern vm_zone_t swap_zone; void swap_pager_putpages __P((vm_object_t, vm_page_t *, int, boolean_t, int *)); boolean_t swap_pager_haspage __P((vm_object_t object, vm_pindex_t pindex, int *before, int *after)); Index: vm/vm_kern.c =================================================================== RCS file: /home/ncvs/src/sys/vm/vm_kern.c,v retrieving revision 1.64 diff -u -r1.64 vm_kern.c --- vm/vm_kern.c 2000/05/21 12:50:17 1.64 +++ vm/vm_kern.c 2000/12/12 02:47:16 @@ -489,4 +489,3 @@ /* ... and ending with the completion of the above `insert' */ vm_map_unlock(m); } - Index: vm/vm_map.c =================================================================== RCS file: /home/ncvs/src/sys/vm/vm_map.c,v retrieving revision 1.192 diff -u -r1.192 vm_map.c --- vm/vm_map.c 2000/11/02 21:38:18 1.192 +++ vm/vm_map.c 2000/12/12 02:47:17 @@ -86,8 +86,8 @@ #include #include #include -#include #include +#include /* * Virtual memory maps provide for the mapping, protection, Index: vm/vm_object.c =================================================================== RCS file: /home/ncvs/src/sys/vm/vm_object.c,v retrieving revision 1.178 diff -u -r1.178 vm_object.c --- vm/vm_object.c 2000/11/22 07:42:04 1.178 +++ vm/vm_object.c 2000/12/12 02:47:18 @@ -84,10 +84,10 @@ #include #include #include +#include #include #include #include -#include static void vm_object_qcollapse __P((vm_object_t object)); Index: vm/vm_pageout.c =================================================================== RCS file: /home/ncvs/src/sys/vm/vm_pageout.c,v retrieving revision 1.165 diff -u -r1.165 vm_pageout.c --- vm/vm_pageout.c 2000/12/11 07:52:47 1.165 +++ vm/vm_pageout.c 2000/12/12 02:47:18 @@ -93,6 +93,7 @@ #include #include #include +#include #include #include Index: vm/vm_swap.c =================================================================== RCS file: /home/ncvs/src/sys/vm/vm_swap.c,v retrieving revision 1.105 diff -u -r1.105 vm_swap.c --- vm/vm_swap.c 2000/10/13 16:44:34 1.105 +++ vm/vm_swap.c 2000/12/12 02:47:19 @@ -53,6 +53,7 @@ #include #include #include +#include #include /* @@ -193,6 +194,13 @@ error = suser(p); if (error) return (error); + + /* + * Swap metadata may not fit in the KVM if we have physical + * memory of >1GB. + */ + if (swap_zone == NULL) + return (ENOMEM); NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->name, p); error = namei(&nd); Index: vm/vm_zone.c =================================================================== RCS file: /home/ncvs/src/sys/vm/vm_zone.c,v retrieving revision 1.34 diff -u -r1.34 vm_zone.c --- vm/vm_zone.c 2000/07/04 11:25:35 1.34 +++ vm/vm_zone.c 2000/12/12 02:47:19 @@ -80,8 +80,11 @@ zinitna(vm_zone_t z, vm_object_t obj, char *name, int size, int nentries, int flags, int zalloc) { - int totsize; + int totsize, oldzflags; + vm_zone_t oldzlist; + oldzflags = z->zflags; + oldzlist = zlist; if ((z->zflags & ZONE_BOOT) == 0) { z->zsize = (size + ZONE_ROUNDING - 1) & ~(ZONE_ROUNDING - 1); simple_lock_init(&z->zlock); @@ -112,8 +115,12 @@ zone_kmem_kvaspace += totsize; z->zkva = kmem_alloc_pageable(kernel_map, totsize); - if (z->zkva == 0) + if (z->zkva == 0) { + /* Clean up the zlist in case we messed it. */ + if ((oldzflags & ZONE_BOOT) == 0) + zlist = oldzlist; return 0; + } z->zpagemax = totsize / PAGE_SIZE; if (obj == NULL) { @@ -156,11 +163,10 @@ { vm_zone_t z; - z = (vm_zone_t) malloc(sizeof (struct vm_zone), M_ZONE, M_NOWAIT); + z = (vm_zone_t) malloc(sizeof (struct vm_zone), M_ZONE, M_NOWAIT | M_ZERO); if (z == NULL) return NULL; - z->zflags = 0; if (zinitna(z, NULL, name, size, nentries, flags, zalloc) == 0) { free(z, M_ZONE); return NULL;