svn commit: r191935 - head/sys/vm

Alan Cox alc at FreeBSD.org
Sat May 9 08:30:44 UTC 2009


Author: alc
Date: Sat May  9 08:30:44 2009
New Revision: 191935
URL: http://svn.freebsd.org/changeset/base/191935

Log:
  Fix a race involving vnode_pager_input_smlfs().  Specifically, in the case
  that vnode_pager_input_smlfs() zeroes the page, it should not mark the page
  as valid until after the page is zeroed.  Otherwise, the page could be
  mapped for read access (e.g., by vm_map_pmap_enter()) before the page is
  zeroed.  Reviewed by: tegge
  
  Eliminate gratuitous clearing of the page's dirty mask by
  vnode_pager_input_smlfs().  Instead, assert that the page is clean.
  Reviewed by: tegge
  
  Eliminate some blank lines.
  
  Eliminate pointless calls to pmap_clear_modify() and vm_page_undirty() from
  vnode_pager_input_old().  The page is not mapped.  Therefore, it cannot have
  any page table entries that are modified.
  
  Eliminate an incorrect comment from vnode_pager_generic_getpages().

Modified:
  head/sys/vm/vnode_pager.c

Modified: head/sys/vm/vnode_pager.c
==============================================================================
--- head/sys/vm/vnode_pager.c	Sat May  9 05:45:13 2009	(r191934)
+++ head/sys/vm/vnode_pager.c	Sat May  9 08:30:44 2009	(r191935)
@@ -476,7 +476,7 @@ vnode_pager_input_smlfs(object, m)
 	vm_object_t object;
 	vm_page_t m;
 {
-	int i;
+	int bits, i;
 	struct vnode *vp;
 	struct bufobj *bo;
 	struct buf *bp;
@@ -498,7 +498,8 @@ vnode_pager_input_smlfs(object, m)
 	for (i = 0; i < PAGE_SIZE / bsize; i++) {
 		vm_ooffset_t address;
 
-		if (vm_page_bits(i * bsize, bsize) & m->valid)
+		bits = vm_page_bits(i * bsize, bsize);
+		if (m->valid & bits)
 			continue;
 
 		address = IDX_TO_OFF(m->pindex) + i * bsize;
@@ -543,30 +544,21 @@ vnode_pager_input_smlfs(object, m)
 			relpbuf(bp, &vnode_pbuf_freecnt);
 			if (error)
 				break;
-
-			VM_OBJECT_LOCK(object);
-			vm_page_lock_queues();
-			vm_page_set_validclean(m, (i * bsize) & PAGE_MASK, bsize);
-			vm_page_unlock_queues();
-			VM_OBJECT_UNLOCK(object);
-		} else {
-			VM_OBJECT_LOCK(object);
-			vm_page_lock_queues();
-			vm_page_set_validclean(m, (i * bsize) & PAGE_MASK, bsize);
-			vm_page_unlock_queues();
-			VM_OBJECT_UNLOCK(object);
+		} else
 			bzero((caddr_t)sf_buf_kva(sf) + i * bsize, bsize);
-		}
+		KASSERT((m->dirty & bits) == 0,
+		    ("vnode_pager_input_smlfs: page %p is dirty", m));
+		VM_OBJECT_LOCK(object);
+		m->valid |= bits;
+		VM_OBJECT_UNLOCK(object);
 	}
 	sf_buf_free(sf);
 	if (error) {
 		return VM_PAGER_ERROR;
 	}
 	return VM_PAGER_OK;
-
 }
 
-
 /*
  * old style vnode pager input routine
  */
@@ -627,10 +619,7 @@ vnode_pager_input_old(object, m)
 
 		VM_OBJECT_LOCK(object);
 	}
-	vm_page_lock_queues();
-	pmap_clear_modify(m);
-	vm_page_undirty(m);
-	vm_page_unlock_queues();
+	KASSERT(m->dirty == 0, ("vnode_pager_input_old: page %p is dirty", m));
 	if (!error)
 		m->valid = VM_PAGE_BITS_ALL;
 	return error ? VM_PAGER_ERROR : VM_PAGER_OK;
@@ -960,8 +949,6 @@ vnode_pager_generic_getpages(vp, m, byte
 			 */
 			vm_page_set_validclean(mt, 0,
 			    object->un_pager.vnp.vnp_size - tfoff);
-			/* handled by vm_fault now */
-			/* vm_page_zero_invalid(mt, FALSE); */
 		}
 		
 		if (i != reqpage) {


More information about the svn-src-head mailing list