Index: sys/vm/vm_pageout.c =================================================================== --- sys/vm/vm_pageout.c +++ sys/vm/vm_pageout.c @@ -339,6 +339,25 @@ return (false); } +/* + * We can cluster only if the page is not clean, busy, or held, and the page is + * in the laundry queue. + */ +static bool +vm_pageout_flushable(vm_page_t m) +{ + if (vm_page_tryxbusy(m) == 0) + return (false); + if (!vm_page_wired(m)) { + vm_page_test_dirty(m); + if (m->dirty != 0 && vm_page_in_laundry(m) && + vm_page_try_remove_write(m)) + return (true); + } + vm_page_xunbusy(m); + return (false); +} + /* * Scan for pages at adjacent offsets within the given page's object that are * eligible for laundering, form a cluster of these pages and the given page, @@ -348,7 +367,7 @@ vm_pageout_cluster(vm_page_t m) { vm_object_t object; - vm_page_t mc[2 * vm_pageout_page_count - 1], p, pb, ps; + vm_page_t mc[2 * vm_pageout_page_count - 1]; vm_pindex_t pindex; int ib, is, page_base, pageout_count; @@ -360,14 +379,11 @@ pageout_count = 1; page_base = nitems(mc) / 2; - mc[page_base] = pb = ps = m; + mc[page_base] = m; ib = 1; is = 1; /* - * We can cluster only if the page is not clean, busy, or held, and - * the page is in the laundry queue. - * * During heavy mmap/modification loads the pageout * daemon can really fragment the underlying file * due to flushing pages out of order and not trying to @@ -377,33 +393,19 @@ * forward scan if room remains. */ more: + m = mc[page_base]; while (ib != 0 && pageout_count < vm_pageout_page_count) { if (ib > pindex) { + /* Don't walk backward from pindex 0. */ ib = 0; break; } - if ((p = vm_page_prev(pb)) == NULL || - vm_page_tryxbusy(p) == 0) { - ib = 0; - break; - } - if (vm_page_wired(p)) { + m = vm_page_prev(m); + if (m == NULL || !vm_pageout_flushable(m)) { ib = 0; - vm_page_xunbusy(p); break; } - vm_page_test_dirty(p); - if (p->dirty == 0) { - ib = 0; - vm_page_xunbusy(p); - break; - } - if (!vm_page_in_laundry(p) || !vm_page_try_remove_write(p)) { - vm_page_xunbusy(p); - ib = 0; - break; - } - mc[--page_base] = pb = p; + mc[--page_base] = m; ++pageout_count; ++ib; @@ -414,25 +416,13 @@ if ((pindex - (ib - 1)) % vm_pageout_page_count == 0) break; } + m = mc[page_base + pageout_count - 1]; while (pageout_count < vm_pageout_page_count && pindex + is < object->size) { - if ((p = vm_page_next(ps)) == NULL || - vm_page_tryxbusy(p) == 0) + m = vm_page_next(m); + if (m == NULL || !vm_pageout_flushable(m)) break; - if (vm_page_wired(p)) { - vm_page_xunbusy(p); - break; - } - vm_page_test_dirty(p); - if (p->dirty == 0) { - vm_page_xunbusy(p); - break; - } - if (!vm_page_in_laundry(p) || !vm_page_try_remove_write(p)) { - vm_page_xunbusy(p); - break; - } - mc[page_base + pageout_count] = ps = p; + mc[page_base + pageout_count] = m; ++pageout_count; ++is; }