Index: vm/vm_pageout.c =================================================================== --- vm/vm_pageout.c +++ vm/vm_pageout.c @@ -355,41 +355,28 @@ } /* - * vm_pageout_clean: - * - * Clean the page and remove it from the laundry. - * - * We set the busy bit to cause potential page faults on this page to - * block. Note the careful timing, however, the busy bit isn't set till - * late and we cannot do anything that will mess with the page. + * 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, + * and launder that cluster. */ static int vm_pageout_cluster(vm_page_t m) { vm_object_t object; - vm_page_t mc[2*vm_pageout_page_count], pb, ps; - int pageout_count; - int ib, is, page_base; - vm_pindex_t pindex = m->pindex; + vm_page_t mc[2 * vm_pageout_page_count], p, pb, ps; + vm_pindex_t pindex; + int ib, is, page_base, pageout_count; - vm_page_lock_assert(m, MA_OWNED); + vm_page_assert_locked(m); object = m->object; VM_OBJECT_ASSERT_WLOCKED(object); + pindex = m->pindex; /* - * It doesn't cost us anything to pageout OBJT_DEFAULT or OBJT_SWAP - * with the new swapper, but we could have serious problems paging - * out other object types if there is insufficient memory. - * - * Unfortunately, checking free memory here is far too late, so the - * check has been moved up a procedural level. + * We can't clean the page if it's busy or held. */ - - /* - * Can't clean the page if it's busy or held. - */ vm_page_assert_unbusied(m); - KASSERT(m->hold_count == 0, ("vm_pageout_clean: page %p is held", m)); + KASSERT(m->hold_count == 0, ("page %p is held", m)); vm_page_unlock(m); mc[vm_pageout_page_count] = pb = ps = m; @@ -399,33 +386,23 @@ is = 1; /* - * Scan object for clusterable pages. - * * We can cluster ONLY if: ->> the page is NOT - * clean, wired, busy, held, or mapped into a - * buffer, and one of the following: - * 1) The page is inactive, or a seldom used - * active page. - * -or- - * 2) we force the issue. + * clean, busy, or held, and the page is inactive. * * During heavy mmap/modification loads the pageout * daemon can really fragment the underlying file - * due to flushing pages out of order and not trying - * align the clusters (which leave sporatic out-of-order + * due to flushing pages out of order and not trying to + * align the clusters (which leaves sporatic out-of-order * holes). To solve this problem we do the reverse scan * first and attempt to align our cluster, then do a * forward scan if room remains. */ more: - while (ib && pageout_count < vm_pageout_page_count) { - vm_page_t p; - + while (ib != 0 && pageout_count < vm_pageout_page_count) { if (ib > pindex) { ib = 0; break; } - if ((p = vm_page_prev(pb)) == NULL || vm_page_busied(p)) { ib = 0; break; @@ -446,18 +423,16 @@ mc[--page_base] = pb = p; ++pageout_count; ++ib; + /* - * alignment boundary, stop here and switch directions. Do - * not clear ib. + * We are at an alignment boundary. Stop here, and switch + * directions. Do not clear ib. */ if ((pindex - (ib - 1)) % vm_pageout_page_count == 0) break; } - while (pageout_count < vm_pageout_page_count && pindex + is < object->size) { - vm_page_t p; - if ((p = vm_page_next(ps)) == NULL || vm_page_busied(p)) break; vm_page_test_dirty(p); @@ -477,15 +452,12 @@ /* * If we exhausted our forward scan, continue with the reverse scan - * when possible, even past a page boundary. This catches boundary - * conditions. + * when possible, even past an alignment boundary. This catches + * boundary conditions. */ - if (ib && pageout_count < vm_pageout_page_count) + if (ib != 0 && pageout_count < vm_pageout_page_count) goto more; - /* - * we allow reads during pageouts... - */ return (vm_pageout_flush(&mc[page_base], pageout_count, 0, 0, NULL, NULL)); }