Changeset View
Standalone View
sys/vm/swap_pager.c
Show First 20 Lines • Show All 334 Lines • ▼ Show 20 Lines | |||||
#endif | #endif | ||||
} | } | ||||
static int swap_pager_full = 2; /* swap space exhaustion (task killing) */ | static int swap_pager_full = 2; /* swap space exhaustion (task killing) */ | ||||
static int swap_pager_almost_full = 1; /* swap space exhaustion (w/hysteresis)*/ | static int swap_pager_almost_full = 1; /* swap space exhaustion (w/hysteresis)*/ | ||||
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 */ | int nsw_cluster_max = MIN(MAXPHYS / PAGE_SIZE, MAX_PAGEOUT_CLUSTER); /* maximum VOP I/O allowed */ | ||||
kib: I suspect this is no longer correct. | |||||
Done Inline ActionsOh, thanks for noticing! glebius: Oh, thanks for noticing! | |||||
Not Done Inline ActionsThis cannot work either, maxphys is initialized only in init_param2. I am not even sure that non-constant initialization is tolerated (i.e. does it compile)? Why the two first chunks for swap_pager.c are needed at all? kib: This cannot work either, maxphys is initialized only in init_param2. I am not even sure that… | |||||
Not Done Inline ActionsThe idea is to make nsw_cluster_max externally visible so we can calculate the maximum-sized swap buffer we are likely to see. See g_eli_init_uma() in g_eli.c jtl: The idea is to make nsw_cluster_max externally visible so we can calculate the maximum-sized… | |||||
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", | ||||
"Maximum running async swap ops"); | "Maximum running async swap ops"); | ||||
static int sysctl_swap_fragmentation(SYSCTL_HANDLER_ARGS); | static int sysctl_swap_fragmentation(SYSCTL_HANDLER_ARGS); | ||||
SYSCTL_PROC(_vm, OID_AUTO, swap_fragmentation, CTLTYPE_STRING | CTLFLAG_RD | | SYSCTL_PROC(_vm, OID_AUTO, swap_fragmentation, CTLTYPE_STRING | CTLFLAG_RD | | ||||
CTLFLAG_MPSAFE, NULL, 0, sysctl_swap_fragmentation, "A", | CTLFLAG_MPSAFE, NULL, 0, sysctl_swap_fragmentation, "A", | ||||
"Swap Fragmentation Info"); | "Swap Fragmentation Info"); | ||||
▲ Show 20 Lines • Show All 174 Lines • ▼ Show 20 Lines | swap_pager_init(void) | ||||
sx_init(&swdev_syscall_lock, "swsysc"); | sx_init(&swdev_syscall_lock, "swsysc"); | ||||
} | } | ||||
/* | /* | ||||
* SWAP_PAGER_SWAP_INIT() - swap pager initialization from pageout process | * SWAP_PAGER_SWAP_INIT() - swap pager initialization from pageout process | ||||
* | * | ||||
* Expected to be started from pageout process once, prior to entering | * Expected to be started from pageout process once, prior to entering | ||||
* its main loop. | * its main loop. | ||||
*/ | */ | ||||
Not Done Inline ActionsI would say nsw_cluster_max is initialized early so that GEOM_ELI can see it. kib: I would say `nsw_cluster_max is initialized early so that GEOM_ELI can see it.` | |||||
void | void | ||||
swap_pager_swap_init(void) | swap_pager_swap_init(void) | ||||
{ | { | ||||
unsigned long n, n2; | unsigned long n, n2; | ||||
/* | /* | ||||
* Number of in-transit swap bp operations. Don't | * Number of in-transit swap bp operations. Don't | ||||
* exhaust the pbufs completely. Make sure we | * exhaust the pbufs completely. Make sure we | ||||
* initialize workable values (0 will work for hysteresis | * initialize workable values (0 will work for hysteresis | ||||
* but it isn't very efficient). | * but it isn't very efficient). | ||||
* | * | ||||
* The nsw_cluster_max is constrained by the bp->b_pages[] | * The nsw_cluster_max is constrained by the bp->b_pages[] | ||||
Not Done Inline ActionsI would put there a replacement sentence that nsw_cluster_max is initialized in swap_pager_init() kib: I would put there a replacement sentence that nsw_cluster_max is initialized in swap_pager_init… | |||||
Done Inline ActionsI'd rather expand the comment in swap_pager_init() to explain why we are doing this early. My change makes this comment block dedicated solely to explanation of what nsw_wcount_async is, which I find good. Putting back a note about nsw_cluster_max into the middle of that explanation would disrupt it. Do you agree? glebius: I'd rather expand the comment in swap_pager_init() to explain why we are doing this early. My… | |||||
Done Inline ActionsOf course I do not object against expanding the comment in swap_pager_init(). If you do not like putting a reference in the middle of this comment, put it at the end: I want something there that points out for the complete set of nsw_* controls. kib: Of course I do not object against expanding the comment in swap_pager_init(). If you do not… | |||||
* array, which has MAXPHYS / PAGE_SIZE entries, and our locally | * array, which has MAXPHYS / PAGE_SIZE entries, and our locally | ||||
* defined MAX_PAGEOUT_CLUSTER. Also be aware that swap ops are | * defined MAX_PAGEOUT_CLUSTER. Also be aware that swap ops are | ||||
* constrained by the swap device interleave stripe size. | * constrained by the swap device interleave stripe size. | ||||
* | * | ||||
* Currently we hardwire nsw_wcount_async to 4. This limit is | * Currently we hardwire nsw_wcount_async to 4. This limit is | ||||
* designed to prevent other I/O from having high latencies due to | * designed to prevent other I/O from having high latencies due to | ||||
* our pageout I/O. The value 4 works well for one or two active swap | * our pageout I/O. The value 4 works well for one or two active swap | ||||
* devices but is probably a little low if you have more. Even so, | * devices but is probably a little low if you have more. Even so, | ||||
* a higher value would probably generate only a limited improvement | * a higher value would probably generate only a limited improvement | ||||
* with three or four active swap devices since the system does not | * with three or four active swap devices since the system does not | ||||
* typically have to pageout at extreme bandwidths. We will want | * typically have to pageout at extreme bandwidths. We will want | ||||
* at least 2 per swap devices, and 4 is a pretty good value if you | * at least 2 per swap devices, and 4 is a pretty good value if you | ||||
* have one NFS swap device due to the command/ack latency over NFS. | * have one NFS swap device due to the command/ack latency over NFS. | ||||
* So it all works out pretty well. | * So it all works out pretty well. | ||||
*/ | */ | ||||
nsw_cluster_max = min(MAXPHYS / PAGE_SIZE, MAX_PAGEOUT_CLUSTER); | |||||
nsw_wcount_async = 4; | nsw_wcount_async = 4; | ||||
nsw_wcount_async_max = nsw_wcount_async; | nsw_wcount_async_max = nsw_wcount_async; | ||||
mtx_init(&swbuf_mtx, "async swbuf mutex", NULL, MTX_DEF); | mtx_init(&swbuf_mtx, "async swbuf mutex", NULL, MTX_DEF); | ||||
swwbuf_zone = pbuf_zsecond_create("swwbuf", nswbuf / 4); | swwbuf_zone = pbuf_zsecond_create("swwbuf", nswbuf / 4); | ||||
swrbuf_zone = pbuf_zsecond_create("swrbuf", nswbuf / 2); | swrbuf_zone = pbuf_zsecond_create("swrbuf", nswbuf / 2); | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 2,246 Lines • ▼ Show 20 Lines | swapgeom_strategy(struct buf *bp, struct swdevt *sp) | ||||
bp->b_caller1 = bio; | bp->b_caller1 = bio; | ||||
bio->bio_caller1 = sp; | bio->bio_caller1 = sp; | ||||
bio->bio_caller2 = bp; | bio->bio_caller2 = bp; | ||||
bio->bio_cmd = bp->b_iocmd; | bio->bio_cmd = bp->b_iocmd; | ||||
bio->bio_offset = (bp->b_blkno - sp->sw_first) * PAGE_SIZE; | bio->bio_offset = (bp->b_blkno - sp->sw_first) * PAGE_SIZE; | ||||
bio->bio_length = bp->b_bcount; | bio->bio_length = bp->b_bcount; | ||||
bio->bio_done = swapgeom_done; | bio->bio_done = swapgeom_done; | ||||
bio->bio_flags |= BIO_SWAP; | |||||
if (!buf_mapped(bp)) { | if (!buf_mapped(bp)) { | ||||
bio->bio_ma = bp->b_pages; | bio->bio_ma = bp->b_pages; | ||||
bio->bio_data = unmapped_buf; | bio->bio_data = unmapped_buf; | ||||
bio->bio_ma_offset = (vm_offset_t)bp->b_offset & PAGE_MASK; | bio->bio_ma_offset = (vm_offset_t)bp->b_offset & PAGE_MASK; | ||||
bio->bio_ma_n = bp->b_npages; | bio->bio_ma_n = bp->b_npages; | ||||
bio->bio_flags |= BIO_UNMAPPED; | bio->bio_flags |= BIO_UNMAPPED; | ||||
} else { | } else { | ||||
bio->bio_data = bp->b_data; | bio->bio_data = bp->b_data; | ||||
▲ Show 20 Lines • Show All 247 Lines • Show Last 20 Lines |
I suspect this is no longer correct.