From owner-svn-src-all@FreeBSD.ORG Fri Nov 26 15:30:03 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 004E11065697; Fri, 26 Nov 2010 15:30:02 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id D8C058FC15; Fri, 26 Nov 2010 15:30:02 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id oAQFU2aP050837; Fri, 26 Nov 2010 15:30:02 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id oAQFU2J3050833; Fri, 26 Nov 2010 15:30:02 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201011261530.oAQFU2J3050833@svn.freebsd.org> From: Konstantin Belousov Date: Fri, 26 Nov 2010 15:30:02 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r215866 - stable/8/sys/vm X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 26 Nov 2010 15:30:03 -0000 Author: kib Date: Fri Nov 26 15:30:02 2010 New Revision: 215866 URL: http://svn.freebsd.org/changeset/base/215866 Log: MFC r215471: In vm_object_page_clean(), handle the pages that might be cached or not written by vm_pageout_flush(). MFC r215574: The runlen returned from vm_pageout_flush() might be zero legitimately MCF r215610: Eliminate the mab, maf arrays and related variables. The change also fixes off-by-one error in the calculation of mreq. MFC r215796: After the sleep caused by encountering a busy page, relookup the page. Modified: stable/8/sys/vm/vm_contig.c stable/8/sys/vm/vm_object.c stable/8/sys/vm/vm_pageout.c stable/8/sys/vm/vm_pageout.h Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) Modified: stable/8/sys/vm/vm_contig.c ============================================================================== --- stable/8/sys/vm/vm_contig.c Fri Nov 26 14:50:42 2010 (r215865) +++ stable/8/sys/vm/vm_contig.c Fri Nov 26 15:30:02 2010 (r215866) @@ -138,7 +138,7 @@ vm_contig_launder_page(vm_page_t m, vm_p } else if (object->type == OBJT_SWAP || object->type == OBJT_DEFAULT) { m_tmp = m; - vm_pageout_flush(&m_tmp, 1, VM_PAGER_PUT_SYNC); + vm_pageout_flush(&m_tmp, 1, VM_PAGER_PUT_SYNC, 0, NULL); VM_OBJECT_UNLOCK(object); return (0); } Modified: stable/8/sys/vm/vm_object.c ============================================================================== --- stable/8/sys/vm/vm_object.c Fri Nov 26 14:50:42 2010 (r215865) +++ stable/8/sys/vm/vm_object.c Fri Nov 26 15:30:02 2010 (r215866) @@ -809,10 +809,12 @@ rescan: np = TAILQ_NEXT(p, listq); if (p->valid == 0) continue; - while (vm_page_sleep_if_busy(p, TRUE, "vpcwai")) { + if (vm_page_sleep_if_busy(p, TRUE, "vpcwai")) { vm_page_lock_queues(); if (object->generation != curgeneration) goto rescan; + np = vm_page_find_least(object, pi); + continue; } vm_page_test_dirty(p); if (p->dirty == 0) @@ -828,7 +830,6 @@ rescan: continue; n = vm_object_page_collect_flush(object, p, pagerflags); - KASSERT(n > 0, ("vm_object_page_collect_flush failed")); if (object->generation != curgeneration) goto rescan; np = vm_page_find_least(object, pi + n); @@ -844,77 +845,39 @@ rescan: static int vm_object_page_collect_flush(vm_object_t object, vm_page_t p, int pagerflags) { - int runlen; - int maxf; - int chkb; - int maxb; - int i, index; - vm_pindex_t pi; - vm_page_t maf[vm_pageout_page_count]; - vm_page_t mab[vm_pageout_page_count]; - vm_page_t ma[vm_pageout_page_count]; - vm_page_t tp, p1; + vm_page_t ma[vm_pageout_page_count], p_first, tp; + int count, i, mreq, runlen; mtx_assert(&vm_page_queue_mtx, MA_OWNED); - pi = p->pindex; - maxf = 0; - for (i = 1, p1 = p; i < vm_pageout_page_count; i++) { - tp = vm_page_next(p1); + + count = 1; + mreq = 0; + + for (tp = p; count < vm_pageout_page_count; count++) { + tp = vm_page_next(tp); if (tp == NULL || tp->busy != 0 || (tp->oflags & VPO_BUSY) != 0) break; vm_page_test_dirty(tp); if (tp->dirty == 0) break; - maf[i - 1] = p1 = tp; - maxf++; } - maxb = 0; - chkb = vm_pageout_page_count - maxf; - for (i = 1, p1 = p; i < chkb; i++) { - tp = vm_page_prev(p1); + for (p_first = p; count < vm_pageout_page_count; count++) { + tp = vm_page_prev(p_first); if (tp == NULL || tp->busy != 0 || (tp->oflags & VPO_BUSY) != 0) break; vm_page_test_dirty(tp); if (tp->dirty == 0) break; - mab[i - 1] = p1 = tp; - maxb++; + p_first = tp; + mreq++; } - for (i = 0; i < maxb; i++) { - index = (maxb - i) - 1; - ma[index] = mab[i]; - } - ma[maxb] = p; - for (i = 0; i < maxf; i++) { - index = (maxb + i) + 1; - ma[index] = maf[i]; - } - runlen = maxb + maxf + 1; + for (tp = p_first, i = 0; i < count; tp = TAILQ_NEXT(tp, listq), i++) + ma[i] = tp; - vm_pageout_flush(ma, runlen, pagerflags); - for (i = 0; i < runlen; i++) { - if (ma[i]->dirty != 0) { - KASSERT((ma[i]->flags & PG_WRITEABLE) == 0, - ("vm_object_page_collect_flush: page %p is not write protected", - ma[i])); - } - } - for (i = 0; i < maxf; i++) { - if (ma[i + maxb + 1]->dirty != 0) { - /* - * maxf will end up being the actual number of pages - * we wrote out contiguously, non-inclusive of the - * first page. We do not count look-behind pages. - */ - if (maxf > i) { - maxf = i; - break; - } - } - } - return (maxf + 1); + vm_pageout_flush(ma, count, pagerflags, mreq, &runlen); + return (runlen); } /* Modified: stable/8/sys/vm/vm_pageout.c ============================================================================== --- stable/8/sys/vm/vm_pageout.c Fri Nov 26 14:50:42 2010 (r215865) +++ stable/8/sys/vm/vm_pageout.c Fri Nov 26 15:30:02 2010 (r215866) @@ -391,7 +391,7 @@ more: /* * we allow reads during pageouts... */ - return (vm_pageout_flush(&mc[page_base], pageout_count, 0)); + return (vm_pageout_flush(&mc[page_base], pageout_count, 0, 0, NULL)); } /* @@ -402,14 +402,17 @@ more: * reference count all in here rather then in the parent. If we want * the parent to do more sophisticated things we may have to change * the ordering. + * + * Returned runlen is the count of pages between mreq and first + * page after mreq with status VM_PAGER_AGAIN. */ int -vm_pageout_flush(vm_page_t *mc, int count, int flags) +vm_pageout_flush(vm_page_t *mc, int count, int flags, int mreq, int *prunlen) { vm_object_t object = mc[0]->object; int pageout_status[count]; int numpagedout = 0; - int i; + int i, runlen; mtx_assert(&vm_page_queue_mtx, MA_OWNED); VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); @@ -435,6 +438,7 @@ vm_pageout_flush(vm_page_t *mc, int coun vm_pager_put_pages(object, mc, count, flags, pageout_status); + runlen = count - mreq; vm_page_lock_queues(); for (i = 0; i < count; i++) { vm_page_t mt = mc[i]; @@ -465,6 +469,8 @@ vm_pageout_flush(vm_page_t *mc, int coun vm_page_activate(mt); break; case VM_PAGER_AGAIN: + if (i >= mreq && i - mreq < runlen) + runlen = i - mreq; break; } @@ -481,7 +487,9 @@ vm_pageout_flush(vm_page_t *mc, int coun vm_page_try_to_cache(mt); } } - return numpagedout; + if (prunlen != NULL) + *prunlen = runlen; + return (numpagedout); } #if !defined(NO_SWAPPING) Modified: stable/8/sys/vm/vm_pageout.h ============================================================================== --- stable/8/sys/vm/vm_pageout.h Fri Nov 26 14:50:42 2010 (r215865) +++ stable/8/sys/vm/vm_pageout.h Fri Nov 26 15:30:02 2010 (r215866) @@ -102,7 +102,7 @@ extern void vm_waitpfault(void); #ifdef _KERNEL boolean_t vm_pageout_fallback_object_lock(vm_page_t, vm_page_t *); -int vm_pageout_flush(vm_page_t *, int, int); +int vm_pageout_flush(vm_page_t *, int, int, int, int *); void vm_pageout_oom(int shortage); #endif #endif /* _VM_VM_PAGEOUT_H_ */