swap_pager.c (2a758ebe58269f6c32edf4ac298577e274993e13) swap_pager.c (a9fa2c05fcc4b5cfa4734f5c18a3bce8755e6e6b)
1/*
2 * Copyright (c) 1998 Matthew Dillon,
3 * Copyright (c) 1994 John S. Dyson
4 * Copyright (c) 1990 University of Utah.
5 * Copyright (c) 1991, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by

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

75#include <sys/bio.h>
76#include <sys/buf.h>
77#include <sys/vnode.h>
78#include <sys/malloc.h>
79#include <sys/vmmeter.h>
80#include <sys/sysctl.h>
81#include <sys/blist.h>
82#include <sys/lock.h>
1/*
2 * Copyright (c) 1998 Matthew Dillon,
3 * Copyright (c) 1994 John S. Dyson
4 * Copyright (c) 1990 University of Utah.
5 * Copyright (c) 1991, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by

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

75#include <sys/bio.h>
76#include <sys/buf.h>
77#include <sys/vnode.h>
78#include <sys/malloc.h>
79#include <sys/vmmeter.h>
80#include <sys/sysctl.h>
81#include <sys/blist.h>
82#include <sys/lock.h>
83#include <sys/sx.h>
83#include <sys/vmmeter.h>
84
85#ifndef MAX_PAGEOUT_CLUSTER
86#define MAX_PAGEOUT_CLUSTER 16
87#endif
88
89#define SWB_NPAGES MAX_PAGEOUT_CLUSTER
90

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

113
114int swap_pager_full; /* swap space exhaustion (task killing) */
115static int swap_pager_almost_full; /* swap space exhaustion (w/ hysteresis)*/
116static int nsw_rcount; /* free read buffers */
117static int nsw_wcount_sync; /* limit write buffers / synchronous */
118static int nsw_wcount_async; /* limit write buffers / asynchronous */
119static int nsw_wcount_async_max;/* assigned maximum */
120static int nsw_cluster_max; /* maximum VOP I/O allowed */
84#include <sys/vmmeter.h>
85
86#ifndef MAX_PAGEOUT_CLUSTER
87#define MAX_PAGEOUT_CLUSTER 16
88#endif
89
90#define SWB_NPAGES MAX_PAGEOUT_CLUSTER
91

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

114
115int swap_pager_full; /* swap space exhaustion (task killing) */
116static int swap_pager_almost_full; /* swap space exhaustion (w/ hysteresis)*/
117static int nsw_rcount; /* free read buffers */
118static int nsw_wcount_sync; /* limit write buffers / synchronous */
119static int nsw_wcount_async; /* limit write buffers / asynchronous */
120static int nsw_wcount_async_max;/* assigned maximum */
121static int nsw_cluster_max; /* maximum VOP I/O allowed */
121static int sw_alloc_interlock; /* swap pager allocation interlock */
122
123struct blist *swapblist;
124static struct swblock **swhash;
125static int swhash_mask;
126static int swap_async_max = 4; /* maximum in-progress async I/O's */
127
128/* from vm_swap.c */
129extern struct vnode *swapdev_vp;

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

140 * of searching a named list by hashing it just a little.
141 */
142
143#define NOBJLISTS 8
144
145#define NOBJLIST(handle) \
146 (&swap_pager_object_list[((int)(intptr_t)handle >> 4) & (NOBJLISTS-1)])
147
122
123struct blist *swapblist;
124static struct swblock **swhash;
125static int swhash_mask;
126static int swap_async_max = 4; /* maximum in-progress async I/O's */
127
128/* from vm_swap.c */
129extern struct vnode *swapdev_vp;

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

140 * of searching a named list by hashing it just a little.
141 */
142
143#define NOBJLISTS 8
144
145#define NOBJLIST(handle) \
146 (&swap_pager_object_list[((int)(intptr_t)handle >> 4) & (NOBJLISTS-1)])
147
148static struct sx sw_alloc_sx; /* prevent concurrant creation */
149static struct mtx sw_alloc_mtx; /* protect list manipulation */
148static struct pagerlst swap_pager_object_list[NOBJLISTS];
149struct pagerlst swap_pager_un_object_list;
150vm_zone_t swap_zone;
151
152/*
153 * pagerops for OBJT_SWAP - "swap pager". Some ops are also global procedure
154 * calls hooked from other parts of the VM system and do not appear here.
155 * (see vm/swap_pager.h).

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

257 /*
258 * Initialize object lists
259 */
260 int i;
261
262 for (i = 0; i < NOBJLISTS; ++i)
263 TAILQ_INIT(&swap_pager_object_list[i]);
264 TAILQ_INIT(&swap_pager_un_object_list);
150static struct pagerlst swap_pager_object_list[NOBJLISTS];
151struct pagerlst swap_pager_un_object_list;
152vm_zone_t swap_zone;
153
154/*
155 * pagerops for OBJT_SWAP - "swap pager". Some ops are also global procedure
156 * calls hooked from other parts of the VM system and do not appear here.
157 * (see vm/swap_pager.h).

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

259 /*
260 * Initialize object lists
261 */
262 int i;
263
264 for (i = 0; i < NOBJLISTS; ++i)
265 TAILQ_INIT(&swap_pager_object_list[i]);
266 TAILQ_INIT(&swap_pager_un_object_list);
267 sx_init(&sw_alloc_sx, "swap_pager create");
268 mtx_init(&sw_alloc_mtx, "swap_pager list", MTX_DEF);
265
266 /*
267 * Device Stripe, in PAGE_SIZE'd blocks
268 */
269
270 dmmax = SWB_NPAGES * 2;
271 dmmax_mask = ~(dmmax - 1);
272}

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

380 if (handle) {
381 /*
382 * Reference existing named region or allocate new one. There
383 * should not be a race here against swp_pager_meta_build()
384 * as called from vm_page_remove() in regards to the lookup
385 * of the handle.
386 */
387
269
270 /*
271 * Device Stripe, in PAGE_SIZE'd blocks
272 */
273
274 dmmax = SWB_NPAGES * 2;
275 dmmax_mask = ~(dmmax - 1);
276}

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

384 if (handle) {
385 /*
386 * Reference existing named region or allocate new one. There
387 * should not be a race here against swp_pager_meta_build()
388 * as called from vm_page_remove() in regards to the lookup
389 * of the handle.
390 */
391
388 while (sw_alloc_interlock) {
389 sw_alloc_interlock = -1;
390 tsleep(&sw_alloc_interlock, PVM, "swpalc", 0);
391 }
392 sw_alloc_interlock = 1;
392 sx_xlock(&sw_alloc_sx);
393
394 object = vm_pager_object_lookup(NOBJLIST(handle), handle);
395
396 if (object != NULL) {
397 vm_object_reference(object);
398 } else {
399 object = vm_object_allocate(OBJT_DEFAULT,
400 OFF_TO_IDX(offset + PAGE_MASK + size));
401 object->handle = handle;
402
403 swp_pager_meta_build(object, 0, SWAPBLK_NONE);
404 }
405
393
394 object = vm_pager_object_lookup(NOBJLIST(handle), handle);
395
396 if (object != NULL) {
397 vm_object_reference(object);
398 } else {
399 object = vm_object_allocate(OBJT_DEFAULT,
400 OFF_TO_IDX(offset + PAGE_MASK + size));
401 object->handle = handle;
402
403 swp_pager_meta_build(object, 0, SWAPBLK_NONE);
404 }
405
406 if (sw_alloc_interlock < 0)
407 wakeup(&sw_alloc_interlock);
408
409 sw_alloc_interlock = 0;
406 sx_xunlock(&sw_alloc_sx);
410 } else {
411 object = vm_object_allocate(OBJT_DEFAULT,
412 OFF_TO_IDX(offset + PAGE_MASK + size));
413
414 swp_pager_meta_build(object, 0, SWAPBLK_NONE);
415 }
416
417 return (object);

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

436{
437 int s;
438
439 /*
440 * Remove from list right away so lookups will fail if we block for
441 * pageout completion.
442 */
443
407 } else {
408 object = vm_object_allocate(OBJT_DEFAULT,
409 OFF_TO_IDX(offset + PAGE_MASK + size));
410
411 swp_pager_meta_build(object, 0, SWAPBLK_NONE);
412 }
413
414 return (object);

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

433{
434 int s;
435
436 /*
437 * Remove from list right away so lookups will fail if we block for
438 * pageout completion.
439 */
440
441 mtx_lock(&sw_alloc_mtx);
444 if (object->handle == NULL) {
445 TAILQ_REMOVE(&swap_pager_un_object_list, object, pager_object_list);
446 } else {
447 TAILQ_REMOVE(NOBJLIST(object->handle), object, pager_object_list);
448 }
442 if (object->handle == NULL) {
443 TAILQ_REMOVE(&swap_pager_un_object_list, object, pager_object_list);
444 } else {
445 TAILQ_REMOVE(NOBJLIST(object->handle), object, pager_object_list);
446 }
447 mtx_unlock(&sw_alloc_mtx);
449
450 vm_object_pip_wait(object, "swpdea");
451
452 /*
453 * Free all remaining metadata. We only bother to free it from
454 * the swap meta data. We do not attempt to free swapblk's still
455 * associated with vm_page_t's for this object. We do not care
456 * if paging is still in progress on some objects.

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

637 s = splvm();
638
639 /*
640 * If destroysource is set, we remove the source object from the
641 * swap_pager internal queue now.
642 */
643
644 if (destroysource) {
448
449 vm_object_pip_wait(object, "swpdea");
450
451 /*
452 * Free all remaining metadata. We only bother to free it from
453 * the swap meta data. We do not attempt to free swapblk's still
454 * associated with vm_page_t's for this object. We do not care
455 * if paging is still in progress on some objects.

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

636 s = splvm();
637
638 /*
639 * If destroysource is set, we remove the source object from the
640 * swap_pager internal queue now.
641 */
642
643 if (destroysource) {
644 mtx_lock(&sw_alloc_mtx);
645 if (srcobject->handle == NULL) {
646 TAILQ_REMOVE(
647 &swap_pager_un_object_list,
648 srcobject,
649 pager_object_list
650 );
651 } else {
652 TAILQ_REMOVE(
653 NOBJLIST(srcobject->handle),
654 srcobject,
655 pager_object_list
656 );
657 }
645 if (srcobject->handle == NULL) {
646 TAILQ_REMOVE(
647 &swap_pager_un_object_list,
648 srcobject,
649 pager_object_list
650 );
651 } else {
652 TAILQ_REMOVE(
653 NOBJLIST(srcobject->handle),
654 srcobject,
655 pager_object_list
656 );
657 }
658 mtx_unlock(&sw_alloc_mtx);
658 }
659
660 /*
661 * transfer source to destination.
662 */
663
664 for (i = 0; i < dstobject->size; ++i) {
665 daddr_t dstaddr;

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

1748 /*
1749 * Convert default object to swap object if necessary
1750 */
1751
1752 if (object->type != OBJT_SWAP) {
1753 object->type = OBJT_SWAP;
1754 object->un_pager.swp.swp_bcount = 0;
1755
659 }
660
661 /*
662 * transfer source to destination.
663 */
664
665 for (i = 0; i < dstobject->size; ++i) {
666 daddr_t dstaddr;

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

1749 /*
1750 * Convert default object to swap object if necessary
1751 */
1752
1753 if (object->type != OBJT_SWAP) {
1754 object->type = OBJT_SWAP;
1755 object->un_pager.swp.swp_bcount = 0;
1756
1757 mtx_lock(&sw_alloc_mtx);
1756 if (object->handle != NULL) {
1757 TAILQ_INSERT_TAIL(
1758 NOBJLIST(object->handle),
1759 object,
1760 pager_object_list
1761 );
1762 } else {
1763 TAILQ_INSERT_TAIL(
1764 &swap_pager_un_object_list,
1765 object,
1766 pager_object_list
1767 );
1768 }
1758 if (object->handle != NULL) {
1759 TAILQ_INSERT_TAIL(
1760 NOBJLIST(object->handle),
1761 object,
1762 pager_object_list
1763 );
1764 } else {
1765 TAILQ_INSERT_TAIL(
1766 &swap_pager_un_object_list,
1767 object,
1768 pager_object_list
1769 );
1770 }
1771 mtx_unlock(&sw_alloc_mtx);
1769 }
1770
1771 /*
1772 * Locate hash entry. If not found create, but if we aren't adding
1773 * anything just return. If we run out of space in the map we wait
1774 * and, since the hash table may have changed, retry.
1775 */
1776

--- 320 unchanged lines hidden ---
1772 }
1773
1774 /*
1775 * Locate hash entry. If not found create, but if we aren't adding
1776 * anything just return. If we run out of space in the map we wait
1777 * and, since the hash table may have changed, retry.
1778 */
1779

--- 320 unchanged lines hidden ---