Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 11 Jul 2010 20:11:45 +0000 (UTC)
From:      Alan Cox <alc@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r209902 - head/sys/kern
Message-ID:  <201007112011.o6BKBjdr078418@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: alc
Date: Sun Jul 11 20:11:44 2010
New Revision: 209902
URL: http://svn.freebsd.org/changeset/base/209902

Log:
  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().
  
  MFC after:	3 weeks

Modified:
  head/sys/kern/vfs_bio.c

Modified: head/sys/kern/vfs_bio.c
==============================================================================
--- head/sys/kern/vfs_bio.c	Sun Jul 11 17:08:37 2010	(r209901)
+++ head/sys/kern/vfs_bio.c	Sun Jul 11 20:11:44 2010	(r209902)
@@ -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);
@@ -2888,10 +2887,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.
@@ -3766,31 +3762,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;
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201007112011.o6BKBjdr078418>