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 --- |