Changeset View
Changeset View
Standalone View
Standalone View
sys/vm/swap_pager.c
Show First 20 Lines • Show All 317 Lines • ▼ Show 20 Lines | |||||
#ifdef RACCT | #ifdef RACCT | ||||
if (racct_enable) | if (racct_enable) | ||||
racct_sub_cred(cred, RACCT_SWAP, decr); | racct_sub_cred(cred, RACCT_SWAP, decr); | ||||
#endif | #endif | ||||
} | } | ||||
#define SWM_POP 0x01 /* pop out */ | #define SWM_POP 0x01 /* pop out */ | ||||
static int swap_pager_full = 2; /* swap space exhaustion (task killing) */ | enum swp_gauge { SWPG_LOW, SWPG_ALMOST_FULL, SWPG_FULL }; | ||||
freqlabs: Please add comments describing what each of these means. | |||||
static int swap_pager_almost_full = 1; /* swap space exhaustion (w/hysteresis)*/ | typedef u_char swpgauge_t; | ||||
static swpgauge_t swp_gauge = SWPG_FULL; | |||||
static struct mtx swbuf_mtx; /* to sync nsw_wcount_async */ | static struct mtx swbuf_mtx; /* to sync nsw_wcount_async */ | ||||
static int nsw_wcount_async; /* limit async write buffers */ | static int nsw_wcount_async; /* limit async write buffers */ | ||||
static int nsw_wcount_async_max;/* assigned maximum */ | static int nsw_wcount_async_max;/* assigned maximum */ | ||||
static int nsw_cluster_max; /* maximum VOP I/O allowed */ | static int nsw_cluster_max; /* maximum VOP I/O allowed */ | ||||
static int sysctl_swap_async_max(SYSCTL_HANDLER_ARGS); | static int sysctl_swap_async_max(SYSCTL_HANDLER_ARGS); | ||||
SYSCTL_PROC(_vm, OID_AUTO, swap_async_max, CTLTYPE_INT | CTLFLAG_RW | | SYSCTL_PROC(_vm, OID_AUTO, swap_async_max, CTLTYPE_INT | CTLFLAG_RW | | ||||
CTLFLAG_MPSAFE, NULL, 0, sysctl_swap_async_max, "I", | CTLFLAG_MPSAFE, NULL, 0, sysctl_swap_async_max, "I", | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | struct pagerops swappagerops = { | ||||
.pgo_update_writecount = swap_pager_update_writecount, | .pgo_update_writecount = swap_pager_update_writecount, | ||||
.pgo_release_writecount = swap_pager_release_writecount, | .pgo_release_writecount = swap_pager_release_writecount, | ||||
}; | }; | ||||
/* | /* | ||||
* swap_*() routines are externally accessible. swp_*() routines are | * swap_*() routines are externally accessible. swp_*() routines are | ||||
* internal. | * internal. | ||||
*/ | */ | ||||
static int nswap_lowat = 128; /* in pages, swap_pager_almost_full warn */ | static int nswap_lowat = 128; /* in pages, almost full warn */ | ||||
static int nswap_hiwat = 512; /* in pages, swap_pager_almost_full warn */ | static int nswap_hiwat = 512; /* in pages, almost full warn */ | ||||
SYSCTL_INT(_vm, OID_AUTO, dmmax, CTLFLAG_RD, &nsw_cluster_max, 0, | SYSCTL_INT(_vm, OID_AUTO, dmmax, CTLFLAG_RD, &nsw_cluster_max, 0, | ||||
"Maximum size of a swap block in pages"); | "Maximum size of a swap block in pages"); | ||||
static void swp_sizecheck(void); | static void swp_sizecheck(void); | ||||
static void swp_pager_async_iodone(struct buf *bp); | static void swp_pager_async_iodone(struct buf *bp); | ||||
static bool swp_pager_swblk_empty(struct swblk *sb, int start, int limit); | static bool swp_pager_swblk_empty(struct swblk *sb, int start, int limit); | ||||
static int swapongeom(struct vnode *); | static int swapongeom(struct vnode *); | ||||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
uma_zfree(swpctrie_zone, node); | uma_zfree(swpctrie_zone, node); | ||||
} | } | ||||
PCTRIE_DEFINE(SWAP, swblk, p, swblk_trie_alloc, swblk_trie_free); | PCTRIE_DEFINE(SWAP, swblk, p, swblk_trie_alloc, swblk_trie_free); | ||||
/* | /* | ||||
* SWP_SIZECHECK() - update swap_pager_full indication | * SWP_SIZECHECK() - update swp_gauge indication | ||||
* | * | ||||
* update the swap_pager_almost_full indication and warn when we are | * update the swp_gauge indication and warn when we are | ||||
* about to run out of swap space, using lowat/hiwat hysteresis. | * about to run out of swap space, using lowat/hiwat hysteresis. | ||||
* | * | ||||
* Clear swap_pager_full ( task killing ) indication when lowat is met. | |||||
* | |||||
* No restrictions on call | * No restrictions on call | ||||
* This routine may not block. | * This routine may not block. | ||||
*/ | */ | ||||
static void | static void | ||||
swp_sizecheck(void) | swp_sizecheck(void) | ||||
{ | { | ||||
if (swap_pager_avail < nswap_lowat) { | if (swap_pager_avail < nswap_lowat) { | ||||
if (swap_pager_almost_full == 0) { | if (swp_gauge == SWPG_LOW) { | ||||
printf("swap_pager: out of swap space\n"); | printf("swap_pager: almost out of swap - %dKB left\n", | ||||
swap_pager_almost_full = 1; | swap_pager_avail * PAGE_SIZE >> 10 ); | ||||
swp_gauge = SWPG_ALMOST_FULL; | |||||
Done Inline ActionsHow about "== SWPG_LOW"? dougm: How about "== SWPG_LOW"? | |||||
} | } | ||||
} else { | |||||
swap_pager_full = 0; | |||||
if (swap_pager_avail > nswap_hiwat) | |||||
swap_pager_almost_full = 0; | |||||
} | } | ||||
else if (swap_pager_avail > nswap_hiwat) { | |||||
dougmUnsubmitted Not Done Inline ActionsHow about if swap_pager_avail >= nswap_lowat and swap_pager_avail <= nswap_hiwat? You are changing that behavior. dougm: How about if swap_pager_avail >= nswap_lowat and swap_pager_avail <= nswap_hiwat? You are… | |||||
ota_j.email.ne.jpAuthorUnsubmitted Done Inline ActionsThat's a case when we reset SWPG_FULL status. Page in/out doesn't happen over (512-128) size block and system will hit the other cases. I think we are okay as is for now. Or I can add else case to the top if-elseif like following: if(swp_gauge == SWPG_FULL) swp_gauge = SWPG_LOW; } What do you think? ota_j.email.ne.jp: That's a case when we reset SWPG_FULL status.
Page in/out doesn't happen over (512-128) size… | |||||
swp_gauge = SWPG_LOW; | |||||
Not Done Inline ActionsWhy is this line necessary? dougm: Why is this line necessary? | |||||
} | } | ||||
} | |||||
/* | /* | ||||
* SWAP_PAGER_INIT() - initialize the swap pager! | * SWAP_PAGER_INIT() - initialize the swap pager! | ||||
* | * | ||||
* Expected to be started from system init. NOTE: This code is run | * Expected to be started from system init. NOTE: This code is run | ||||
* before much else so be careful what you depend on. Most of the VM | * before much else so be careful what you depend on. Most of the VM | ||||
* system has yet to be initialized at this point. | * system has yet to be initialized at this point. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 259 Lines • ▼ Show 20 Lines | swp_pager_getswapspace(int *io_npages, int limit) | ||||
if (blk != SWAPBLK_NONE) { | if (blk != SWAPBLK_NONE) { | ||||
*io_npages = npages; | *io_npages = npages; | ||||
blk += sp->sw_first; | blk += sp->sw_first; | ||||
sp->sw_used += npages; | sp->sw_used += npages; | ||||
swap_pager_avail -= npages; | swap_pager_avail -= npages; | ||||
swp_sizecheck(); | swp_sizecheck(); | ||||
swdevhd = TAILQ_NEXT(sp, sw_list); | swdevhd = TAILQ_NEXT(sp, sw_list); | ||||
} else { | } else { | ||||
if (swap_pager_full != 2) { | if (swp_gauge != SWPG_FULL) { | ||||
printf("swp_pager_getswapspace(%d): failed\n", | printf("%s(%d): failed\n", __func__, *io_npages); | ||||
Done Inline ActionsDoes this line really compile? It looks about 3 arguments short. dougm: Does this line really compile? It looks about 3 arguments short. | |||||
*io_npages); | swp_gauge = SWPG_FULL; | ||||
swap_pager_full = 2; | |||||
swap_pager_almost_full = 1; | |||||
} | } | ||||
swdevhd = NULL; | swdevhd = NULL; | ||||
} | } | ||||
mtx_unlock(&sw_dev_mtx); | mtx_unlock(&sw_dev_mtx); | ||||
return (blk); | return (blk); | ||||
} | } | ||||
static bool | static bool | ||||
▲ Show 20 Lines • Show All 1,655 Lines • ▼ Show 20 Lines | #endif | ||||
*/ | */ | ||||
swap_pager_swapoff(sp); | swap_pager_swapoff(sp); | ||||
sp->sw_close(curthread, sp); | sp->sw_close(curthread, sp); | ||||
mtx_lock(&sw_dev_mtx); | mtx_lock(&sw_dev_mtx); | ||||
sp->sw_id = NULL; | sp->sw_id = NULL; | ||||
TAILQ_REMOVE(&swtailq, sp, sw_list); | TAILQ_REMOVE(&swtailq, sp, sw_list); | ||||
nswapdev--; | nswapdev--; | ||||
if (nswapdev == 0) { | if (nswapdev == 0) | ||||
swap_pager_full = 2; | swp_gauge = SWPG_FULL; | ||||
swap_pager_almost_full = 1; | |||||
} | |||||
if (swdevhd == sp) | if (swdevhd == sp) | ||||
swdevhd = NULL; | swdevhd = NULL; | ||||
mtx_unlock(&sw_dev_mtx); | mtx_unlock(&sw_dev_mtx); | ||||
blist_destroy(sp->sw_blist); | blist_destroy(sp->sw_blist); | ||||
free(sp, M_VMPGDATA); | free(sp, M_VMPGDATA); | ||||
return (0); | return (0); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 571 Lines • Show Last 20 Lines |
Please add comments describing what each of these means.