Deleted Added
full compact
swap_pager.c (15583) swap_pager.c (15809)
1/*
2 * Copyright (c) 1994 John S. Dyson
3 * Copyright (c) 1990 University of Utah.
4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * the Systems Programming Group of the University of Utah Computer

--- 25 unchanged lines hidden (view full) ---

34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
39 * from: Utah $Hdr: swap_pager.c 1.4 91/04/30$
40 *
41 * @(#)swap_pager.c 8.9 (Berkeley) 3/21/94
1/*
2 * Copyright (c) 1994 John S. Dyson
3 * Copyright (c) 1990 University of Utah.
4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * the Systems Programming Group of the University of Utah Computer

--- 25 unchanged lines hidden (view full) ---

34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
39 * from: Utah $Hdr: swap_pager.c 1.4 91/04/30$
40 *
41 * @(#)swap_pager.c 8.9 (Berkeley) 3/21/94
42 * $Id: swap_pager.c,v 1.64 1996/05/02 14:21:14 phk Exp $
42 * $Id: swap_pager.c,v 1.65 1996/05/03 21:01:47 phk Exp $
43 */
44
45/*
46 * Quick hack to page to dedicated partition(s).
47 * TODO:
48 * Add multiprocessor locks
49 * Deal with async writes in a better fashion
50 */

--- 474 unchanged lines hidden (view full) ---

525 return;
526 }
527 in_reclaim = 1;
528 reclaimcount = 0;
529
530 /* for each pager queue */
531 for (k = 0; swp_qs[k]; k++) {
532
43 */
44
45/*
46 * Quick hack to page to dedicated partition(s).
47 * TODO:
48 * Add multiprocessor locks
49 * Deal with async writes in a better fashion
50 */

--- 474 unchanged lines hidden (view full) ---

525 return;
526 }
527 in_reclaim = 1;
528 reclaimcount = 0;
529
530 /* for each pager queue */
531 for (k = 0; swp_qs[k]; k++) {
532
533 object = swp_qs[k]->tqh_first;
533 object = TAILQ_FIRST(swp_qs[k]);
534 while (object && (reclaimcount < MAXRECLAIM)) {
535
536 /*
537 * see if any blocks associated with a pager has been
538 * allocated but not used (written)
539 */
540 if (object->paging_in_progress == 0) {
541 for (i = 0; i < object->un_pager.swp.swp_nblocks; i++) {

--- 8 unchanged lines hidden (view full) ---

550 reclaims[reclaimcount++].object = object;
551 swb->swb_block[j] = SWB_EMPTY;
552 if (reclaimcount >= MAXRECLAIM)
553 goto rfinished;
554 }
555 }
556 }
557 }
534 while (object && (reclaimcount < MAXRECLAIM)) {
535
536 /*
537 * see if any blocks associated with a pager has been
538 * allocated but not used (written)
539 */
540 if (object->paging_in_progress == 0) {
541 for (i = 0; i < object->un_pager.swp.swp_nblocks; i++) {

--- 8 unchanged lines hidden (view full) ---

550 reclaims[reclaimcount++].object = object;
551 swb->swb_block[j] = SWB_EMPTY;
552 if (reclaimcount >= MAXRECLAIM)
553 goto rfinished;
554 }
555 }
556 }
557 }
558 object = object->pager_object_list.tqe_next;
558 object = TAILQ_NEXT(object, pager_object_list);
559 }
560 }
561
562rfinished:
563
564 /*
565 * free the blocks that have been added to the reclaim list
566 */

--- 384 unchanged lines hidden (view full) ---

951 * at this point: "m" is a pointer to the array of vm_page_t for
952 * paging I/O "count" is the number of vm_page_t entries represented
953 * by "m" "object" is the vm_object_t for I/O "reqpage" is the index
954 * into "m" for the page actually faulted
955 */
956
957 spc = NULL; /* we might not use an spc data structure */
958
559 }
560 }
561
562rfinished:
563
564 /*
565 * free the blocks that have been added to the reclaim list
566 */

--- 384 unchanged lines hidden (view full) ---

951 * at this point: "m" is a pointer to the array of vm_page_t for
952 * paging I/O "count" is the number of vm_page_t entries represented
953 * by "m" "object" is the vm_object_t for I/O "reqpage" is the index
954 * into "m" for the page actually faulted
955 */
956
957 spc = NULL; /* we might not use an spc data structure */
958
959 if ((count == 1) && (swap_pager_free.tqh_first != NULL)) {
960 spc = swap_pager_free.tqh_first;
959 if ((count == 1) && (TAILQ_FIRST(&swap_pager_free) != NULL)) {
960 spc = TAILQ_FIRST(&swap_pager_free);
961 TAILQ_REMOVE(&swap_pager_free, spc, spc_list);
962 kva = spc->spc_kva;
963 bp = spc->spc_bp;
964 bzero(bp, sizeof *bp);
965 bp->b_spc = spc;
966 bp->b_vnbufs.le_next = NOLIST;
967 } else {
968 /*

--- 289 unchanged lines hidden (view full) ---

1258 if (sync == TRUE) {
1259 swap_pager_sync();
1260 }
1261 kva = 0;
1262
1263 /*
1264 * get a swap pager clean data structure, block until we get it
1265 */
961 TAILQ_REMOVE(&swap_pager_free, spc, spc_list);
962 kva = spc->spc_kva;
963 bp = spc->spc_bp;
964 bzero(bp, sizeof *bp);
965 bp->b_spc = spc;
966 bp->b_vnbufs.le_next = NOLIST;
967 } else {
968 /*

--- 289 unchanged lines hidden (view full) ---

1258 if (sync == TRUE) {
1259 swap_pager_sync();
1260 }
1261 kva = 0;
1262
1263 /*
1264 * get a swap pager clean data structure, block until we get it
1265 */
1266 if (swap_pager_free.tqh_first == NULL ||
1267 swap_pager_free.tqh_first->spc_list.tqe_next == NULL ||
1268 swap_pager_free.tqh_first->spc_list.tqe_next->spc_list.tqe_next == NULL) {
1266 if (TAILQ_FIRST(&swap_pager_free) == NULL ||
1267 TAILQ_NEXT(TAILQ_FIRST(&swap_pager_free),spc_list) == NULL ||
1268 TAILQ_NEXT(TAILQ_NEXT(TAILQ_FIRST(&swap_pager_free),spc_list),spc_list) == NULL) {
1269 s = splbio();
1270 if (curproc == pageproc) {
1271retryfree:
1272 /*
1273 * pageout daemon needs a swap control block
1274 */
1275 swap_pager_needflags |= SWAP_FREE_NEEDED_BY_PAGEOUT|SWAP_FREE_NEEDED;
1276 /*
1277 * if it does not get one within a short time, then
1278 * there is a potential deadlock, so we go-on trying
1279 * to free pages. It is important to block here as opposed
1280 * to returning, thereby allowing the pageout daemon to continue.
1281 * It is likely that pageout daemon will start suboptimally
1282 * reclaiming vnode backed pages if we don't block. Since the
1283 * I/O subsystem is probably already fully utilized, might as
1284 * well wait.
1285 */
1286 if (tsleep(&swap_pager_free, PVM, "swpfre", hz/5)) {
1287 swap_pager_sync();
1269 s = splbio();
1270 if (curproc == pageproc) {
1271retryfree:
1272 /*
1273 * pageout daemon needs a swap control block
1274 */
1275 swap_pager_needflags |= SWAP_FREE_NEEDED_BY_PAGEOUT|SWAP_FREE_NEEDED;
1276 /*
1277 * if it does not get one within a short time, then
1278 * there is a potential deadlock, so we go-on trying
1279 * to free pages. It is important to block here as opposed
1280 * to returning, thereby allowing the pageout daemon to continue.
1281 * It is likely that pageout daemon will start suboptimally
1282 * reclaiming vnode backed pages if we don't block. Since the
1283 * I/O subsystem is probably already fully utilized, might as
1284 * well wait.
1285 */
1286 if (tsleep(&swap_pager_free, PVM, "swpfre", hz/5)) {
1287 swap_pager_sync();
1288 if (swap_pager_free.tqh_first == NULL ||
1289 swap_pager_free.tqh_first->spc_list.tqe_next == NULL ||
1290 swap_pager_free.tqh_first->spc_list.tqe_next->spc_list.tqe_next == NULL) {
1288 if (TAILQ_FIRST(&swap_pager_free) == NULL ||
1289 TAILQ_NEXT(TAILQ_FIRST(&swap_pager_free),spc_list) == NULL ||
1290 TAILQ_NEXT(TAILQ_NEXT(TAILQ_FIRST(&swap_pager_free),spc_list),spc_list) == NULL) {
1291 splx(s);
1292 return VM_PAGER_AGAIN;
1293 }
1294 } else {
1295 /*
1296 * we make sure that pageouts aren't taking up all of
1297 * the free swap control blocks.
1298 */
1299 swap_pager_sync();
1291 splx(s);
1292 return VM_PAGER_AGAIN;
1293 }
1294 } else {
1295 /*
1296 * we make sure that pageouts aren't taking up all of
1297 * the free swap control blocks.
1298 */
1299 swap_pager_sync();
1300 if (swap_pager_free.tqh_first == NULL ||
1301 swap_pager_free.tqh_first->spc_list.tqe_next == NULL ||
1302 swap_pager_free.tqh_first->spc_list.tqe_next->spc_list.tqe_next == NULL) {
1300 if (TAILQ_FIRST(&swap_pager_free) == NULL ||
1301 TAILQ_NEXT(TAILQ_FIRST(&swap_pager_free),spc_list) == NULL ||
1302 TAILQ_NEXT(TAILQ_NEXT(TAILQ_FIRST(&swap_pager_free),spc_list),spc_list) == NULL) {
1303 goto retryfree;
1304 }
1305 }
1306 } else {
1307 pagedaemon_wakeup();
1303 goto retryfree;
1304 }
1305 }
1306 } else {
1307 pagedaemon_wakeup();
1308 while (swap_pager_free.tqh_first == NULL ||
1309 swap_pager_free.tqh_first->spc_list.tqe_next == NULL ||
1310 swap_pager_free.tqh_first->spc_list.tqe_next->spc_list.tqe_next == NULL) {
1308 while (TAILQ_FIRST(&swap_pager_free) == NULL ||
1309 TAILQ_NEXT(TAILQ_FIRST(&swap_pager_free),spc_list) == NULL ||
1310 TAILQ_NEXT(TAILQ_NEXT(TAILQ_FIRST(&swap_pager_free),spc_list),spc_list) == NULL) {
1311 swap_pager_needflags |= SWAP_FREE_NEEDED;
1312 tsleep(&swap_pager_free, PVM, "swpfre", 0);
1313 pagedaemon_wakeup();
1314 }
1315 }
1316 splx(s);
1317 }
1311 swap_pager_needflags |= SWAP_FREE_NEEDED;
1312 tsleep(&swap_pager_free, PVM, "swpfre", 0);
1313 pagedaemon_wakeup();
1314 }
1315 }
1316 splx(s);
1317 }
1318 spc = swap_pager_free.tqh_first;
1318 spc = TAILQ_FIRST(&swap_pager_free);
1319 TAILQ_REMOVE(&swap_pager_free, spc, spc_list);
1320
1321 kva = spc->spc_kva;
1322
1323 /*
1324 * map our page(s) into kva for I/O
1325 */
1326 pmap_qenter(kva, m, count);

--- 150 unchanged lines hidden (view full) ---

1477
1478static void
1479swap_pager_sync()
1480{
1481 register swp_clean_t spc, tspc;
1482 register int s;
1483
1484 tspc = NULL;
1319 TAILQ_REMOVE(&swap_pager_free, spc, spc_list);
1320
1321 kva = spc->spc_kva;
1322
1323 /*
1324 * map our page(s) into kva for I/O
1325 */
1326 pmap_qenter(kva, m, count);

--- 150 unchanged lines hidden (view full) ---

1477
1478static void
1479swap_pager_sync()
1480{
1481 register swp_clean_t spc, tspc;
1482 register int s;
1483
1484 tspc = NULL;
1485 if (swap_pager_done.tqh_first == NULL)
1485 if (TAILQ_FIRST(&swap_pager_done) == NULL)
1486 return;
1487 for (;;) {
1488 s = splbio();
1489 /*
1490 * Look up and removal from done list must be done at splbio()
1491 * to avoid conflicts with swap_pager_iodone.
1492 */
1486 return;
1487 for (;;) {
1488 s = splbio();
1489 /*
1490 * Look up and removal from done list must be done at splbio()
1491 * to avoid conflicts with swap_pager_iodone.
1492 */
1493 while ((spc = swap_pager_done.tqh_first) != 0) {
1493 while ((spc = TAILQ_FIRST(&swap_pager_done)) != 0) {
1494 pmap_qremove(spc->spc_kva, spc->spc_count);
1495 swap_pager_finish(spc);
1496 TAILQ_REMOVE(&swap_pager_done, spc, spc_list);
1497 goto doclean;
1498 }
1499
1500 /*
1501 * No operations done, thats all we can do for now.

--- 102 unchanged lines hidden (view full) ---

1604 if (bp->b_wcred != NOCRED)
1605 crfree(bp->b_wcred);
1606
1607 nswiodone += spc->spc_count;
1608 if (--spc->spc_object->un_pager.swp.swp_poip == 0) {
1609 wakeup(spc->spc_object);
1610 }
1611 if ((swap_pager_needflags & SWAP_FREE_NEEDED) ||
1494 pmap_qremove(spc->spc_kva, spc->spc_count);
1495 swap_pager_finish(spc);
1496 TAILQ_REMOVE(&swap_pager_done, spc, spc_list);
1497 goto doclean;
1498 }
1499
1500 /*
1501 * No operations done, thats all we can do for now.

--- 102 unchanged lines hidden (view full) ---

1604 if (bp->b_wcred != NOCRED)
1605 crfree(bp->b_wcred);
1606
1607 nswiodone += spc->spc_count;
1608 if (--spc->spc_object->un_pager.swp.swp_poip == 0) {
1609 wakeup(spc->spc_object);
1610 }
1611 if ((swap_pager_needflags & SWAP_FREE_NEEDED) ||
1612 swap_pager_inuse.tqh_first == 0) {
1612 TAILQ_FIRST(&swap_pager_inuse) == 0) {
1613 swap_pager_needflags &= ~SWAP_FREE_NEEDED;
1614 wakeup(&swap_pager_free);
1615 }
1616
1617 if( swap_pager_needflags & SWAP_FREE_NEEDED_BY_PAGEOUT) {
1618 swap_pager_needflags &= ~SWAP_FREE_NEEDED_BY_PAGEOUT;
1619 pagedaemon_wakeup();
1620 }
1621
1622 if (vm_pageout_pages_needed) {
1623 wakeup(&vm_pageout_pages_needed);
1624 vm_pageout_pages_needed = 0;
1625 }
1613 swap_pager_needflags &= ~SWAP_FREE_NEEDED;
1614 wakeup(&swap_pager_free);
1615 }
1616
1617 if( swap_pager_needflags & SWAP_FREE_NEEDED_BY_PAGEOUT) {
1618 swap_pager_needflags &= ~SWAP_FREE_NEEDED_BY_PAGEOUT;
1619 pagedaemon_wakeup();
1620 }
1621
1622 if (vm_pageout_pages_needed) {
1623 wakeup(&vm_pageout_pages_needed);
1624 vm_pageout_pages_needed = 0;
1625 }
1626 if ((swap_pager_inuse.tqh_first == NULL) ||
1626 if ((TAILQ_FIRST(&swap_pager_inuse) == NULL) ||
1627 ((cnt.v_free_count + cnt.v_cache_count) < cnt.v_free_min &&
1628 nswiodone + cnt.v_free_count + cnt.v_cache_count >= cnt.v_free_min)) {
1629 pagedaemon_wakeup();
1630 }
1631 splx(s);
1632}
1627 ((cnt.v_free_count + cnt.v_cache_count) < cnt.v_free_min &&
1628 nswiodone + cnt.v_free_count + cnt.v_cache_count >= cnt.v_free_min)) {
1629 pagedaemon_wakeup();
1630 }
1631 splx(s);
1632}