Module Name:    src
Committed By:   rmind
Date:           Sun Jun  3 16:46:08 UTC 2012

Modified Files:
        src/sys/rump/librump/rumpvfs: vm_vfs.c

Log Message:
rumpvfs:
- ubc_uiomove: avoid the re-lock dance, since the lock is shared these days.
- uvm_aio_aiodone: acquire the lock before modifying the page flags.

Tested by martin@.


To generate a diff of this commit:
cvs rdiff -u -r1.32 -r1.33 src/sys/rump/librump/rumpvfs/vm_vfs.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/rump/librump/rumpvfs/vm_vfs.c
diff -u src/sys/rump/librump/rumpvfs/vm_vfs.c:1.32 src/sys/rump/librump/rumpvfs/vm_vfs.c:1.33
--- src/sys/rump/librump/rumpvfs/vm_vfs.c:1.32	Sun Jun 19 18:28:24 2011
+++ src/sys/rump/librump/rumpvfs/vm_vfs.c	Sun Jun  3 16:46:08 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: vm_vfs.c,v 1.32 2011/06/19 18:28:24 hannken Exp $	*/
+/*	$NetBSD: vm_vfs.c,v 1.33 2012/06/03 16:46:08 rmind Exp $	*/
 
 /*
  * Copyright (c) 2008-2011 Antti Kantee.  All Rights Reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm_vfs.c,v 1.32 2011/06/19 18:28:24 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm_vfs.c,v 1.33 2012/06/03 16:46:08 rmind Exp $");
 
 #include <sys/param.h>
 
@@ -44,7 +44,7 @@ __KERNEL_RCSID(0, "$NetBSD: vm_vfs.c,v 1
 void
 uvm_aio_aiodone(struct buf *bp)
 {
-	struct uvm_object *uobj;
+	struct uvm_object *uobj = NULL;
 	int i, npages = bp->b_bufsize >> PAGE_SHIFT;
 	struct vm_page **pgs;
 	vaddr_t va;
@@ -55,6 +55,15 @@ uvm_aio_aiodone(struct buf *bp)
 	for (i = 0; i < npages; i++) {
 		va = (vaddr_t)bp->b_data + (i << PAGE_SHIFT);
 		pgs[i] = uvm_pageratop(va);
+
+		if (uobj == NULL) {
+			uobj = pgs[i]->uobject;
+			KASSERT(uobj != NULL);
+			mutex_enter(uobj->vmobjlock);
+		} else {
+			KASSERT(uobj == pgs[i]->uobject);
+		}
+
 		if (pgs[i]->flags & PG_PAGEOUT) {
 			KASSERT((pgs[i]->flags & PG_FAKE) == 0);
 			pageout++;
@@ -62,19 +71,14 @@ uvm_aio_aiodone(struct buf *bp)
 			pgs[i]->flags |= PG_RELEASED;
 		}
 	}
+	KASSERT(mutex_owned(uobj->vmobjlock));
 
-	uvm_pagermapout((vaddr_t)bp->b_data, npages);
-
-	/* get uobj because we need it after pages might be recycled */
-	uobj = pgs[0]->uobject;
-	KASSERT(uobj);
-
-	mutex_enter(uobj->vmobjlock);
 	mutex_enter(&uvm_pageqlock);
 	uvm_page_unbusy(pgs, npages);
 	mutex_exit(&uvm_pageqlock);
 	mutex_exit(uobj->vmobjlock);
 
+	uvm_pagermapout((vaddr_t)bp->b_data, npages);
 	uvm_pageout_done(pageout);
 
 	if (BUF_ISWRITE(bp) && (bp->b_cflags & BC_AGE) != 0) {
@@ -105,7 +109,6 @@ void
 ubc_zerorange(struct uvm_object *uobj, off_t off, size_t len, int flags)
 {
 	struct vm_page **pgs;
-	struct uvm_object *pguobj;
 	int maxpages = MIN(32, round_page(len) >> PAGE_SHIFT);
 	int rv, npages, i;
 
@@ -122,7 +125,8 @@ ubc_zerorange(struct uvm_object *uobj, o
 		    0, PAGERFLAGS | PGO_PASTEOF);
 		KASSERT(npages > 0);
 
-		for (i = 0, pguobj = NULL; i < npages; i++) {
+		mutex_enter(uobj->vmobjlock);
+		for (i = 0; i < npages; i++) {
 			struct vm_page *pg;
 			uint8_t *start;
 			size_t chunkoff, chunklen;
@@ -130,9 +134,9 @@ ubc_zerorange(struct uvm_object *uobj, o
 			pg = pgs[i];
 			if (pg == NULL)
 				break;
-			if (pguobj == NULL)
-				pguobj = pg->uobject;
-			KASSERT(pguobj == pg->uobject);
+
+			KASSERT(pg->uobject != NULL);
+			KASSERT(uobj->vmobjlock == pg->uobject->vmobjlock);
 
 			chunkoff = off & PAGE_MASK;
 			chunklen = MIN(PAGE_SIZE - chunkoff, len);
@@ -144,17 +148,10 @@ ubc_zerorange(struct uvm_object *uobj, o
 			off += chunklen;
 			len -= chunklen;
 		}
-		mutex_enter(pguobj->vmobjlock);
 		uvm_page_unbusy(pgs, npages);
-		if (pguobj != uobj) {
-			mutex_exit(pguobj->vmobjlock);
-			mutex_enter(uobj->vmobjlock);
-		}
 	}
 	mutex_exit(uobj->vmobjlock);
 	kmem_free(pgs, maxpages * sizeof(pgs));
-
-	return;
 }
 
 #define len2npages(off, len)						\
@@ -165,7 +162,6 @@ ubc_uiomove(struct uvm_object *uobj, str
 	int advice, int flags)
 {
 	struct vm_page **pgs;
-	struct uvm_object *pguobj;
 	int npages = len2npages(uio->uio_offset, todo);
 	size_t pgalloc;
 	int i, rv, pagerflags;
@@ -193,7 +189,8 @@ ubc_uiomove(struct uvm_object *uobj, str
 		if (rv)
 			goto out;
 
-		for (i = 0, pguobj = NULL; i < npages; i++) {
+		mutex_enter(uobj->vmobjlock);
+		for (i = 0; i < npages; i++) {
 			struct vm_page *pg;
 			size_t xfersize;
 			off_t pageoff;
@@ -201,31 +198,25 @@ ubc_uiomove(struct uvm_object *uobj, str
 			pg = pgs[i];
 			if (pg == NULL)
 				break;
-			if (pguobj == NULL)
-				pguobj = pg->uobject;
-			KASSERT(pguobj == pg->uobject);
 
+			KASSERT(pg->uobject != NULL);
+			KASSERT(uobj->vmobjlock == pg->uobject->vmobjlock);
 			pageoff = uio->uio_offset & PAGE_MASK;
+
 			xfersize = MIN(MIN(todo, PAGE_SIZE), PAGE_SIZE-pageoff);
 			KASSERT(xfersize > 0);
 			rv = uiomove((uint8_t *)pg->uanon + pageoff,
 			    xfersize, uio);
 			if (rv) {
-				mutex_enter(pguobj->vmobjlock);
 				uvm_page_unbusy(pgs, npages);
-				mutex_exit(pguobj->vmobjlock);
+				mutex_exit(uobj->vmobjlock);
 				goto out;
 			}
 			if (uio->uio_rw == UIO_WRITE)
 				pg->flags &= ~(PG_CLEAN | PG_FAKE);
 			todo -= xfersize;
 		}
-		mutex_enter(pguobj->vmobjlock);
 		uvm_page_unbusy(pgs, npages);
-		if (pguobj != uobj) {
-			mutex_exit(pguobj->vmobjlock);
-			mutex_enter(uobj->vmobjlock);
-		}
 	} while (todo);
 	mutex_exit(uobj->vmobjlock);
 

Reply via email to