From e937bc9bfd3323cfbec01c3cdb7c91fe4c2bbe7d Mon Sep 17 00:00:00 2001 From: cgd Date: Fri, 15 Apr 1994 07:04:03 +0000 Subject: [PATCH] convert vm system to use new queues. I'll never write code w/queues again. --- sys/arch/amiga/amiga/symbols.raw | 5 +- sys/arch/hp300/hp300/symbols.raw | 5 +- sys/arch/i386/i386/machdep.c | 4 +- sys/arch/i386/i386/symbols.raw | 5 +- sys/arch/pmax/pmax/symbols.raw | 5 +- sys/sys/vmmeter.h | 74 +++++----- sys/vm/device_pager.c | 33 ++--- sys/vm/device_pager.h | 4 +- sys/vm/pmap.h | 23 ++- sys/vm/swap_pager.c | 75 +++++----- sys/vm/vm.h | 42 ++---- sys/vm/vm_fault.c | 22 ++- sys/vm/vm_glue.c | 14 +- sys/vm/vm_init.c | 4 +- sys/vm/vm_mmap.c | 24 ++-- sys/vm/vm_object.c | 234 ++++++++----------------------- sys/vm/vm_object.h | 27 ++-- sys/vm/vm_page.c | 179 +++++++++++------------ sys/vm/vm_page.h | 48 ++----- sys/vm/vm_pageout.c | 111 +++++++-------- sys/vm/vm_pageout.h | 4 +- sys/vm/vm_pager.c | 15 +- sys/vm/vm_param.h | 25 ++-- sys/vm/vnode_pager.c | 17 ++- 24 files changed, 423 insertions(+), 576 deletions(-) diff --git a/sys/arch/amiga/amiga/symbols.raw b/sys/arch/amiga/amiga/symbols.raw index 50812fcdfb44..6e12e42dbc03 100644 --- a/sys/arch/amiga/amiga/symbols.raw +++ b/sys/arch/amiga/amiga/symbols.raw @@ -1,5 +1,5 @@ # @(#)symbols.raw 7.6 (Berkeley) 5/8/91 -# $Id: symbols.raw,v 1.2 1994/02/11 07:00:01 chopps Exp $ +# $Id: symbols.raw,v 1.3 1994/04/15 07:04:03 cgd Exp $ _version #dmesg @@ -29,9 +29,8 @@ # _ndh11 #vmstat _cp_time - _rate _total - _sum + _cnt # _rectime # _pgintime _dk_xfer diff --git a/sys/arch/hp300/hp300/symbols.raw b/sys/arch/hp300/hp300/symbols.raw index fffd0e1b5713..ad6b19b2abb3 100644 --- a/sys/arch/hp300/hp300/symbols.raw +++ b/sys/arch/hp300/hp300/symbols.raw @@ -1,5 +1,5 @@ # from: @(#)symbols.raw 7.6 (Berkeley) 5/8/91 -# $Id: symbols.raw,v 1.2 1993/05/22 07:57:45 cgd Exp $ +# $Id: symbols.raw,v 1.3 1994/04/15 07:04:13 cgd Exp $ _version #dmesg @@ -29,9 +29,8 @@ # _ndh11 #vmstat _cp_time - _rate _total - _sum + _cnt # _rectime # _pgintime _dk_xfer diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index 86103afb159b..87e5584a18e7 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 - * $Id: machdep.c,v 1.97 1994/04/08 19:15:52 mycroft Exp $ + * $Id: machdep.c,v 1.98 1994/04/15 07:04:22 cgd Exp $ */ #include @@ -224,7 +224,7 @@ cpu_startup() for (i = 1; i < ncallout; i++) callout[i-1].c_next = &callout[i]; - printf("avail mem = %d\n", ptoa(vm_page_free_count)); + printf("avail mem = %d\n", ptoa(cnt.v_free_count)); printf("using %d buffers containing %d bytes of memory\n", nbuf, bufpages * CLBYTES); diff --git a/sys/arch/i386/i386/symbols.raw b/sys/arch/i386/i386/symbols.raw index 304ad8bdfa8a..1dce59042e0c 100644 --- a/sys/arch/i386/i386/symbols.raw +++ b/sys/arch/i386/i386/symbols.raw @@ -1,5 +1,5 @@ # from: @(#)symbols.raw 7.6 (Berkeley) 5/8/91 -# $Id: symbols.raw,v 1.3 1993/05/22 08:00:01 cgd Exp $ +# $Id: symbols.raw,v 1.4 1994/04/15 07:04:26 cgd Exp $ #gdb _IdlePTD @@ -36,9 +36,8 @@ _swapmap #vmstat _cp_time - _rate _total - _sum + _cnt # _rectime # _pgintime _dk_xfer diff --git a/sys/arch/pmax/pmax/symbols.raw b/sys/arch/pmax/pmax/symbols.raw index ecef7bf0a020..e1b0ff17391e 100644 --- a/sys/arch/pmax/pmax/symbols.raw +++ b/sys/arch/pmax/pmax/symbols.raw @@ -1,5 +1,5 @@ # from: @(#)symbols.raw 7.6 (Berkeley) 5/8/91 -# $Id: symbols.raw,v 1.1.1.1 1993/10/12 03:22:34 deraadt Exp $ +# $Id: symbols.raw,v 1.2 1994/04/15 07:04:30 cgd Exp $ _version #dmesg @@ -29,9 +29,8 @@ # _ndh11 #vmstat _cp_time - _rate _total - _sum + _cnt # _rectime # _pgintime _dk_xfer diff --git a/sys/sys/vmmeter.h b/sys/sys/vmmeter.h index 09fcf3105397..a0234174e1eb 100644 --- a/sys/sys/vmmeter.h +++ b/sys/sys/vmmeter.h @@ -31,57 +31,63 @@ * SUCH DAMAGE. * * from: @(#)vmmeter.h 7.3 (Berkeley) 5/5/91 - * $Id: vmmeter.h,v 1.3 1993/05/20 16:23:51 cgd Exp $ + * $Id: vmmeter.h,v 1.4 1994/04/15 07:04:36 cgd Exp $ */ #ifndef _SYS_VMMETER_H_ #define _SYS_VMMETER_H_ /* - * Virtual memory related instrumentation + * System wide statistics counters. */ -struct vmmeter -{ -#define v_first v_swtch +struct vmmeter { + /* + * General system activity. + */ unsigned v_swtch; /* context switches */ unsigned v_trap; /* calls to trap */ unsigned v_syscall; /* calls to syscall() */ unsigned v_intr; /* device interrupts */ unsigned v_soft; /* software interrupts */ - unsigned v_pdma; /* pseudo-dma interrupts */ + unsigned v_faults; /* total faults taken */ + /* + * Virtual memory activity. + */ + unsigned v_lookups; /* object cache lookups */ + unsigned v_hits; /* object cache hits */ + unsigned v_vm_faults; /* number of address memory faults */ + unsigned v_cow_faults; /* number of copy-on-writes */ + unsigned v_swpin; /* swapins */ + unsigned v_swpout; /* swapouts */ unsigned v_pswpin; /* pages swapped in */ unsigned v_pswpout; /* pages swapped out */ - unsigned v_pgin; /* pageins */ - unsigned v_pgout; /* pageouts */ + unsigned v_pageins; /* number of pageins */ + unsigned v_pageouts; /* number of pageouts */ unsigned v_pgpgin; /* pages paged in */ unsigned v_pgpgout; /* pages paged out */ unsigned v_intrans; /* intransit blocking page faults */ - unsigned v_pgrec; /* total page reclaims */ - unsigned v_xsfrec; /* found in free list rather than on swapdev */ - unsigned v_xifrec; /* found in free list rather than in filsys */ - unsigned v_exfod; /* pages filled on demand from executables */ - unsigned v_zfod; /* pages zero filled on demand */ - unsigned v_vrfod; /* fills of pages mapped by vread() */ - unsigned v_nexfod; /* number of exfod's created */ - unsigned v_nzfod; /* number of zfod's created */ - unsigned v_nvrfod; /* number of vrfod's created */ - unsigned v_pgfrec; /* page reclaims from free list */ - unsigned v_faults; /* total faults taken */ - unsigned v_scan; /* scans in page out daemon */ + unsigned v_reactivated; /* number of pages reactivated from free list */ unsigned v_rev; /* revolutions of the hand */ - unsigned v_seqfree; /* pages taken from sequential programs */ + unsigned v_scan; /* scans in page out daemon */ unsigned v_dfree; /* pages freed by daemon */ - unsigned v_fastpgrec; /* fast reclaims in locore */ -#ifdef tahoe - unsigned v_fpe; /* floating point emulation traps */ - unsigned v_align; /* alignment emulation traps */ -#endif -#define v_last v_fastpgrec - unsigned v_swpin; /* swapins */ - unsigned v_swpout; /* swapouts */ + unsigned v_pfree; /* pages freed by exiting processes */ + unsigned v_zfod; /* pages zero filled on demand */ + unsigned v_nzfod; /* number of zfod's created */ + /* + * Distribution of page usages. + */ + unsigned v_page_size; /* page size in bytes */ + unsigned v_kernel_pages;/* number of pages in use by kernel */ + unsigned v_free_target; /* number of pages desired free */ + unsigned v_free_min; /* minimum number of pages desired free */ + unsigned v_free_count; /* number of pages free */ + unsigned v_wire_count; /* number of pages wired down */ + unsigned v_active_count;/* number of pages active */ + unsigned v_inactive_target; /* number of pages desired inactive */ + unsigned v_inactive_count; /* number of pages inactive */ }; #ifdef KERNEL -struct vmmeter cnt, rate, sum; +struct vmmeter cnt; #endif /* systemwide totals computed every five seconds */ @@ -96,10 +102,10 @@ struct vmtotal long t_avm; /* active virtual memory */ long t_rm; /* total real memory in use */ long t_arm; /* active real memory */ - long t_vmtxt; /* virtual memory used by text */ - long t_avmtxt; /* active virtual memory used by text */ - long t_rmtxt; /* real memory used by text */ - long t_armtxt; /* active real memory used by text */ + long t_vmshr; /* shared virtual memory */ + long t_avmshr; /* active shared virtual memory */ + long t_rmshr; /* shared real memory */ + long t_armshr; /* active shared real memory */ long t_free; /* free memory pages */ }; #ifdef KERNEL diff --git a/sys/vm/device_pager.c b/sys/vm/device_pager.c index 9a56df179352..fe4ea266744a 100644 --- a/sys/vm/device_pager.c +++ b/sys/vm/device_pager.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * from: @(#)device_pager.c 8.1 (Berkeley) 6/11/93 - * $Id: device_pager.c,v 1.13 1994/03/17 02:51:57 cgd Exp $ + * $Id: device_pager.c,v 1.14 1994/04/15 07:04:40 cgd Exp $ */ /* @@ -56,8 +56,8 @@ #include #include -queue_head_t dev_pager_list; /* list of managed devices */ -queue_head_t dev_pager_fakelist; /* list of available vm_page_t's */ +struct pagerlst dev_pager_list; /* list of managed devices */ +struct pglist dev_pager_fakelist; /* list of available vm_page_t's */ #ifdef DEBUG int dpagerdebug = 0; @@ -95,8 +95,8 @@ dev_pager_init() if (dpagerdebug & DDB_FOLLOW) printf("dev_pager_init()\n"); #endif - queue_init(&dev_pager_list); - queue_init(&dev_pager_fakelist); + TAILQ_INIT(&dev_pager_list); + TAILQ_INIT(&dev_pager_fakelist); } static vm_pager_t @@ -172,7 +172,7 @@ top: pager->pg_ops = &devicepagerops; pager->pg_type = PG_DEVICE; pager->pg_data = (caddr_t)devp; - queue_init(&devp->devp_pglist); + TAILQ_INIT(&devp->devp_pglist); /* * Allocate object and associate it with the pager. */ @@ -190,7 +190,7 @@ top: free((caddr_t)pager, M_VMPAGER); goto top; } - queue_enter(&dev_pager_list, pager, vm_pager_t, pg_list); + TAILQ_INSERT_TAIL(&dev_pager_list, pager, pg_list); #ifdef DEBUG if (dpagerdebug & DDB_ALLOC) { printf("dev_pager_alloc: pager %x devp %x object %x\n", @@ -225,7 +225,7 @@ dev_pager_dealloc(pager) if (dpagerdebug & DDB_FOLLOW) printf("dev_pager_dealloc(%x)\n", pager); #endif - queue_remove(&dev_pager_list, pager, vm_pager_t, pg_list); + TAILQ_REMOVE(&dev_pager_list, pager, pg_list); /* * Get the object. * Note: cannot use vm_object_lookup since object has already @@ -240,8 +240,8 @@ dev_pager_dealloc(pager) /* * Free up our fake pages. */ - while (!queue_empty(&devp->devp_pglist)) { - queue_remove_first(&devp->devp_pglist, m, vm_page_t, pageq); + while ((m = devp->devp_pglist.tqh_first) != NULL) { + TAILQ_REMOVE(&devp->devp_pglist, m, pageq); dev_pager_putfake(m); } free((caddr_t)devp, M_VMPGDATA); @@ -284,8 +284,8 @@ dev_pager_getpage(pager, m, sync) * up the original. */ page = dev_pager_getfake(paddr); - queue_enter(&((dev_pager_t)pager->pg_data)->devp_pglist, - page, vm_page_t, pageq); + TAILQ_INSERT_TAIL(&((dev_pager_t)pager->pg_data)->devp_pglist, page, + pageq); vm_object_lock(object); vm_page_lock_queues(); vm_page_free(m); @@ -333,14 +333,15 @@ dev_pager_getfake(paddr) vm_page_t m; int i; - if (queue_empty(&dev_pager_fakelist)) { + if (dev_pager_fakelist.tqh_first == NULL) { m = (vm_page_t)malloc(PAGE_SIZE, M_VMPGDATA, M_WAITOK); for (i = PAGE_SIZE / sizeof(*m); i > 0; i--) { - queue_enter(&dev_pager_fakelist, m, vm_page_t, pageq); + TAILQ_INSERT_TAIL(&dev_pager_fakelist, m, pageq); m++; } } - queue_remove_first(&dev_pager_fakelist, m, vm_page_t, pageq); + m = dev_pager_fakelist.tqh_first; + TAILQ_REMOVE(&dev_pager_fakelist, m, pageq); m->flags = PG_BUSY | PG_CLEAN | PG_FAKE | PG_FICTITIOUS; m->phys_addr = paddr; m->wire_count = 1; @@ -355,5 +356,5 @@ dev_pager_putfake(m) if (!(m->flags & PG_FICTITIOUS)) panic("dev_pager_putfake: bad page"); #endif - queue_enter(&dev_pager_fakelist, m, vm_page_t, pageq); + TAILQ_INSERT_TAIL(&dev_pager_fakelist, m, pageq); } diff --git a/sys/vm/device_pager.h b/sys/vm/device_pager.h index c5c5369380be..1a113a07e243 100644 --- a/sys/vm/device_pager.h +++ b/sys/vm/device_pager.h @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * from: @(#)device_pager.h 8.1 (Berkeley) 6/11/93 - * $Id: device_pager.h,v 1.5 1993/12/20 12:39:57 cgd Exp $ + * $Id: device_pager.h,v 1.6 1994/04/15 07:04:42 cgd Exp $ */ #ifndef _DEVICE_PAGER_ @@ -46,7 +46,7 @@ * Device pager private data. */ struct devpager { - queue_head_t devp_pglist; /* list of pages allocated */ + struct pglist devp_pglist; /* list of pages allocated */ vm_object_t devp_object; /* object representing this device */ }; typedef struct devpager *dev_pager_t; diff --git a/sys/vm/pmap.h b/sys/vm/pmap.h index 3d5baa2821e5..01d9c65eb753 100644 --- a/sys/vm/pmap.h +++ b/sys/vm/pmap.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)pmap.h 7.4 (Berkeley) 5/7/91 - * $Id: pmap.h,v 1.5 1993/08/29 12:12:20 brezak Exp $ + * $Id: pmap.h,v 1.6 1994/04/15 07:04:43 cgd Exp $ * * * Copyright (c) 1987, 1990 Carnegie-Mellon University. @@ -63,18 +63,29 @@ * rights to redistribute these changes. */ -#ifndef _VM_PMAP_H_ -#define _VM_PMAP_H_ - /* * Machine address mapping definitions -- machine-independent * section. [For machine-dependent section, see "machine/pmap.h".] */ +#ifndef _PMAP_VM_ +#define _PMAP_VM_ + +/* + * Each machine dependent implementation is expected to + * keep certain statistics. They may do this anyway they + * so choose, but are expected to return the statistics + * in the following structure. + */ +struct pmap_statistics { + long resident_count; /* # of pages mapped (total)*/ + long wired_count; /* # of pages wired */ +}; +typedef struct pmap_statistics *pmap_statistics_t; + #include #ifdef KERNEL - /* * Currently this option is used on the i386 to be able to handle the * memory from 0-640k and 1M+. @@ -168,4 +179,4 @@ boolean_t pmap_access(); extern pmap_t kernel_pmap; #endif -#endif /* !_VM_PMAP_H_ */ +#endif /* _PMAP_VM_ */ diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c index 2487a19f7cbd..024adb76b481 100644 --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -38,7 +38,7 @@ * from: Utah $Hdr: swap_pager.c 1.4 91/04/30$ * * from: @(#)swap_pager.c 8.1 (Berkeley) 6/11/93 - * $Id: swap_pager.c,v 1.16 1994/01/13 18:20:36 cgd Exp $ + * $Id: swap_pager.c,v 1.17 1994/04/15 07:04:45 cgd Exp $ */ /* @@ -80,15 +80,19 @@ int swpagerdebug = 0x100; #define SDB_FULL 0x080 #define SDB_ANOM 0x100 #define SDB_ANOMPANIC 0x200 +#define SDB_CLUSTER 0x400 +#define SDB_PARANOIA 0x800 #endif +TAILQ_HEAD(swpclean, swpagerclean); + struct swpagerclean { - queue_head_t spc_list; - int spc_flags; - struct buf *spc_bp; - sw_pager_t spc_swp; - vm_offset_t spc_kva; - vm_page_t spc_m; + TAILQ_ENTRY(swpagerclean) spc_list; + int spc_flags; + struct buf *spc_bp; + sw_pager_t spc_swp; + vm_offset_t spc_kva; + vm_page_t spc_m; } swcleanlist[NPENDINGIO]; typedef struct swpagerclean *swp_clean_t; @@ -115,9 +119,9 @@ int swap_pager_poip; /* pageouts in progress */ int swap_pager_piip; /* pageins in progress */ #endif -queue_head_t swap_pager_inuse; /* list of pending page cleans */ -queue_head_t swap_pager_free; /* list of free pager clean structs */ -queue_head_t swap_pager_list; /* list of "named" anon regions */ +struct swpclean swap_pager_inuse; /* list of pending page cleans */ +struct swpclean swap_pager_free; /* list of free pager clean structs */ +struct pagerlst swap_pager_list; /* list of "named" anon regions */ static int swap_pager_finish __P((swp_clean_t)); static void swap_pager_init __P((void)); @@ -155,15 +159,15 @@ swap_pager_init() printf("swpg_init()\n"); #endif dfltpagerops = &swappagerops; - queue_init(&swap_pager_list); + TAILQ_INIT(&swap_pager_list); /* * Initialize clean lists */ - queue_init(&swap_pager_inuse); - queue_init(&swap_pager_free); + TAILQ_INIT(&swap_pager_inuse); + TAILQ_INIT(&swap_pager_free); for (i = 0, spc = swcleanlist; i < NPENDINGIO; i++, spc++) { - queue_enter(&swap_pager_free, spc, swp_clean_t, spc_list); + TAILQ_INSERT_TAIL(&swap_pager_free, spc, spc_list); spc->spc_flags = SPC_FREE; } @@ -290,7 +294,7 @@ swap_pager_alloc(handle, size, prot, foff) vm_object_t object; swp->sw_flags = SW_NAMED; - queue_enter(&swap_pager_list, pager, vm_pager_t, pg_list); + TAILQ_INSERT_TAIL(&swap_pager_list, pager, pg_list); /* * Consistant with other pagers: return with object * referenced. Can't do this with handle == NULL @@ -301,7 +305,8 @@ swap_pager_alloc(handle, size, prot, foff) vm_object_setpager(object, pager, 0, FALSE); } else { swp->sw_flags = 0; - queue_init(&pager->pg_list); + pager->pg_list.tqe_next = NULL; + pager->pg_list.tqe_prev = NULL; } pager->pg_handle = handle; pager->pg_ops = &swappagerops; @@ -339,7 +344,7 @@ swap_pager_dealloc(pager) */ swp = (sw_pager_t) pager->pg_data; if (swp->sw_flags & SW_NAMED) { - queue_remove(&swap_pager_list, pager, vm_pager_t, pg_list); + TAILQ_INSERT_TAIL(&swap_pager_list, pager, pg_list); swp->sw_flags &= ~SW_NAMED; } #ifdef DEBUG @@ -517,10 +522,10 @@ swap_pager_io(swp, m, flags) * are available, we try again later. */ else if (swap_pager_clean(m, B_WRITE) || - queue_empty(&swap_pager_free)) { + swap_pager_free.tqh_first == NULL) { #ifdef DEBUG if ((swpagerdebug & SDB_ANOM) && - !queue_empty(&swap_pager_free)) + swap_pager_free.tqh_first != NULL) printf("swap_pager_io: page %x already cleaning\n", m); #endif return(VM_PAGER_FAIL); @@ -618,11 +623,11 @@ swap_pager_io(swp, m, flags) */ if ((flags & (B_READ|B_ASYNC)) == B_ASYNC) { #ifdef DEBUG - if (queue_empty(&swap_pager_free)) + if (swap_pager_free.tqh_first == NULL) panic("swpg_io: lost spc"); #endif - queue_remove_first(&swap_pager_free, - spc, swp_clean_t, spc_list); + spc = swap_pager_free.tqh_first; + TAILQ_REMOVE(&swap_pager_free, spc, spc_list); #ifdef DEBUG if (spc->spc_flags != SPC_FREE) panic("swpg_io: bad free spc"); @@ -636,7 +641,7 @@ swap_pager_io(swp, m, flags) bp->b_iodone = swap_pager_iodone; s = splbio(); swp->sw_poip++; - queue_enter(&swap_pager_inuse, spc, swp_clean_t, spc_list); + TAILQ_INSERT_TAIL(&swap_pager_inuse, spc, spc_list); #ifdef DEBUG swap_pager_poip++; @@ -728,12 +733,12 @@ swap_pager_clean(m, rw) * at splbio() to avoid conflicts with swap_pager_iodone. */ s = splbio(); - spc = (swp_clean_t) queue_first(&swap_pager_inuse); - while (!queue_end(&swap_pager_inuse, (queue_entry_t)spc)) { + for (spc = swap_pager_inuse.tqh_first; + spc != NULL; + spc = spc->spc_list.tqe_next) { if ((spc->spc_flags & SPC_DONE) && swap_pager_finish(spc)) { - queue_remove(&swap_pager_inuse, spc, - swp_clean_t, spc_list); + TAILQ_REMOVE(&swap_pager_inuse, spc, spc_list); break; } if (m && m == spc->spc_m) { @@ -744,14 +749,15 @@ swap_pager_clean(m, rw) #endif tspc = spc; } - spc = (swp_clean_t) queue_next(&spc->spc_list); } /* * No operations done, thats all we can do for now. */ - if (queue_end(&swap_pager_inuse, (queue_entry_t)spc)) + if (spc == NULL) { + splx(s); break; + } splx(s); /* @@ -768,7 +774,7 @@ swap_pager_clean(m, rw) } spc->spc_flags = SPC_FREE; vm_pager_unmap_page(spc->spc_kva); - queue_enter(&swap_pager_free, spc, swp_clean_t, spc_list); + TAILQ_INSERT_TAIL(&swap_pager_free, spc, spc_list); #ifdef DEBUG if (swpagerdebug & SDB_WRITE) printf("swpg_clean: free spc %x\n", spc); @@ -872,14 +878,13 @@ swap_pager_iodone(bp) printf("swpg_iodone(%x)\n", bp); #endif s = splbio(); - spc = (swp_clean_t) queue_first(&swap_pager_inuse); - while (!queue_end(&swap_pager_inuse, (queue_entry_t)spc)) { + for (spc = swap_pager_inuse.tqh_first; + spc != NULL; + spc = spc->spc_list.tqe_next) if (spc->spc_bp == bp) break; - spc = (swp_clean_t) queue_next(&spc->spc_list); - } #ifdef DEBUG - if (queue_end(&swap_pager_inuse, (queue_entry_t)spc)) + if (spc == NULL) panic("swap_pager_iodone: bp not found"); #endif diff --git a/sys/vm/vm.h b/sys/vm/vm.h index 993b7f62de44..61fd7077b115 100644 --- a/sys/vm/vm.h +++ b/sys/vm/vm.h @@ -31,11 +31,11 @@ * SUCH DAMAGE. * * from: @(#)vm.h 7.1 (Berkeley) 5/5/91 - * $Id: vm.h,v 1.9 1994/03/17 02:52:02 cgd Exp $ + * $Id: vm.h,v 1.10 1994/04/15 07:04:46 cgd Exp $ */ -#ifndef _VM_H_ -#define _VM_H_ +#ifndef VM_H +#define VM_H typedef int vm_inherit_t; /* XXX: inheritance codes */ @@ -43,30 +43,30 @@ union vm_map_object; typedef union vm_map_object vm_map_object_t; struct vm_map_entry; -typedef struct vm_map_entry *vm_map_entry_t; - +typedef struct vm_map_entry *vm_map_entry_t; + struct vm_map; typedef struct vm_map *vm_map_t; - -struct vm_object; + +struct vm_object; typedef struct vm_object *vm_object_t; - + struct vm_page; typedef struct vm_page *vm_page_t; - + struct pager_struct; typedef struct pager_struct *vm_pager_t; #include -#include /* sys/queue.h in 4.4 */ +#include #include #include #include #include -#include -#include -#include #include +#include +#include +#include /* * Shareable process virtual address space. @@ -89,18 +89,4 @@ struct vmspace { caddr_t vm_daddr; /* user virtual address of data XXX */ caddr_t vm_maxsaddr; /* user VA at max stack growth */ }; - -struct vmspace *vmspace_alloc __P((vm_offset_t min, vm_offset_t max, - int pageable)); -struct vmspace *vmspace_fork __P((struct vmspace *)); -void vmspace_free __P((struct vmspace *)); - -int vm_fault __P((vm_map_t, vm_offset_t, vm_prot_t, boolean_t)); -void vm_fault_wire __P((vm_map_t, vm_offset_t, vm_offset_t)); -void vm_fault_unwire __P((vm_map_t, vm_offset_t, vm_offset_t)); -void vm_fault_copy_entry __P((vm_map_t, vm_map_t, vm_map_entry_t, vm_map_entry_t)); - -void vslock __P((caddr_t, u_int)); -void vsunlock __P((caddr_t, u_int, int)); - -#endif /* !_VM_VM_H_ */ +#endif /* VM_H */ diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 0200f44c9762..dff11c6eff2f 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)vm_fault.c 7.6 (Berkeley) 5/7/91 - * $Id: vm_fault.c,v 1.11 1994/03/17 02:52:04 cgd Exp $ + * $Id: vm_fault.c,v 1.12 1994/04/15 07:04:48 cgd Exp $ * * * Copyright (c) 1987, 1990 Carnegie-Mellon University. @@ -114,7 +114,7 @@ vm_fault(map, vaddr, fault_type, change_wiring) vm_page_t old_m; vm_object_t next_object; - vm_stat.faults++; /* needs lock XXX */ + cnt.v_vm_faults++; /* needs lock XXX */ /* * Recovery actions */ @@ -269,18 +269,16 @@ thread_wakeup(&vm_pages_needed); /* XXX! */ vm_page_lock_queues(); if (m->flags & PG_INACTIVE) { - queue_remove(&vm_page_queue_inactive, m, - vm_page_t, pageq); + TAILQ_REMOVE(&vm_page_queue_inactive, m, pageq); m->flags &= ~PG_INACTIVE; - vm_page_inactive_count--; - vm_stat.reactivations++; + cnt.v_inactive_count--; + cnt.v_reactivated++; } if (m->flags & PG_ACTIVE) { - queue_remove(&vm_page_queue_active, m, - vm_page_t, pageq); + TAILQ_REMOVE(&vm_page_queue_active, m, pageq); m->flags &= ~PG_ACTIVE; - vm_page_active_count--; + cnt.v_active_count--; } vm_page_unlock_queues(); @@ -340,7 +338,7 @@ thread_wakeup(&vm_pages_needed); /* XXX! */ */ m = vm_page_lookup(object, offset); - vm_stat.pageins++; + cnt.v_pageins++; m->flags &= ~PG_FAKE; pmap_clear_modify(VM_PAGE_TO_PHYS(m)); break; @@ -411,7 +409,7 @@ thread_wakeup(&vm_pages_needed); /* XXX! */ first_m = NULL; vm_page_zero_fill(m); - vm_stat.zero_fill_count++; + cnt.v_zfod++; m->flags &= ~PG_FAKE; break; } @@ -505,7 +503,7 @@ thread_wakeup(&vm_pages_needed); /* XXX! */ * Only use the new page below... */ - vm_stat.cow_faults++; + cnt.v_cow_faults++; m = first_m; object = first_object; offset = first_offset; diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c index ced5c84e80ee..da1395a60a94 100644 --- a/sys/vm/vm_glue.c +++ b/sys/vm/vm_glue.c @@ -287,7 +287,7 @@ vm_init_limits(p) p->p_rlimit[RLIMIT_DATA].rlim_cur = DFLDSIZ; p->p_rlimit[RLIMIT_DATA].rlim_max = MAXDSIZ; p->p_rlimit[RLIMIT_RSS].rlim_cur = p->p_rlimit[RLIMIT_RSS].rlim_max = - ptoa(vm_page_free_count); + ptoa(cnt.v_free_count); } #include @@ -354,12 +354,12 @@ noswap: */ size = round_page(ctob(UPAGES)); addr = (vm_offset_t) p->p_addr; - if (vm_page_free_count > atop(size)) { + if (cnt.v_free_count > atop(size)) { #ifdef DEBUG if (swapdebug & SDB_SWAPIN) printf("swapin: pid %d(%s)@%x, pri %d free %d\n", p->p_pid, p->p_comm, p->p_addr, - ppri, vm_page_free_count); + ppri, cnt.v_free_count); #endif vm_map_pageable(kernel_map, addr, addr+size, FALSE); (void) splclock(); @@ -377,14 +377,14 @@ noswap: #ifdef DEBUG if (swapdebug & SDB_FOLLOW) printf("sched: no room for pid %d(%s), free %d\n", - p->p_pid, p->p_comm, vm_page_free_count); + p->p_pid, p->p_comm, cnt.v_free_count); #endif (void) splhigh(); VM_WAIT; (void) spl0(); #ifdef DEBUG if (swapdebug & SDB_FOLLOW) - printf("sched: room again, free %d\n", vm_page_free_count); + printf("sched: room again, free %d\n", cnt.v_free_count); #endif goto loop; } @@ -445,7 +445,7 @@ swapout_threads() * it (UPAGES pages). */ if (didswap == 0 && - vm_page_free_count <= atop(round_page(ctob(UPAGES)))) { + cnt.v_free_count <= atop(round_page(ctob(UPAGES)))) { if ((p = outp) == 0) p = outp2; #ifdef DEBUG @@ -468,7 +468,7 @@ swapout(p) if (swapdebug & SDB_SWAPOUT) printf("swapout: pid %d(%s)@%x, stat %x pri %d free %d\n", p->p_pid, p->p_comm, p->p_addr, p->p_stat, - p->p_slptime, vm_page_free_count); + p->p_slptime, cnt.v_free_count); #endif size = round_page(ctob(UPAGES)); addr = (vm_offset_t) p->p_addr; diff --git a/sys/vm/vm_init.c b/sys/vm/vm_init.c index f533fd367982..41f043ddac30 100644 --- a/sys/vm/vm_init.c +++ b/sys/vm/vm_init.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)vm_init.c 7.3 (Berkeley) 4/21/91 - * $Id: vm_init.c,v 1.5 1993/12/20 12:40:06 cgd Exp $ + * $Id: vm_init.c,v 1.6 1994/04/15 07:04:50 cgd Exp $ * * * Copyright (c) 1987, 1990 Carnegie-Mellon University. @@ -94,7 +94,7 @@ void vm_mem_init() * From here on, all physical memory is accounted for, * and we use only virtual addresses. */ - + vm_set_page_size(); #ifndef MACHINE_NONCONTIG virtual_avail = vm_page_startup(avail_start, avail_end, virtual_avail); #else diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index eb4d5000c458..21bca96d281b 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -37,7 +37,7 @@ * * from: Utah Hdr: vm_mmap.c 1.3 90/01/21 * from: @(#)vm_mmap.c 7.5 (Berkeley) 6/28/91 - * $Id: vm_mmap.c,v 1.21 1994/04/02 08:39:55 cgd Exp $ + * $Id: vm_mmap.c,v 1.22 1994/04/15 07:04:51 cgd Exp $ */ /* @@ -57,7 +57,6 @@ #include #include #include -#include #include #ifdef DEBUG @@ -156,7 +155,7 @@ smmap(p, uap, retval) /* XXX SHOULD BE mmap() */ * Size is implicitly rounded to a page boundary. */ addr = (vm_offset_t) uap->addr; - if ((flags & MAP_FIXED) && (addr & page_mask) || uap->len < 0) + if ((flags & MAP_FIXED) && (addr & PAGE_MASK) || uap->len < 0) return(EINVAL); size = (vm_size_t) round_page(uap->len); if ((flags & MAP_FIXED) && (addr + size > VM_MAXUSER_ADDRESS)) @@ -350,7 +349,7 @@ msync(p, uap, retval) printf("msync(%d): addr %x len %x\n", p->p_pid, uap->addr, uap->len); #endif - if (((int)uap->addr & page_mask) || uap->len < 0) + if (((int)uap->addr & PAGE_MASK) || uap->len < 0) return(EINVAL); addr = oaddr = (vm_offset_t)uap->addr; osize = (vm_size_t)uap->len; @@ -421,7 +420,7 @@ munmap(p, uap, retval) p->p_pid, uap->addr, uap->len); #endif addr = (vm_offset_t) uap->addr; - if ((addr & page_mask) || uap->len < 0) + if ((addr & PAGE_MASK) || uap->len < 0) return(EINVAL); size = (vm_size_t) round_page(uap->len); if (size == 0) @@ -474,7 +473,7 @@ mprotect(p, uap, retval) p->p_pid, uap->addr, uap->len, uap->prot); #endif addr = (vm_offset_t) uap->addr; - if ((addr & page_mask) || uap->len < 0) + if ((addr & PAGE_MASK) || uap->len < 0) return(EINVAL); size = (vm_size_t) uap->len; /* @@ -912,12 +911,19 @@ vm_allocate_with_pager(map, addr, size, fitit, pager, poffset, internal) * it. */ object = vm_object_lookup(pager); - vm_stat.lookups++; + cnt.v_lookups++; if (object == NULL) { object = vm_object_allocate(size); - vm_object_enter(object, pager); + /* + * From Mike Hibler: "unnamed anonymous objects should never + * be on the hash list ... For now you can just change + * vm_allocate_with_pager to not do vm_object_enter if this + * is an internal object ..." + */ + if (!internal) + vm_object_enter(object, pager); } else - vm_stat.hits++; + cnt.v_hits++; if (internal) object->flags |= OBJ_INTERNAL; else diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index 8028bcffe72b..e47d35d262c7 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)vm_object.c 7.4 (Berkeley) 5/7/91 - * $Id: vm_object.c,v 1.17 1994/03/17 02:52:19 cgd Exp $ + * $Id: vm_object.c,v 1.18 1994/04/15 07:04:53 cgd Exp $ * * * Copyright (c) 1987, 1990 Carnegie-Mellon University. @@ -78,7 +78,6 @@ static void _vm_object_allocate __P((vm_size_t, vm_object_t)); static void vm_object_terminate __P((vm_object_t)); static void vm_object_deactivate_pages __P((vm_object_t)); static void vm_object_cache_trim __P((void)); -static void vm_object_shutdown __P((void)); static void vm_object_remove __P((vm_pager_t)); static void vm_object_cache_clear __P((void)); @@ -113,8 +112,8 @@ struct vm_object kmem_object_store; #define VM_OBJECT_HASH_COUNT 157 -int vm_cache_max = 100; /* can patch if necessary */ -queue_head_t vm_object_hashtable[VM_OBJECT_HASH_COUNT]; +int vm_cache_max = 100; /* can patch if necessary */ +struct vm_object_hash_head vm_object_hashtable[VM_OBJECT_HASH_COUNT]; long object_collapses = 0; long object_bypasses = 0; @@ -129,14 +128,14 @@ vm_object_init() { register int i; - queue_init(&vm_object_cached_list); - queue_init(&vm_object_list); + TAILQ_INIT(&vm_object_cached_list); + TAILQ_INIT(&vm_object_list); vm_object_count = 0; simple_lock_init(&vm_cache_lock); simple_lock_init(&vm_object_list_lock); for (i = 0; i < VM_OBJECT_HASH_COUNT; i++) - queue_init(&vm_object_hashtable[i]); + TAILQ_INIT(&vm_object_hashtable[i]); kernel_object = &kernel_object_store; _vm_object_allocate(VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS, @@ -170,7 +169,7 @@ _vm_object_allocate(size, object) vm_size_t size; register vm_object_t object; { - queue_init(&object->memq); + TAILQ_INIT(&object->memq); vm_object_lock_init(object); object->ref_count = 1; object->resident_page_count = 0; @@ -190,7 +189,7 @@ _vm_object_allocate(size, object) object->shadow_offset = (vm_offset_t) 0; simple_lock(&vm_object_list_lock); - queue_enter(&vm_object_list, object, vm_object_t, object_list); + TAILQ_INSERT_TAIL(&vm_object_list, object, object_list); vm_object_count++; simple_unlock(&vm_object_list_lock); } @@ -267,10 +266,10 @@ vm_object_deallocate(object) /* * Check for dirty pages in object * Print warning as this may signify kernel bugs - * pk@cs.few.eur.nl - 4/15/93 */ - p = (vm_page_t) queue_first(&object->memq); - while (!queue_end(&object->memq, (queue_entry_t) p)) { + for (p = object->memq.tqh_first; + p != NULL; + p = p->listq.tqe_next) { VM_PAGE_CHECK(p); if (pmap_is_modified(VM_PAGE_TO_PHYS(p)) || @@ -279,13 +278,11 @@ vm_object_deallocate(object) printf("vm_object_dealloc: persistent object %x isn't clean\n", object); goto cant_persist; } - - p = (vm_page_t) queue_next(&p->listq); } #endif /* DIAGNOSTIC */ - queue_enter(&vm_object_cached_list, object, - vm_object_t, cached_list); + TAILQ_INSERT_TAIL(&vm_object_cached_list, object, + cached_list); vm_object_cached++; vm_object_cache_unlock(); @@ -306,23 +303,23 @@ vm_object_deallocate(object) * Sanity check on the object hash table. */ { - register vm_object_hash_entry_t entry; - int i; + register vm_object_hash_entry_t entry; + int i; - for (i = 0; i < VM_OBJECT_HASH_COUNT; i++) { - queue_t bucket = &vm_object_hashtable[i]; + for (i = 0; i < VM_OBJECT_HASH_COUNT; i++) { + struct vm_object_hash_head *bucket = + &vm_object_hashtable[i]; - entry = (vm_object_hash_entry_t) queue_first(bucket); - while (!queue_end(bucket, (queue_entry_t) entry)) { - if (object == entry->object) { - vm_object_print(object,0); - panic("object hashtable burb"); + for (entry = bucket->tqh_first; + entry != NULL; + entry = entry->hash_links.tqe_next) { + if (object == entry->object) { + vm_object_print(object,0); + panic("object hashtable burb"); + } } - entry = (vm_object_hash_entry_t) - queue_next(&entry->hash_links); } } - } #endif vm_object_cache_unlock(); @@ -385,29 +382,12 @@ vm_object_terminate(object) * before deallocating the paging space. */ - p = (vm_page_t) queue_first(&object->memq); - while (!queue_end(&object->memq, (queue_entry_t) p)) { + for (p = object->memq.tqh_first; p != NULL; p = p->listq.tqe_next) { VM_PAGE_CHECK(p); - vm_page_lock_queues(); - if (p->flags & PG_ACTIVE) { - queue_remove(&vm_page_queue_active, p, vm_page_t, - pageq); - p->flags &= ~PG_ACTIVE; - vm_page_active_count--; - } - - if (p->flags & PG_INACTIVE) { - queue_remove(&vm_page_queue_inactive, p, vm_page_t, - pageq); - p->flags &= ~PG_INACTIVE; - vm_page_inactive_count--; - } + vm_page_free(p); vm_page_unlock_queues(); - p = (vm_page_t) queue_next(&p->listq); } - - vm_object_unlock(object); if (object->paging_in_progress != 0) panic("vm_object_deallocate: pageout in progress"); @@ -423,11 +403,8 @@ vm_object_terminate(object) vm_object_page_clean(object, 0, 0); vm_object_unlock(object); } - while (!queue_empty(&object->memq)) { - p = (vm_page_t) queue_first(&object->memq); - + while ((p = object->memq.tqh_first) != NULL) { VM_PAGE_CHECK(p); - vm_page_lock_queues(); vm_page_free(p); vm_page_unlock_queues(); @@ -442,7 +419,7 @@ vm_object_terminate(object) simple_lock(&vm_object_list_lock); - queue_remove(&vm_object_list, object, vm_object_t, object_list); + TAILQ_REMOVE(&vm_object_list, object, object_list); vm_object_count--; simple_unlock(&vm_object_list_lock); @@ -475,8 +452,7 @@ vm_object_page_clean(object, start, end) return; again: - p = (vm_page_t) queue_first(&object->memq); - while (!queue_end(&object->memq, (queue_entry_t) p)) { + for (p = object->memq.tqh_first; p != NULL; p = p->listq.tqe_next) { if ((start == end || p->offset >= start && p->offset < end) && !(p->flags & PG_FICTITIOUS)) { if ((p->flags & PG_CLEAN) && @@ -495,7 +471,6 @@ again: goto again; } } - p = (vm_page_t) queue_next(&p->listq); } } @@ -513,17 +488,11 @@ vm_object_deactivate_pages(object) { register vm_page_t p, next; - p = (vm_page_t) queue_first(&object->memq); - while (!queue_end(&object->memq, (queue_entry_t) p)) { - next = (vm_page_t) queue_next(&p->listq); + for (p = object->memq.tqh_first; p != NULL; p = next) { + next = p->listq.tqe_next; vm_page_lock_queues(); - if (!(p->flags & PG_BUSY)) - vm_page_deactivate(p); /* optimisation from mach 3.0 - - * andrew@werple.apana.org.au, - * Feb '93 - */ + vm_page_deactivate(p); vm_page_unlock_queues(); - p = next; } } @@ -537,7 +506,7 @@ vm_object_cache_trim() vm_object_cache_lock(); while (vm_object_cached > vm_cache_max) { - object = (vm_object_t) queue_first(&vm_object_cached_list); + object = vm_object_cached_list.tqh_first; vm_object_cache_unlock(); if (object != vm_object_lookup(object->pager)) @@ -550,61 +519,6 @@ vm_object_cache_trim() vm_object_cache_unlock(); } -/* - * vm_object_shutdown() - * - * Shut down the object system. Unfortunately, while we - * may be trying to do this, init is happily waiting for - * processes to exit, and therefore will be causing some objects - * to be deallocated. To handle this, we gain a fake reference - * to all objects we release paging areas for. This will prevent - * a duplicate deallocation. This routine is probably full of - * race conditions! - */ -static void -vm_object_shutdown() -{ - register vm_object_t object; - - /* - * Clean up the object cache *before* we screw up the reference - * counts on all of the objects. - */ - - vm_object_cache_clear(); - - printf("free paging spaces: "); - - /* - * First we gain a reference to each object so that - * no one else will deallocate them. - */ - - simple_lock(&vm_object_list_lock); - object = (vm_object_t) queue_first(&vm_object_list); - while (!queue_end(&vm_object_list, (queue_entry_t) object)) { - vm_object_reference(object); - object = (vm_object_t) queue_next(&object->object_list); - } - simple_unlock(&vm_object_list_lock); - - /* - * Now we deallocate all the paging areas. We don't need - * to lock anything because we've reduced to a single - * processor while shutting down. This also assumes that - * no new objects are being created. - */ - - object = (vm_object_t) queue_first(&vm_object_list); - while (!queue_end(&vm_object_list, (queue_entry_t) object)) { - if (object->pager != NULL) - vm_pager_deallocate(object->pager); - object = (vm_object_t) queue_next(&object->object_list); - printf("."); - } - printf("done.\n"); -} - /* * vm_object_pmap_copy: * @@ -626,13 +540,11 @@ vm_object_pmap_copy(object, start, end) return; vm_object_lock(object); - p = (vm_page_t) queue_first(&object->memq); - while (!queue_end(&object->memq, (queue_entry_t) p)) { + for (p = object->memq.tqh_first; p != NULL; p = p->listq.tqe_next) { if ((start <= p->offset) && (p->offset < end)) { pmap_page_protect(VM_PAGE_TO_PHYS(p), VM_PROT_READ); p->flags |= PG_COPYONWRITE; } - p = (vm_page_t) queue_next(&p->listq); } vm_object_unlock(object); } @@ -657,12 +569,9 @@ vm_object_pmap_remove(object, start, end) return; vm_object_lock(object); - p = (vm_page_t) queue_first(&object->memq); - while (!queue_end(&object->memq, (queue_entry_t) p)) { + for (p = object->memq.tqh_first; p != NULL; p = p->listq.tqe_next) if ((start <= p->offset) && (p->offset < end)) pmap_page_protect(VM_PAGE_TO_PHYS(p), VM_PROT_NONE); - p = (vm_page_t) queue_next(&p->listq); - } vm_object_unlock(object); } @@ -722,13 +631,10 @@ vm_object_copy(src_object, src_offset, size, /* * Mark all of the pages copy-on-write. */ - for (p = (vm_page_t) queue_first(&src_object->memq); - !queue_end(&src_object->memq, (queue_entry_t)p); - p = (vm_page_t) queue_next(&p->listq)) { + for (p = src_object->memq.tqh_first; p; p = p->listq.tqe_next) if (src_offset <= p->offset && p->offset < src_offset + size) p->flags |= PG_COPYONWRITE; - } vm_object_unlock(src_object); *dst_object = src_object; @@ -853,12 +759,9 @@ vm_object_copy(src_object, src_offset, size, * Mark all the affected pages of the existing object * copy-on-write. */ - p = (vm_page_t) queue_first(&src_object->memq); - while (!queue_end(&src_object->memq, (queue_entry_t) p)) { + for (p = src_object->memq.tqh_first; p != NULL; p = p->listq.tqe_next) if ((new_start <= p->offset) && (p->offset < new_end)) p->flags |= PG_COPYONWRITE; - p = (vm_page_t) queue_next(&p->listq); - } vm_object_unlock(src_object); @@ -954,22 +857,20 @@ vm_object_t vm_object_lookup(pager) vm_pager_t pager; { - register queue_t bucket; register vm_object_hash_entry_t entry; vm_object_t object; - bucket = &vm_object_hashtable[vm_object_hash(pager)]; - vm_object_cache_lock(); - entry = (vm_object_hash_entry_t) queue_first(bucket); - while (!queue_end(bucket, (queue_entry_t) entry)) { + for (entry = vm_object_hashtable[vm_object_hash(pager)].tqh_first; + entry != NULL; + entry = entry->hash_links.tqe_next) { object = entry->object; if (object->pager == pager) { vm_object_lock(object); if (object->ref_count == 0) { - queue_remove(&vm_object_cached_list, object, - vm_object_t, cached_list); + TAILQ_REMOVE(&vm_object_cached_list, object, + cached_list); vm_object_cached--; } object->ref_count++; @@ -977,7 +878,6 @@ vm_object_lookup(pager) vm_object_cache_unlock(); return(object); } - entry = (vm_object_hash_entry_t) queue_next(&entry->hash_links); } vm_object_cache_unlock(); @@ -994,7 +894,7 @@ vm_object_enter(object, pager) vm_object_t object; vm_pager_t pager; { - register queue_t bucket; + struct vm_object_hash_head *bucket; register vm_object_hash_entry_t entry; /* @@ -1014,7 +914,7 @@ vm_object_enter(object, pager) object->flags |= OBJ_CANPERSIST; vm_object_cache_lock(); - queue_enter(bucket, entry, vm_object_hash_entry_t, hash_links); + TAILQ_INSERT_TAIL(bucket, entry, hash_links); vm_object_cache_unlock(); } @@ -1030,22 +930,21 @@ static void vm_object_remove(pager) register vm_pager_t pager; { - register queue_t bucket; + struct vm_object_hash_head *bucket; register vm_object_hash_entry_t entry; register vm_object_t object; bucket = &vm_object_hashtable[vm_object_hash(pager)]; - entry = (vm_object_hash_entry_t) queue_first(bucket); - while (!queue_end(bucket, (queue_entry_t) entry)) { + for (entry = bucket->tqh_first; + entry != NULL; + entry = entry->hash_links.tqe_next) { object = entry->object; if (object->pager == pager) { - queue_remove(bucket, entry, vm_object_hash_entry_t, - hash_links); + TAILQ_REMOVE(bucket, entry, hash_links); free((caddr_t)entry, M_VMOBJHASH); break; } - entry = (vm_object_hash_entry_t) queue_next(&entry->hash_links); } } @@ -1063,8 +962,7 @@ vm_object_cache_clear() * list of cached objects. */ vm_object_cache_lock(); - while (!queue_empty(&vm_object_cached_list)) { - object = (vm_object_t) queue_first(&vm_object_cached_list); + while ((object = vm_object_cached_list.tqh_first) != NULL) { vm_object_cache_unlock(); /* @@ -1184,11 +1082,7 @@ vm_object_collapse(object) * pages that shadow them. */ - while (!queue_empty(&backing_object->memq)) { - - p = (vm_page_t) - queue_first(&backing_object->memq); - + while ((p = backing_object->memq.tqh_first) != NULL) { new_offset = (p->offset - backing_offset); /* @@ -1307,8 +1201,8 @@ vm_object_collapse(object) vm_object_unlock(backing_object); simple_lock(&vm_object_list_lock); - queue_remove(&vm_object_list, backing_object, - vm_object_t, object_list); + TAILQ_REMOVE(&vm_object_list, backing_object, + object_list); vm_object_count--; simple_unlock(&vm_object_list_lock); @@ -1339,10 +1233,9 @@ vm_object_collapse(object) * of pages here. */ - p = (vm_page_t) queue_first(&backing_object->memq); - while (!queue_end(&backing_object->memq, - (queue_entry_t) p)) { - + for (p = backing_object->memq.tqh_first; + p != NULL; + p = p->listq.tqe_next) { new_offset = (p->offset - backing_offset); /* @@ -1365,7 +1258,6 @@ vm_object_collapse(object) vm_object_unlock(backing_object); return; } - p = (vm_page_t) queue_next(&p->listq); } /* @@ -1427,16 +1319,14 @@ vm_object_page_remove(object, start, end) if (object == NULL) return; - p = (vm_page_t) queue_first(&object->memq); - while (!queue_end(&object->memq, (queue_entry_t) p)) { - next = (vm_page_t) queue_next(&p->listq); + for (p = object->memq.tqh_first; p != NULL; p = next) { + next = p->listq.tqe_next; if ((start <= p->offset) && (p->offset < end)) { pmap_page_protect(VM_PAGE_TO_PHYS(p), VM_PROT_NONE); vm_page_lock_queues(); vm_page_free(p); vm_page_unlock_queues(); } - p = next; } } @@ -1566,15 +1456,14 @@ _vm_object_print(object, full, pr) (int) object->pager, (int) object->paging_offset, (int) object->shadow, (int) object->shadow_offset); (*pr)("cache: next=0x%x, prev=0x%x\n", - object->cached_list.next, object->cached_list.prev); + object->cached_list.tqe_next, object->cached_list.tqe_prev); if (!full) return; indent += 2; count = 0; - p = (vm_page_t) queue_first(&object->memq); - while (!queue_end(&object->memq, (queue_entry_t) p)) { + for (p = object->memq.tqh_first; p != NULL; p = p->listq.tqe_next) { if (count == 0) iprintf(pr, "memory:="); else if (count == 6) { @@ -1586,7 +1475,6 @@ _vm_object_print(object, full, pr) count++; (*pr)("(off=0x%x,page=0x%x)", p->offset, VM_PAGE_TO_PHYS(p)); - p = (vm_page_t) queue_next(&p->listq); } if (count != 0) (*pr)("\n"); diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h index f14c9a5ed73a..d6b9e0f22e1f 100644 --- a/sys/vm/vm_object.h +++ b/sys/vm/vm_object.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)vm_object.h 7.3 (Berkeley) 4/21/91 - * $Id: vm_object.h,v 1.9 1994/03/17 02:52:25 cgd Exp $ + * $Id: vm_object.h,v 1.10 1994/04/15 07:04:54 cgd Exp $ * * * Copyright (c) 1987, 1990 Carnegie-Mellon University. @@ -70,6 +70,7 @@ * Virtual memory object module definitions. */ +#include #include /* @@ -79,8 +80,8 @@ */ struct vm_object { - queue_chain_t memq; /* Resident memory */ - queue_chain_t object_list; /* list of all objects */ + struct pglist memq; /* Resident memory */ + TAILQ_ENTRY(vm_object) object_list; /* list of all objects */ simple_lock_data_t Lock; /* Synchronization */ int ref_count; /* How many refs?? */ vm_size_t size; /* Object size */ @@ -96,26 +97,32 @@ struct vm_object { /* Paging (in or out) - don't collapse or destroy */ u_short flags; /* object flags; see below */ - queue_chain_t cached_list; /* for persistence */ + TAILQ_ENTRY(vm_object) cached_list; /* for persistence */ }; - -/* Object flags */ +/* + * Flags + */ #define OBJ_CANPERSIST 0x0001 /* allow to persist */ #define OBJ_INTERNAL 0x0002 /* internally created object */ +#define OBJ_ACTIVE 0x0004 /* used to mark active objects */ + +TAILQ_HEAD(vm_object_hash_head, vm_object_hash_entry); struct vm_object_hash_entry { - queue_chain_t hash_links; /* hash chain links */ - vm_object_t object; /* object we represent */ + TAILQ_ENTRY(vm_object_hash_entry) hash_links; /* hash chain links */ + vm_object_t object; /* object represented */ }; typedef struct vm_object_hash_entry *vm_object_hash_entry_t; #ifdef KERNEL -queue_head_t vm_object_cached_list; /* list of objects persisting */ +TAILQ_HEAD(object_q, vm_object); + +struct object_q vm_object_cached_list; /* list of objects persisting */ int vm_object_cached; /* size of cached list */ simple_lock_data_t vm_cache_lock; /* lock for object cache */ -queue_head_t vm_object_list; /* list of allocated objects */ +struct object_q vm_object_list; /* list of allocated objects */ long vm_object_count; /* count of all objects */ simple_lock_data_t vm_object_list_lock; /* lock for object list and count */ diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 41f5d7723745..0e1e371cba5f 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)vm_page.c 7.4 (Berkeley) 5/7/91 - * $Id: vm_page.c,v 1.12 1994/03/17 02:52:27 cgd Exp $ + * $Id: vm_page.c,v 1.13 1994/04/15 07:04:57 cgd Exp $ * * * Copyright (c) 1987, 1990 Carnegie-Mellon University. @@ -91,18 +91,14 @@ vm_offset_t virtual_space_start; vm_offset_t virtual_space_end; #endif /* MACHINE_NONCONTIG */ -queue_head_t *vm_page_buckets; /* Array of buckets */ +struct pglist *vm_page_buckets; /* Array of buckets */ int vm_page_bucket_count = 0; /* How big is array? */ int vm_page_hash_mask; /* Mask for hash function */ simple_lock_data_t bucket_lock; /* lock for all buckets XXX */ -vm_size_t page_size = 4096; -vm_size_t page_mask = 4095; -int page_shift = 12; - -queue_head_t vm_page_queue_free; -queue_head_t vm_page_queue_active; -queue_head_t vm_page_queue_inactive; +struct pglist vm_page_queue_free; +struct pglist vm_page_queue_active; +struct pglist vm_page_queue_inactive; simple_lock_data_t vm_page_queue_lock; simple_lock_data_t vm_page_queue_free_lock; @@ -117,17 +113,8 @@ vm_offset_t last_phys_addr; u_long first_page; int vm_page_count; #endif /* MACHINE_NONCONTIG */ - -int vm_page_free_count; -int vm_page_active_count; -int vm_page_inactive_count; -int vm_page_wire_count; -int vm_page_laundry_count; - -int vm_page_free_target = 0; -int vm_page_free_min = 0; -int vm_page_inactive_target = 0; -int vm_page_free_reserved = 0; +vm_size_t page_mask; +int page_shift; /* * vm_set_page_size: @@ -141,13 +128,14 @@ int vm_page_free_reserved = 0; void vm_set_page_size() { - page_mask = page_size - 1; - if ((page_mask & page_size) != 0) + if (cnt.v_page_size == 0) + cnt.v_page_size = DEFAULT_PAGE_SIZE; + page_mask = cnt.v_page_size - 1; + if ((page_mask & cnt.v_page_size) != 0) panic("vm_set_page_size: page size not a power of two"); - for (page_shift = 0; ; page_shift++) - if ((1 << page_shift) == page_size) + if ((1 << page_shift) == cnt.v_page_size) break; } @@ -169,6 +157,7 @@ vm_page_bootstrap(startp, endp) vm_offset_t *endp; { int i; + register struct pglist *bucket; extern vm_offset_t kentry_data; extern vm_size_t kentry_data_size; @@ -186,9 +175,9 @@ vm_page_bootstrap(startp, endp) * the active queue and the inactive queue. */ - queue_init(&vm_page_queue_free); - queue_init(&vm_page_queue_active); - queue_init(&vm_page_queue_inactive); + TAILQ_INIT(&vm_page_queue_free); + TAILQ_INIT(&vm_page_queue_active); + TAILQ_INIT(&vm_page_queue_inactive); /* * Pre-allocate maps and map entries that cannot be dynamically @@ -235,15 +224,15 @@ vm_page_bootstrap(startp, endp) vm_page_hash_mask = vm_page_bucket_count - 1; - vm_page_buckets = (queue_t) - pmap_steal_memory(vm_page_bucket_count * sizeof(*vm_page_buckets)); - - for (i = 0; i < vm_page_bucket_count; i++) { - register queue_head_t *bucket = &vm_page_buckets[i]; - - queue_init(bucket); + vm_page_buckets = (struct pglist *) + pmap_steal_memory(vm_page_bucket_count * sizeof(*vm_page_buckets)); + bucket = vm_page_buckets; + + for (i = vm_page_bucket_count; i--;) { + TAILQ_INIT(bucket); + bucket++; } - + simple_lock_init(&bucket_lock); /* @@ -281,14 +270,13 @@ vm_page_startup(start, end, vaddr) vm_offset_t end; register vm_offset_t vaddr; { - register vm_offset_t mapped; register vm_page_t m; - register queue_t bucket; + register vm_offset_t mapped; + register struct pglist *bucket; vm_size_t npages; register vm_offset_t new_start; int i; vm_offset_t pa; - extern vm_offset_t kentry_data; extern vm_size_t kentry_data_size; @@ -305,9 +293,9 @@ vm_page_startup(start, end, vaddr) * the active queue and the inactive queue. */ - queue_init(&vm_page_queue_free); - queue_init(&vm_page_queue_active); - queue_init(&vm_page_queue_inactive); + TAILQ_INIT(&vm_page_queue_free); + TAILQ_INIT(&vm_page_queue_active); + TAILQ_INIT(&vm_page_queue_inactive); /* * Allocate (and initialize) the hash table buckets. @@ -320,8 +308,7 @@ vm_page_startup(start, end, vaddr) * This computation can be tweaked if desired. */ - vm_page_buckets = (queue_t) vaddr; - bucket = vm_page_buckets; + vm_page_buckets = (struct pglist *) vaddr; if (vm_page_bucket_count == 0) { vm_page_bucket_count = 1; while (vm_page_bucket_count < atop(end - start)) @@ -334,7 +321,7 @@ vm_page_startup(start, end, vaddr) * Validate these addresses. */ - new_start = round_page(((queue_t)start) + vm_page_bucket_count); + new_start = round_page(((struct pglist *)start) + vm_page_bucket_count); mapped = vaddr; vaddr = pmap_map(mapped, start, new_start, VM_PROT_READ|VM_PROT_WRITE); @@ -342,8 +329,9 @@ vm_page_startup(start, end, vaddr) bzero((caddr_t) mapped, vaddr - mapped); mapped = vaddr; + bucket = vm_page_buckets; for (i = vm_page_bucket_count; i--;) { - queue_init(bucket); + TAILQ_INIT(bucket); bucket++; } @@ -389,7 +377,7 @@ vm_page_startup(start, end, vaddr) * of a page structure per page). */ - vm_page_free_count = npages = + cnt.v_free_count = npages = (end - start + sizeof(struct vm_page))/(PAGE_SIZE + sizeof(struct vm_page)); /* @@ -404,7 +392,7 @@ vm_page_startup(start, end, vaddr) last_page = first_page + npages - 1; first_phys_addr = ptoa(first_page); - last_phys_addr = ptoa(last_page) + page_mask; + last_phys_addr = ptoa(last_page) + PAGE_MASK; /* * Validate these addresses. @@ -423,7 +411,7 @@ vm_page_startup(start, end, vaddr) pa = first_phys_addr; while (npages--) { m->phys_addr = pa; - queue_enter(&vm_page_queue_free, m, vm_page_t, pageq); + TAILQ_INSERT_TAIL(&vm_page_queue_free, m, pageq); m++; pa += PAGE_SIZE; } @@ -448,12 +436,17 @@ pmap_steal_memory(size) vm_size_t size; { vm_offset_t addr, vaddr, paddr; - + +#ifdef i386 /* XXX i386 calls pmap_steal_memory before vm_mem_init() */ + if (cnt.v_page_size == 0) /* XXX */ + vm_set_page_size(); +#endif + /* * We round the size to an integer multiple. */ - size = (size + 3) &~ 3; + size = (size + 3) &~ 3; /* XXX */ /* * If this is the first call to pmap_steal_memory, @@ -568,7 +561,7 @@ vm_page_insert(mem, object, offset) register vm_object_t object; register vm_offset_t offset; { - register queue_t bucket; + register struct pglist *bucket; int spl; VM_PAGE_CHECK(mem); @@ -590,7 +583,7 @@ vm_page_insert(mem, object, offset) bucket = &vm_page_buckets[vm_page_hash(object, offset)]; spl = splimp(); simple_lock(&bucket_lock); - queue_enter(bucket, mem, vm_page_t, hashq); + TAILQ_INSERT_TAIL(bucket, mem, hashq); simple_unlock(&bucket_lock); (void) splx(spl); @@ -598,7 +591,7 @@ vm_page_insert(mem, object, offset) * Now link into the object's list of backed pages. */ - queue_enter(&object->memq, mem, vm_page_t, listq); + TAILQ_INSERT_TAIL(&object->memq, mem, listq); mem->flags |= PG_TABLED; /* @@ -621,7 +614,7 @@ void vm_page_remove(mem) register vm_page_t mem; { - register queue_t bucket; + register struct pglist *bucket; int spl; VM_PAGE_CHECK(mem); @@ -636,7 +629,7 @@ vm_page_remove(mem) bucket = &vm_page_buckets[vm_page_hash(mem->object, mem->offset)]; spl = splimp(); simple_lock(&bucket_lock); - queue_remove(bucket, mem, vm_page_t, hashq); + TAILQ_REMOVE(bucket, mem, hashq); simple_unlock(&bucket_lock); (void) splx(spl); @@ -644,7 +637,7 @@ vm_page_remove(mem) * Now remove from the object's list of backed pages. */ - queue_remove(&mem->object->memq, mem, vm_page_t, listq); + TAILQ_REMOVE(&mem->object->memq, mem, listq); /* * And show that the object has one fewer resident @@ -670,7 +663,7 @@ vm_page_lookup(object, offset) register vm_offset_t offset; { register vm_page_t mem; - register queue_t bucket; + register struct pglist *bucket; int spl; /* @@ -681,15 +674,13 @@ vm_page_lookup(object, offset) spl = splimp(); simple_lock(&bucket_lock); - mem = (vm_page_t) queue_first(bucket); - while (!queue_end(bucket, (queue_entry_t) mem)) { + for (mem = bucket->tqh_first; mem != NULL; mem = mem->hashq.tqe_next) { VM_PAGE_CHECK(mem); if ((mem->object == object) && (mem->offset == offset)) { simple_unlock(&bucket_lock); splx(spl); return(mem); } - mem = (vm_page_t) queue_next(&mem->hashq); } simple_unlock(&bucket_lock); @@ -739,23 +730,16 @@ vm_page_alloc(object, offset) spl = splimp(); /* XXX */ simple_lock(&vm_page_queue_free_lock); - if ( object != kernel_object && - object != kmem_object && - vm_page_free_count <= vm_page_free_reserved) { - - simple_unlock(&vm_page_queue_free_lock); - splx(spl); - return(NULL); - } - if (queue_empty(&vm_page_queue_free)) { + if (vm_page_queue_free.tqh_first == NULL) { simple_unlock(&vm_page_queue_free_lock); splx(spl); return(NULL); } - queue_remove_first(&vm_page_queue_free, mem, vm_page_t, pageq); + mem = vm_page_queue_free.tqh_first; + TAILQ_REMOVE(&vm_page_queue_free, mem, pageq); - vm_page_free_count--; + cnt.v_free_count--; simple_unlock(&vm_page_queue_free_lock); splx(spl); @@ -772,9 +756,9 @@ vm_page_alloc(object, offset) * it doesn't really matter. */ - if ((vm_page_free_count < vm_page_free_min) || - ((vm_page_free_count < vm_page_free_target) && - (vm_page_inactive_count < vm_page_inactive_target))) + if ((cnt.v_free_count < cnt.v_free_min) || + ((cnt.v_free_count < cnt.v_free_target) && + (cnt.v_inactive_count < cnt.v_inactive_target))) thread_wakeup(&vm_pages_needed); return(mem); } @@ -793,15 +777,15 @@ vm_page_free(mem) { vm_page_remove(mem); if (mem->flags & PG_ACTIVE) { - queue_remove(&vm_page_queue_active, mem, vm_page_t, pageq); + TAILQ_REMOVE(&vm_page_queue_active, mem, pageq); mem->flags &= ~PG_ACTIVE; - vm_page_active_count--; + cnt.v_active_count--; } if (mem->flags & PG_INACTIVE) { - queue_remove(&vm_page_queue_inactive, mem, vm_page_t, pageq); + TAILQ_REMOVE(&vm_page_queue_inactive, mem, pageq); mem->flags &= ~PG_INACTIVE; - vm_page_inactive_count--; + cnt.v_inactive_count--; } if (!(mem->flags & PG_FICTITIOUS)) { @@ -809,9 +793,9 @@ vm_page_free(mem) spl = splimp(); simple_lock(&vm_page_queue_free_lock); - queue_enter(&vm_page_queue_free, mem, vm_page_t, pageq); + TAILQ_INSERT_TAIL(&vm_page_queue_free, mem, pageq); - vm_page_free_count++; + cnt.v_free_count++; simple_unlock(&vm_page_queue_free_lock); splx(spl); } @@ -834,18 +818,16 @@ vm_page_wire(mem) if (mem->wire_count == 0) { if (mem->flags & PG_ACTIVE) { - queue_remove(&vm_page_queue_active, mem, vm_page_t, - pageq); - vm_page_active_count--; + TAILQ_REMOVE(&vm_page_queue_active, mem, pageq); + cnt.v_active_count--; mem->flags &= ~PG_ACTIVE; } if (mem->flags & PG_INACTIVE) { - queue_remove(&vm_page_queue_inactive, mem, vm_page_t, - pageq); - vm_page_inactive_count--; + TAILQ_REMOVE(&vm_page_queue_inactive, mem, pageq); + cnt.v_inactive_count--; mem->flags &= ~PG_INACTIVE; } - vm_page_wire_count++; + cnt.v_wire_count++; } mem->wire_count++; } @@ -866,10 +848,10 @@ vm_page_unwire(mem) mem->wire_count--; if (mem->wire_count == 0) { - queue_enter(&vm_page_queue_active, mem, vm_page_t, pageq); - vm_page_active_count++; + TAILQ_INSERT_TAIL(&vm_page_queue_active, mem, pageq); + cnt.v_active_count++; mem->flags |= PG_ACTIVE; - vm_page_wire_count--; + cnt.v_wire_count--; } } @@ -901,13 +883,13 @@ vm_page_deactivate(m) if (!(m->flags & PG_INACTIVE) && m->wire_count == 0) { pmap_clear_reference(VM_PAGE_TO_PHYS(m)); if (m->flags & PG_ACTIVE) { - queue_remove(&vm_page_queue_active, m, vm_page_t, pageq); + TAILQ_REMOVE(&vm_page_queue_active, m, pageq); m->flags &= ~PG_ACTIVE; - vm_page_active_count--; + cnt.v_active_count--; } - queue_enter(&vm_page_queue_inactive, m, vm_page_t, pageq); + TAILQ_INSERT_TAIL(&vm_page_queue_inactive, m, pageq); m->flags |= PG_INACTIVE; - vm_page_inactive_count++; + cnt.v_inactive_count++; if (pmap_is_modified(VM_PAGE_TO_PHYS(m))) m->flags &= ~PG_CLEAN; if (m->flags & PG_CLEAN) @@ -931,18 +913,17 @@ vm_page_activate(m) VM_PAGE_CHECK(m); if (m->flags & PG_INACTIVE) { - queue_remove(&vm_page_queue_inactive, m, vm_page_t, - pageq); - vm_page_inactive_count--; + TAILQ_REMOVE(&vm_page_queue_inactive, m, pageq); + cnt.v_inactive_count--; m->flags &= ~PG_INACTIVE; } if (m->wire_count == 0) { if (m->flags & PG_ACTIVE) panic("vm_page_activate: already active"); - queue_enter(&vm_page_queue_active, m, vm_page_t, pageq); + TAILQ_INSERT_TAIL(&vm_page_queue_active, m, pageq); m->flags |= PG_ACTIVE; - vm_page_active_count++; + cnt.v_active_count++; } } diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h index a827e3163200..8d8da185d1d5 100644 --- a/sys/vm/vm_page.h +++ b/sys/vm/vm_page.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)vm_page.h 7.3 (Berkeley) 4/21/91 - * $Id: vm_page.h,v 1.9 1994/03/17 02:52:29 cgd Exp $ + * $Id: vm_page.h,v 1.10 1994/04/15 07:04:58 cgd Exp $ * * * Copyright (c) 1987, 1990 Carnegie-Mellon University. @@ -95,19 +95,21 @@ * queues (P). */ +TAILQ_HEAD(pglist, vm_page); + struct vm_page { - queue_chain_t pageq; /* queue info for FIFO - * queue or free list (P) */ - queue_chain_t hashq; /* hash table links (O)*/ - queue_chain_t listq; /* all pages in same object (O)*/ + TAILQ_ENTRY(vm_page) pageq; /* queue info for FIFO + * queue or free list (P) */ + TAILQ_ENTRY(vm_page) hashq; /* hash table links (O)*/ + TAILQ_ENTRY(vm_page) listq; /* pages in same object (O)*/ - vm_object_t object; /* which object am I in (O,P)*/ - vm_offset_t offset; /* offset into that object (O,P) */ + vm_object_t object; /* which object am I in (O,P)*/ + vm_offset_t offset; /* offset into object (O,P) */ - u_short wire_count; /* number wired down maps use me? (P) */ - u_short flags; /* flags; see below */ + u_short wire_count; /* wired down maps refs (P) */ + u_short flags; /* see below */ - vm_offset_t phys_addr; /* physical address of page */ + vm_offset_t phys_addr; /* physical address of page */ }; /* @@ -172,11 +174,11 @@ struct vm_page { */ extern -queue_head_t vm_page_queue_free; /* memory free queue */ +struct pglist vm_page_queue_free; /* memory free queue */ extern -queue_head_t vm_page_queue_active; /* active memory queue */ +struct pglist vm_page_queue_active; /* active memory queue */ extern -queue_head_t vm_page_queue_inactive; /* inactive memory queue */ +struct pglist vm_page_queue_inactive; /* inactive memory queue */ extern vm_page_t vm_page_array; /* First resident page in table */ @@ -200,26 +202,6 @@ extern int vm_page_count; /* How many pages do we manage? */ #endif /* MACHINE_NONCONTIG */ -/* XXX -- do these belong here? */ -extern -int vm_page_free_count; /* How many pages are free? */ -extern -int vm_page_active_count; /* How many pages are active? */ -extern -int vm_page_inactive_count; /* How many pages are inactive? */ -extern -int vm_page_wire_count; /* How many pages are wired? */ -extern -int vm_page_free_target; /* How many do we want free? */ -extern -int vm_page_free_min; /* When to wakeup pageout */ -extern -int vm_page_inactive_target;/* How many do we want inactive? */ -extern -int vm_page_free_reserved; /* How many pages reserved to do pageout */ -extern -int vm_page_laundry_count; /* How many pages being laundered? */ - #define VM_PAGE_TO_PHYS(entry) ((entry)->phys_addr) #ifndef MACHINE_NONCONTIG diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index e22e8aa8a66e..e071ac275d26 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)vm_pageout.c 7.4 (Berkeley) 5/7/91 - * $Id: vm_pageout.c,v 1.10 1994/03/17 02:52:36 cgd Exp $ + * $Id: vm_pageout.c,v 1.11 1994/04/15 07:04:59 cgd Exp $ * * * Copyright (c) 1987, 1990 Carnegie-Mellon University. @@ -89,7 +89,7 @@ int vm_page_pagesfreed; /* Pages freed by page daemon */ void vm_pageout_scan() { - register vm_page_t m; + register vm_page_t m, next; register int page_shortage; register int s; register int pages_freed; @@ -101,11 +101,11 @@ vm_pageout_scan() s = splimp(); simple_lock(&vm_page_queue_free_lock); - free = vm_page_free_count; + free = cnt.v_free_count; simple_unlock(&vm_page_queue_free_lock); splx(s); - if (free < vm_page_free_target) { + if (free < cnt.v_free_target) { #ifdef OMIT swapout_threads(); #endif /* OMIT*/ @@ -132,45 +132,43 @@ vm_pageout_scan() */ pages_freed = 0; - m = (vm_page_t) queue_first(&vm_page_queue_inactive); - while (!queue_end(&vm_page_queue_inactive, (queue_entry_t) m)) { - vm_page_t next; - + for (m = vm_page_queue_inactive.tqh_first; m != NULL; m = next) { s = splimp(); simple_lock(&vm_page_queue_free_lock); - free = vm_page_free_count; + free = cnt.v_free_count; simple_unlock(&vm_page_queue_free_lock); splx(s); - - if (free >= vm_page_free_target) + if (free >= cnt.v_free_target) break; + cnt.v_scan++; + next = m->pageq.tqe_next; + + /* + * If the page has been referenced, move it back to the + * active queue. + */ + if (pmap_is_referenced(VM_PAGE_TO_PHYS(m))) { + vm_page_activate(m); + cnt.v_reactivated++; + continue; + } + if (m->flags & PG_CLEAN) { - next = (vm_page_t) queue_next(&m->pageq); - if (pmap_is_referenced(VM_PAGE_TO_PHYS(m))) { - vm_page_activate(m); - vm_stat.reactivations++; - } - else { - register vm_object_t object; - object = m->object; - if (!vm_object_lock_try(object)) { - /* - * Can't lock object - - * skip page. - */ - m = next; - continue; - } + register vm_object_t object; + + object = m->object; + if (vm_object_lock_try(object)) { pmap_page_protect(VM_PAGE_TO_PHYS(m), VM_PROT_NONE); vm_page_free(m); /* will dequeue */ pages_freed++; + cnt.v_dfree++; vm_object_unlock(object); } - m = next; + continue; } - else { + { /* * If a page is dirty, then it is either * being washed (but not yet cleaned) @@ -206,14 +204,13 @@ vm_pageout_scan() * Skip page if we can't lock * its object */ - m = (vm_page_t) queue_next(&m->pageq); continue; } pmap_page_protect(VM_PAGE_TO_PHYS(m), VM_PROT_NONE); m->flags |= PG_BUSY; - vm_stat.pageouts++; + cnt.v_pageouts++; /* * Try to collapse the object before @@ -231,7 +228,7 @@ vm_pageout_scan() * Do a wakeup here in case the following * operations block. */ - thread_wakeup((int) &vm_page_free_count); + thread_wakeup((int) &cnt.v_free_count); /* * If there is no pager for the page, @@ -258,7 +255,6 @@ vm_pageout_scan() VM_PAGER_FAIL; vm_object_lock(object); vm_page_lock_queues(); - next = (vm_page_t) queue_next(&m->pageq); switch (pageout_status) { case VM_PAGER_OK: @@ -305,8 +301,6 @@ vm_pageout_scan() vm_object_unlock(object); m = next; } - else - m = (vm_page_t) queue_next(&m->pageq); } } @@ -316,8 +310,8 @@ vm_pageout_scan() * to inactive. */ - page_shortage = vm_page_inactive_target - vm_page_inactive_count; - page_shortage -= vm_page_free_count; + page_shortage = cnt.v_inactive_target - cnt.v_inactive_count; + page_shortage -= cnt.v_free_count; if ((page_shortage <= 0) && (pages_freed == 0)) page_shortage = 1; @@ -327,10 +321,8 @@ vm_pageout_scan() * Move some more pages from active to inactive. */ - if (queue_empty(&vm_page_queue_active)) { + if ((m = vm_page_queue_active.tqh_first) == NULL) break; - } - m = (vm_page_t) queue_first(&vm_page_queue_active); vm_page_deactivate(m); page_shortage--; } @@ -352,35 +344,26 @@ vm_pageout() * Initialize some paging parameters. */ - if (vm_page_free_min == 0) { - vm_page_free_min = vm_page_free_count / 20; - if (vm_page_free_min < 3) - vm_page_free_min = 3; + if (cnt.v_free_min == 0) { + cnt.v_free_min = cnt.v_free_count / 20; + if (cnt.v_free_min < 3) + cnt.v_free_min = 3; - if (vm_page_free_min > vm_page_free_min_sanity) - vm_page_free_min = vm_page_free_min_sanity; + if (cnt.v_free_min > vm_page_free_min_sanity) + cnt.v_free_min = vm_page_free_min_sanity; } - if (vm_page_free_reserved == 0) { - if ((vm_page_free_reserved = vm_page_free_min / 2) < 10) - vm_page_free_reserved = 10; - } - if (vm_pageout_free_min == 0) { - if ((vm_pageout_free_min = vm_page_free_reserved / 2) > 10) - vm_pageout_free_min = 10; - } + if (cnt.v_free_target == 0) + cnt.v_free_target = (cnt.v_free_min * 4) / 3; - if (vm_page_free_target == 0) - vm_page_free_target = (vm_page_free_min * 4) / 3; + if (cnt.v_inactive_target == 0) + cnt.v_inactive_target = cnt.v_free_min * 2; - if (vm_page_inactive_target == 0) - vm_page_inactive_target = vm_page_free_min * 2; + if (cnt.v_free_target <= cnt.v_free_min) + cnt.v_free_target = cnt.v_free_min + 1; - if (vm_page_free_target <= vm_page_free_min) - vm_page_free_target = vm_page_free_min + 1; - - if (vm_page_inactive_target <= vm_page_free_target) - vm_page_inactive_target = vm_page_free_target + 1; + if (cnt.v_inactive_target <= cnt.v_free_target) + cnt.v_inactive_target = cnt.v_free_target + 1; /* * The pageout daemon is never done, so loop @@ -394,6 +377,6 @@ vm_pageout() vm_pageout_scan(); vm_pager_sync(); simple_lock(&vm_pages_needed_lock); - thread_wakeup((int) &vm_page_free_count); + thread_wakeup((int) &cnt.v_free_count); } } diff --git a/sys/vm/vm_pageout.h b/sys/vm/vm_pageout.h index 0f3098e78f7d..b2d3d5c3ce89 100644 --- a/sys/vm/vm_pageout.h +++ b/sys/vm/vm_pageout.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)vm_pageout.h 7.3 (Berkeley) 4/21/91 - * $Id: vm_pageout.h,v 1.4 1994/01/07 22:22:27 mycroft Exp $ + * $Id: vm_pageout.h,v 1.5 1994/04/15 07:05:01 cgd Exp $ * * * Copyright (c) 1987, 1990 Carnegie-Mellon University. @@ -89,7 +89,7 @@ simple_lock_data_t vm_pages_needed_lock; #define VM_WAIT { \ simple_lock(&vm_pages_needed_lock); \ thread_wakeup((int)&vm_pages_needed); \ - thread_sleep((int)&vm_page_free_count, \ + thread_sleep((int)&cnt.v_free_count, \ &vm_pages_needed_lock); \ } diff --git a/sys/vm/vm_pager.c b/sys/vm/vm_pager.c index 6e6197de88db..845fae628fb7 100644 --- a/sys/vm/vm_pager.c +++ b/sys/vm/vm_pager.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)vm_pager.c 8.1 (Berkeley) 6/11/93 - * $Id: vm_pager.c,v 1.10 1994/01/07 18:11:38 mycroft Exp $ + * $Id: vm_pager.c,v 1.11 1994/04/15 07:05:02 cgd Exp $ * * * Copyright (c) 1987, 1990 Carnegie-Mellon University. @@ -260,19 +260,16 @@ vm_pager_unmap_page(kva) } vm_pager_t -vm_pager_lookup(list, handle) - register queue_head_t *list; +vm_pager_lookup(pglist, handle) + register struct pagerlst *pglist; caddr_t handle; { register vm_pager_t pager; - pager = (vm_pager_t) queue_first(list); - while (!queue_end(list, (queue_entry_t)pager)) { + for (pager = pglist->tqh_first; pager; pager = pager->pg_list.tqe_next) if (pager->pg_handle == handle) - return(pager); - pager = (vm_pager_t) queue_next(&pager->pg_list); - } - return(NULL); + return (pager); + return (NULL); } /* diff --git a/sys/vm/vm_param.h b/sys/vm/vm_param.h index a81c9ec057a6..ec2ffd1d0acf 100644 --- a/sys/vm/vm_param.h +++ b/sys/vm/vm_param.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)vm_param.h 7.2 (Berkeley) 4/21/91 - * $Id: vm_param.h,v 1.4 1993/07/29 21:45:42 jtc Exp $ + * $Id: vm_param.h,v 1.5 1994/04/15 07:05:03 cgd Exp $ * * * Copyright (c) 1987, 1990 Carnegie-Mellon University. @@ -87,6 +87,7 @@ typedef int boolean_t; * The machine independent pages are refered to as PAGES. A page * is some number of hardware pages, depending on the target machine. */ +#define DEFAULT_PAGE_SIZE 4096 /* * All references to the size of a page should be done with PAGE_SIZE @@ -94,8 +95,13 @@ typedef int boolean_t; * we can easily make them constant if we so desire. */ -#define PAGE_SIZE page_size /* size of page in addressible units */ -#define PAGE_SHIFT page_shift /* number of bits to shift for pages */ +#define PAGE_SIZE cnt.v_page_size /* size of page */ +#define PAGE_MASK page_mask /* size of page - 1 */ +#define PAGE_SHIFT page_shift /* bits to shift for pages */ +#ifdef KERNEL +extern vm_size_t page_mask; +extern int page_shift; +#endif /* * Return values from the VM routines. @@ -118,8 +124,8 @@ typedef int boolean_t; */ #ifdef KERNEL -#define atop(x) (((unsigned)(x)) >> page_shift) -#define ptoa(x) ((vm_offset_t)((x) << page_shift)) +#define atop(x) (((unsigned)(x)) >> PAGE_SHIFT) +#define ptoa(x) ((vm_offset_t)((x) << PAGE_SHIFT)) #endif /* KERNEL */ /* @@ -129,19 +135,14 @@ typedef int boolean_t; */ #ifdef KERNEL -#define round_page(x) ((vm_offset_t)((((vm_offset_t)(x)) + page_mask) & ~page_mask)) -#define trunc_page(x) ((vm_offset_t)(((vm_offset_t)(x)) & ~page_mask)) +#define round_page(x) ((vm_offset_t)((((vm_offset_t)(x)) + PAGE_MASK) & ~PAGE_MASK)) +#define trunc_page(x) ((vm_offset_t)(((vm_offset_t)(x)) & ~PAGE_MASK)) #else /* KERNEL */ #define round_page(x) ((((vm_offset_t)(x) + (vm_page_size - 1)) / vm_page_size) * vm_page_size) #define trunc_page(x) ((((vm_offset_t)(x)) / vm_page_size) * vm_page_size) #endif /* KERNEL */ #ifdef KERNEL -extern vm_size_t page_size; /* machine independent page size */ -extern vm_size_t page_mask; /* page_size - 1; mask for - offset within page */ -extern int page_shift; /* shift to use for page size */ - extern vm_size_t mem_size; /* size of physical memory (bytes) */ extern vm_offset_t first_addr; /* first physical page */ extern vm_offset_t last_addr; /* last physical page */ diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index e06b2147bf86..adc620ddc5a8 100644 --- a/sys/vm/vnode_pager.c +++ b/sys/vm/vnode_pager.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * from: @(#)vnode_pager.c 8.1 (Berkeley) 6/11/93 - * $Id: vnode_pager.c,v 1.6 1994/01/07 18:12:12 mycroft Exp $ + * $Id: vnode_pager.c,v 1.7 1994/04/15 07:05:04 cgd Exp $ */ /* @@ -59,7 +59,7 @@ #include #include -queue_head_t vnode_pager_list; /* list of managed vnodes */ +struct pagerlst vnode_pager_list; /* list of managed vnodes */ #ifdef DEBUG int vpagerdebug = 0x00; @@ -99,7 +99,7 @@ vnode_pager_init() if (vpagerdebug & VDB_FOLLOW) printf("vnode_pager_init()\n"); #endif - queue_init(&vnode_pager_list); + TAILQ_INIT(&vnode_pager_list); } /* @@ -167,7 +167,7 @@ vnode_pager_alloc(handle, size, prot, foff) vnp->vnp_flags = 0; vnp->vnp_vp = vp; vnp->vnp_size = vattr.va_size; - queue_enter(&vnode_pager_list, pager, vm_pager_t, pg_list); + TAILQ_INSERT_TAIL(&vnode_pager_list, pager, pg_list); pager->pg_handle = handle; pager->pg_type = PG_VNODE; pager->pg_ops = &vnodepagerops; @@ -212,7 +212,7 @@ vnode_pager_dealloc(pager) #endif vrele(vp); } - queue_remove(&vnode_pager_list, pager, vm_pager_t, pg_list); + TAILQ_REMOVE(&vnode_pager_list, pager, pg_list); free((caddr_t)vnp, M_VMPGDATA); free((caddr_t)pager, M_VMPAGER); } @@ -375,17 +375,16 @@ vnode_pager_umount(mp) register vm_pager_t pager, npager; struct vnode *vp; - pager = (vm_pager_t) queue_first(&vnode_pager_list); - while (!queue_end(&vnode_pager_list, (queue_entry_t)pager)) { + for (pager = vnode_pager_list.tqh_first; pager != NULL; + pager = npager){ /* * Save the next pointer now since uncaching may * terminate the object and render pager invalid */ + npager = pager->pg_list.tqe_next; vp = ((vn_pager_t)pager->pg_data)->vnp_vp; - npager = (vm_pager_t) queue_next(&pager->pg_list); if (mp == (struct mount *)0 || vp->v_mount == mp) (void) vnode_pager_uncache(vp); - pager = npager; } }