diff options
author | dg <dg@FreeBSD.org> | 1994-08-06 09:15:42 +0000 |
---|---|---|
committer | dg <dg@FreeBSD.org> | 1994-08-06 09:15:42 +0000 |
commit | 8b20309268255f6f6fbc908e5af8c9cde9a1a1c2 (patch) | |
tree | 67aa5e71ca8f826b24875a0de9a602849d2b2573 /sys/vm/swap_pager.c | |
parent | edb74877fe59af8008b23d2137302c9ad64c15d2 (diff) | |
download | FreeBSD-src-8b20309268255f6f6fbc908e5af8c9cde9a1a1c2.zip FreeBSD-src-8b20309268255f6f6fbc908e5af8c9cde9a1a1c2.tar.gz |
Incorporated post 1.1.5 work from John Dyson. This includes performance
improvements via the new routines pmap_qenter/pmap_qremove and pmap_kenter/
pmap_kremove. These routine allow fast mapping of pages for those
architectures that have "normal" MMUs. Also included is a fix to the
pageout daemon to properly check a queue end condition.
Submitted by: John Dyson
Diffstat (limited to 'sys/vm/swap_pager.c')
-rw-r--r-- | sys/vm/swap_pager.c | 155 |
1 files changed, 22 insertions, 133 deletions
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c index cec9a3f..189929c 100644 --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -39,7 +39,7 @@ * from: Utah $Hdr: swap_pager.c 1.4 91/04/30$ * * @(#)swap_pager.c 8.9 (Berkeley) 3/21/94 - * $Id$ + * $Id: swap_pager.c,v 1.4 1994/08/02 07:55:13 davidg Exp $ */ /* @@ -1030,19 +1030,8 @@ swap_pager_input(swp, m, count, reqpage) */ spc = NULL; /* we might not use an spc data structure */ - kva = 0; - /* - * we allocate a new kva for transfers > 1 page - * but for transfers == 1 page, the swap_pager_free list contains - * entries that have pre-allocated kva's (for efficiency). - */ - if (count > 1) { - kva = kmem_alloc_pageable(pager_map, count*PAGE_SIZE); - } - - - if (!kva) { + if (count == 1) { /* * if a kva has not been allocated, we can only do a one page transfer, * so we free the other pages that might have been allocated by @@ -1077,29 +1066,22 @@ swap_pager_input(swp, m, count, reqpage) spc = swap_pager_free.tqh_first; TAILQ_REMOVE(&swap_pager_free, spc, spc_list); kva = spc->spc_kva; - } - - - /* - * map our page(s) into kva for input - */ - for (i = 0; i < count; i++) { - pmap_kenter( kva + PAGE_SIZE * i, VM_PAGE_TO_PHYS(m[i])); - } - pmap_update(); - - - /* - * Get a swap buffer header and perform the IO - */ - if( spc) { bp = spc->spc_bp; bzero(bp, sizeof *bp); bp->b_spc = spc; } else { + /* + * Get a swap buffer header to perform the IO + */ bp = getpbuf(); + kva = (vm_offset_t) bp->b_data; } + /* + * map our page(s) into kva for input + */ + pmap_qenter( kva, m, count); + s = splbio(); bp->b_flags = B_BUSY | B_READ | B_CALL; bp->b_iodone = swap_pager_iodone1; @@ -1112,12 +1094,6 @@ swap_pager_input(swp, m, count, reqpage) bp->b_bcount = PAGE_SIZE*count; bp->b_bufsize = PAGE_SIZE*count; -/* - VHOLD(swapdev_vp); - bp->b_vp = swapdev_vp; - if (swapdev_vp->v_type == VBLK) - bp->b_dev = swapdev_vp->v_rdev; -*/ bgetvp( swapdev_vp, bp); swp->sw_piip++; @@ -1153,7 +1129,7 @@ swap_pager_input(swp, m, count, reqpage) /* * remove the mapping for kernel virtual */ - pmap_remove(vm_map_pmap(pager_map), kva, kva + count * PAGE_SIZE); + pmap_qremove( kva, count); if (spc) { /* @@ -1170,10 +1146,6 @@ swap_pager_input(swp, m, count, reqpage) } } else { /* - * free the kernel virtual addresses - */ - kmem_free_wakeup(pager_map, kva, count * PAGE_SIZE); - /* * release the physical I/O buffer */ relpbuf(bp); @@ -1372,6 +1344,11 @@ retrygetspace: * we allocate a new kva for transfers > 1 page * but for transfers == 1 page, the swap_pager_free list contains * entries that have pre-allocated kva's (for efficiency). + * NOTE -- we do not use the physical buffer pool or the + * preallocated associated kva's because of the potential for + * deadlock. This is very subtile -- but deadlocks or resource + * contention must be avoided on pageouts -- or your system will + * sleep (forever) !!! */ if ( count > 1) { kva = kmem_alloc_pageable(pager_map, count*PAGE_SIZE); @@ -1429,10 +1406,7 @@ retrygetspace: /* * map our page(s) into kva for I/O */ - for (i = 0; i < count; i++) { - pmap_kenter( kva + PAGE_SIZE * i, VM_PAGE_TO_PHYS(m[i])); - } - pmap_update(); + pmap_qenter(kva, m, count); /* * get the base I/O offset into the swap file @@ -1473,12 +1447,7 @@ retrygetspace: bp->b_un.b_addr = (caddr_t) kva; bp->b_blkno = reqaddr[0]; bgetvp( swapdev_vp, bp); -/* - VHOLD(swapdev_vp); - bp->b_vp = swapdev_vp; - if (swapdev_vp->v_type == VBLK) - bp->b_dev = swapdev_vp->v_rdev; -*/ + bp->b_bcount = PAGE_SIZE*count; bp->b_bufsize = PAGE_SIZE*count; swapdev_vp->v_numoutput++; @@ -1543,7 +1512,7 @@ retrygetspace: /* * remove the mapping for kernel virtual */ - pmap_remove(vm_map_pmap(pager_map), kva, kva + count * PAGE_SIZE); + pmap_qremove( kva, count); /* * if we have written the page, then indicate that the page @@ -1604,11 +1573,11 @@ swap_pager_clean() */ while (spc = swap_pager_done.tqh_first) { if( spc->spc_altkva) { - pmap_remove(vm_map_pmap(pager_map), spc->spc_altkva, spc->spc_altkva + spc->spc_count * PAGE_SIZE); + pmap_qremove( spc->spc_altkva, spc->spc_count); kmem_free_wakeup(pager_map, spc->spc_altkva, spc->spc_count * PAGE_SIZE); spc->spc_altkva = 0; } else { - pmap_remove(vm_map_pmap(pager_map), spc->spc_kva, spc->spc_kva + PAGE_SIZE); + pmap_qremove( spc->spc_kva, 1); } swap_pager_finish(spc); TAILQ_REMOVE(&swap_pager_done, spc, spc_list); @@ -1742,86 +1711,6 @@ swap_pager_iodone(bp) splx(s); } -int bswneeded; -/* TAILQ_HEAD(swqueue, buf) bswlist; */ -/* - * allocate a physical buffer - */ -struct buf * -getpbuf() { - int s; - struct buf *bp; - - s = splbio(); - /* get a bp from the swap buffer header pool */ - while ((bp = bswlist.tqh_first) == NULL) { - bswneeded = 1; - tsleep((caddr_t)&bswneeded, PVM, "wswbuf", 0); - } - TAILQ_REMOVE(&bswlist, bp, b_freelist); - - splx(s); - - bzero(bp, sizeof *bp); - bp->b_rcred = NOCRED; - bp->b_wcred = NOCRED; - return bp; -} - -/* - * allocate a physical buffer, if one is available - */ -struct buf * -trypbuf() { - int s; - struct buf *bp; - - s = splbio(); - if ((bp = bswlist.tqh_first) == NULL) { - splx(s); - return NULL; - } - TAILQ_REMOVE(&bswlist, bp, b_freelist); - splx(s); - - bzero(bp, sizeof *bp); - bp->b_rcred = NOCRED; - bp->b_wcred = NOCRED; - return bp; -} - -/* - * release a physical buffer - */ -void -relpbuf(bp) - struct buf *bp; -{ - int s; - - s = splbio(); - - if (bp->b_rcred != NOCRED) { - crfree(bp->b_rcred); - bp->b_rcred = NOCRED; - } - if (bp->b_wcred != NOCRED) { - crfree(bp->b_wcred); - bp->b_wcred = NOCRED; - } - - if (bp->b_vp) - brelvp(bp); - - TAILQ_INSERT_HEAD(&bswlist, bp, b_freelist); - - if (bswneeded) { - bswneeded = 0; - wakeup((caddr_t)&bswlist); - } - splx(s); -} - /* * return true if any swap control structures can be allocated */ |