From owner-svn-src-all@FreeBSD.ORG Fri Oct 15 05:42:36 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 330A8106564A; Fri, 15 Oct 2010 05:42:36 +0000 (UTC) (envelope-from alc@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 2075C8FC19; Fri, 15 Oct 2010 05:42:36 +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 o9F5gaNH050687; Fri, 15 Oct 2010 05:42:36 GMT (envelope-from alc@svn.freebsd.org) Received: (from alc@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o9F5gZe1050685; Fri, 15 Oct 2010 05:42:35 GMT (envelope-from alc@svn.freebsd.org) Message-Id: <201010150542.o9F5gZe1050685@svn.freebsd.org> From: Alan Cox Date: Fri, 15 Oct 2010 05:42:35 +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: r213890 - stable/8/sys/kern 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, 15 Oct 2010 05:42:36 -0000 Author: alc Date: Fri Oct 15 05:42:35 2010 New Revision: 213890 URL: http://svn.freebsd.org/changeset/base/213890 Log: MFC r209605 Improve bufdone_finish()'s handling of the bogus page. Specifically, if one or more mappings to the bogus page must be replaced, call pmap_qenter() just once. Previously, pmap_qenter() was called for each mapping to the bogus page. MFC r209902 Change the implementation of vm_hold_free_pages() so that it performs at most one call to pmap_qremove(), and thus one TLB shootdown, instead of one call and TLB shootdown per page. Simplify the interface to vm_hold_free_pages(). Modified: stable/8/sys/kern/vfs_bio.c 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) stable/8/sys/dev/xen/xenpci/ (props changed) Modified: stable/8/sys/kern/vfs_bio.c ============================================================================== --- stable/8/sys/kern/vfs_bio.c Fri Oct 15 05:17:48 2010 (r213889) +++ stable/8/sys/kern/vfs_bio.c Fri Oct 15 05:42:35 2010 (r213890) @@ -95,8 +95,7 @@ struct buf *buf; /* buffer header pool static struct proc *bufdaemonproc; static int inmem(struct vnode *vp, daddr_t blkno); -static void vm_hold_free_pages(struct buf *bp, vm_offset_t from, - vm_offset_t to); +static void vm_hold_free_pages(struct buf *bp, int newbsize); static void vm_hold_load_pages(struct buf *bp, vm_offset_t from, vm_offset_t to); static void vfs_page_set_valid(struct buf *bp, vm_ooffset_t off, vm_page_t m); @@ -2919,10 +2918,7 @@ allocbuf(struct buf *bp, int size) } return 1; } - vm_hold_free_pages( - bp, - (vm_offset_t) bp->b_data + newbsize, - (vm_offset_t) bp->b_data + bp->b_bufsize); + vm_hold_free_pages(bp, newbsize); } else if (newbsize > bp->b_bufsize) { /* * We only use malloced memory on the first allocation. @@ -3358,7 +3354,7 @@ bufdone_finish(struct buf *bp) vm_ooffset_t foff; vm_page_t m; vm_object_t obj; - int iosize; + int bogus, iosize; struct vnode *vp = bp->b_vp; obj = bp->b_bufobj->bo_object; @@ -3396,6 +3392,7 @@ bufdone_finish(struct buf *bp) !(bp->b_ioflags & BIO_ERROR)) { bp->b_flags |= B_CACHE; } + bogus = 0; for (i = 0; i < bp->b_npages; i++) { int bogusflag = 0; int resid; @@ -3409,13 +3406,11 @@ bufdone_finish(struct buf *bp) */ m = bp->b_pages[i]; if (m == bogus_page) { - bogusflag = 1; + bogus = bogusflag = 1; m = vm_page_lookup(obj, OFF_TO_IDX(foff)); if (m == NULL) panic("biodone: page disappeared!"); bp->b_pages[i] = m; - pmap_qenter(trunc_page((vm_offset_t)bp->b_data), - bp->b_pages, bp->b_npages); } #if defined(VFS_BIO_DEBUG) if (OFF_TO_IDX(foff) != m->pindex) { @@ -3469,6 +3464,9 @@ bufdone_finish(struct buf *bp) } vm_object_pip_wakeupn(obj, 0); VM_OBJECT_UNLOCK(obj); + if (bogus) + pmap_qenter(trunc_page((vm_offset_t)bp->b_data), + bp->b_pages, bp->b_npages); } /* @@ -3831,31 +3829,25 @@ tryagain: /* Return pages associated with this buf to the vm system */ static void -vm_hold_free_pages(struct buf *bp, vm_offset_t from, vm_offset_t to) +vm_hold_free_pages(struct buf *bp, int newbsize) { - vm_offset_t pg; + vm_offset_t from; vm_page_t p; int index, newnpages; - from = round_page(from); - to = round_page(to); - newnpages = index = (from - trunc_page((vm_offset_t)bp->b_data)) >> PAGE_SHIFT; - - for (pg = from; pg < to; pg += PAGE_SIZE, index++) { + from = round_page((vm_offset_t)bp->b_data + newbsize); + newnpages = (from - trunc_page((vm_offset_t)bp->b_data)) >> PAGE_SHIFT; + if (bp->b_npages > newnpages) + pmap_qremove(from, bp->b_npages - newnpages); + for (index = newnpages; index < bp->b_npages; index++) { p = bp->b_pages[index]; - if (p && (index < bp->b_npages)) { - if (p->busy) { - printf( - "vm_hold_free_pages: blkno: %jd, lblkno: %jd\n", - (intmax_t)bp->b_blkno, - (intmax_t)bp->b_lblkno); - } - bp->b_pages[index] = NULL; - pmap_qremove(pg, 1); - p->wire_count--; - vm_page_free(p); - atomic_subtract_int(&cnt.v_wire_count, 1); - } + bp->b_pages[index] = NULL; + if (p->busy != 0) + printf("vm_hold_free_pages: blkno: %jd, lblkno: %jd\n", + (intmax_t)bp->b_blkno, (intmax_t)bp->b_lblkno); + p->wire_count--; + vm_page_free(p); + atomic_subtract_int(&cnt.v_wire_count, 1); } bp->b_npages = newnpages; }