Module Name:    src
Committed By:   martin
Date:           Tue Jul  6 04:22:35 UTC 2021

Modified Files:
        src/external/cddl/osnet/dist/uts/common/fs/zfs [netbsd-9]: zfs_vnops.c
        src/sys/rump/librump/rumpkern [netbsd-9]: vm.c
        src/sys/rump/librump/rumpvfs [netbsd-9]: vm_vfs.c
        src/sys/uvm [netbsd-9]: uvm_anon.c uvm_page.c uvm_pager.c
        src/tests/rump/rumpkern [netbsd-9]: t_vm.c

Log Message:
Pull up following revision(s) - all via patch -
(requested by riastradh in ticket #1317):

        sys/uvm/uvm_page.c: revision 1.248
        sys/uvm/uvm_anon.c: revision 1.80
        sys/rump/librump/rumpvfs/vm_vfs.c: revision 1.40
        sys/rump/librump/rumpvfs/vm_vfs.c: revision 1.41
        sys/rump/librump/rumpkern/vm.c: revision 1.191
        sys/uvm/uvm_pager.c: revision 1.130
        external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c: revision 1.71
        tests/rump/rumpkern/t_vm.c: revision 1.5
        tests/rump/rumpkern/t_vm.c: revision 1.6
        sys/rump/librump/rumpvfs/vm_vfs.c: revision 1.39

Move the handling of PG_PAGEOUT from uvm_aio_aiodone_pages() to
uvm_page_unbusy() so that all callers of uvm_page_unbusy() don't need to
handle this flag separately.  Split out the pages part of uvm_aio_aiodone()
into uvm_aio_aiodone_pages() in rump just like in the real kernel.

In ZFS functions that can fail to copy data between the ARC and VM pages,
use uvm_aio_aiodone_pages() rather than uvm_page_unbusy() so that we can
handle these "I/O" errors.  Fixes PR 55702.

fix an incorrect assertion in the previous commit.

Handle PG_PAGEOUT in uvm_anon_release() too.

Commit the ZFS file that I forgot in this previous commit:

Move the handling of PG_PAGEOUT from uvm_aio_aiodone_pages() to
uvm_page_unbusy() so that all callers of uvm_page_unbusy() don't need to
handle this flag separately.  Split out the pages part of uvm_aio_aiodone()
into uvm_aio_aiodone_pages() in rump just like in the real kernel.

In ZFS functions that can fail to copy data between the ARC and VM pages,
use uvm_aio_aiodone_pages() rather than uvm_page_unbusy() so that we can
handle these "I/O" errors.  Fixes PR 55702.
update the rump copy of uvm_page_unbusy() to match the real version,
in particular handle PG_PAGEOUT.  fixes a few atf tests.
the busypage test is buggy, expect it to fail.

make rump's uvm_aio_aiodone_pages() look more like the kernel version.
fixes some more rumpy assertions.

for the busypage test, replace atf_tc_expect_fail() with atf_tc_skip()
because atf apparently has no way to expect a test program to crash.
fixes PR 55945.


To generate a diff of this commit:
cvs rdiff -u -r1.50.2.9 -r1.50.2.10 \
    src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c
cvs rdiff -u -r1.173 -r1.173.14.1 src/sys/rump/librump/rumpkern/vm.c
cvs rdiff -u -r1.34 -r1.34.34.1 src/sys/rump/librump/rumpvfs/vm_vfs.c
cvs rdiff -u -r1.64 -r1.64.8.1 src/sys/uvm/uvm_anon.c
cvs rdiff -u -r1.199 -r1.199.4.1 src/sys/uvm/uvm_page.c
cvs rdiff -u -r1.111.8.1 -r1.111.8.2 src/sys/uvm/uvm_pager.c
cvs rdiff -u -r1.4 -r1.4.16.1 src/tests/rump/rumpkern/t_vm.c

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

Modified files:

Index: src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c
diff -u src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c:1.50.2.9 src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c:1.50.2.10
--- src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c:1.50.2.9	Wed May 13 12:41:43 2020
+++ src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c	Tue Jul  6 04:22:34 2021
@@ -6007,6 +6007,12 @@ zfs_netbsd_getpages(void *v)
 		    va, DMU_READ_PREFETCH);
 		zfs_unmap_page(pg, va);
 
+		if (err != 0) {
+			uvm_aio_aiodone_pages(ap->a_m, npages, false, err);
+			memset(ap->a_m, 0, sizeof(ap->a_m[0]) *
+			       npages);
+			goto out;
+		}
 		mutex_enter(mtx);
 		pg->flags &= ~(PG_FAKE);
 		pmap_clear_modify(pg);
@@ -6023,6 +6029,7 @@ zfs_netbsd_getpages(void *v)
 	mutex_exit(mtx);
 	ap->a_m[ap->a_centeridx] = pg;
 
+out:
 	ZFS_EXIT(zfsvfs);
 	fstrans_done(mp);
 
@@ -6039,14 +6046,13 @@ zfs_putapage(vnode_t *vp, page_t **pp, i
 	voff_t		len, klen;
 	int		err;
 
-	bool async = (flags & PGO_SYNCIO) == 0;
 	bool *cleanedp;
 	struct uvm_object *uobj = &vp->v_uobj;
 	kmutex_t *mtx = uobj->vmobjlock;
 
 	if (zp->z_sa_hdl == NULL) {
 		err = 0;
-		goto out_unbusy;
+		goto out;
 	}
 
 	/*
@@ -6120,14 +6126,8 @@ zfs_putapage(vnode_t *vp, page_t **pp, i
 	}
 	dmu_tx_commit(tx);
 
-out_unbusy:
-	mutex_enter(mtx);
-	mutex_enter(&uvm_pageqlock);
-	uvm_page_unbusy(pp, count);
-	mutex_exit(&uvm_pageqlock);
-	mutex_exit(mtx);
-
 out:
+	uvm_aio_aiodone_pages(pp, count, true, err);
 	return (err);
 }
 

Index: src/sys/rump/librump/rumpkern/vm.c
diff -u src/sys/rump/librump/rumpkern/vm.c:1.173 src/sys/rump/librump/rumpkern/vm.c:1.173.14.1
--- src/sys/rump/librump/rumpkern/vm.c:1.173	Sun May 14 13:49:55 2017
+++ src/sys/rump/librump/rumpkern/vm.c	Tue Jul  6 04:22:34 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: vm.c,v 1.173 2017/05/14 13:49:55 nat Exp $	*/
+/*	$NetBSD: vm.c,v 1.173.14.1 2021/07/06 04:22:34 martin Exp $	*/
 
 /*
  * Copyright (c) 2007-2011 Antti Kantee.  All Rights Reserved.
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm.c,v 1.173 2017/05/14 13:49:55 nat Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm.c,v 1.173.14.1 2021/07/06 04:22:34 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -632,23 +632,50 @@ void
 uvm_page_unbusy(struct vm_page **pgs, int npgs)
 {
 	struct vm_page *pg;
-	int i;
+	int i, pageout_done;
 
 	KASSERT(npgs > 0);
-	KASSERT(mutex_owned(pgs[0]->uobject->vmobjlock));
 
+	pageout_done = 0;
 	for (i = 0; i < npgs; i++) {
 		pg = pgs[i];
-		if (pg == NULL)
+		if (pg == NULL || pg == PGO_DONTCARE) {
 			continue;
+		}
 
+#if 0
+		KASSERT(uvm_page_owner_locked_p(pg, true));
+#else
+		/*
+		 * uvm_page_owner_locked_p() is not available in rump,
+		 * and rump doesn't support amaps anyway.
+		 */
+		KASSERT(mutex_owned(pg->uobject->vmobjlock));
+#endif
 		KASSERT(pg->flags & PG_BUSY);
-		if (pg->flags & PG_WANTED)
+
+		if (pg->flags & PG_PAGEOUT) {
+			pg->flags &= ~PG_PAGEOUT;
+			pg->flags |= PG_RELEASED;
+			pageout_done++;
+			atomic_inc_uint(&uvmexp.pdfreed);
+		}
+		if (pg->flags & PG_WANTED) {
 			wakeup(pg);
-		if (pg->flags & PG_RELEASED)
+		}
+		if (pg->flags & PG_RELEASED) {
+			KASSERT(pg->uobject != NULL ||
+			    (pg->uanon != NULL && pg->uanon->an_ref > 0));
+			pg->flags &= ~PG_RELEASED;
 			uvm_pagefree(pg);
-		else
+		} else {
+			KASSERT((pg->flags & PG_FAKE) == 0);
 			pg->flags &= ~(PG_WANTED|PG_BUSY);
+			UVM_PAGE_OWN(pg, NULL);
+		}
+	}
+	if (pageout_done != 0) {
+		uvm_pageout_done(pageout_done);
 	}
 }
 

Index: src/sys/rump/librump/rumpvfs/vm_vfs.c
diff -u src/sys/rump/librump/rumpvfs/vm_vfs.c:1.34 src/sys/rump/librump/rumpvfs/vm_vfs.c:1.34.34.1
--- src/sys/rump/librump/rumpvfs/vm_vfs.c:1.34	Fri Oct 18 19:56:11 2013
+++ src/sys/rump/librump/rumpvfs/vm_vfs.c	Tue Jul  6 04:22:34 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: vm_vfs.c,v 1.34 2013/10/18 19:56:11 christos Exp $	*/
+/*	$NetBSD: vm_vfs.c,v 1.34.34.1 2021/07/06 04:22:34 martin 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.34 2013/10/18 19:56:11 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm_vfs.c,v 1.34.34.1 2021/07/06 04:22:34 martin Exp $");
 
 #include <sys/param.h>
 
@@ -36,19 +36,47 @@ __KERNEL_RCSID(0, "$NetBSD: vm_vfs.c,v 1
 #include <uvm/uvm.h>
 #include <uvm/uvm_readahead.h>
 
+void
+uvm_aio_aiodone_pages(struct vm_page **pgs, int npages, bool write, int error)
+{
+	struct uvm_object *uobj = pgs[0]->uobject;
+	struct vm_page *pg;
+	int i;
+
+	mutex_enter(uobj->vmobjlock);
+	for (i = 0; i < npages; i++) {
+		pg = pgs[i];
+		KASSERT((pg->flags & PG_PAGEOUT) == 0 ||
+			(pg->flags & PG_FAKE) == 0);
+
+		if (pg->flags & PG_FAKE) {
+			KASSERT(!write);
+			pg->flags &= ~PG_FAKE;
+			KASSERT((pg->flags & PG_CLEAN) != 0);
+			uvm_pageenqueue(pg);
+			pmap_clear_modify(pg);
+		}
+
+	}
+	uvm_page_unbusy(pgs, npages);
+	mutex_exit(uobj->vmobjlock);
+}
+
 /*
- * release resources held during async io.  this is almost the
- * same as uvm_aio_aiodone() from uvm_pager.c and only lacks the
- * call to uvm_aio_aiodone_pages(): unbusies pages directly here.
+ * Release resources held during async io.
  */
 void
 uvm_aio_aiodone(struct buf *bp)
 {
 	struct uvm_object *uobj = NULL;
-	int i, npages = bp->b_bufsize >> PAGE_SHIFT;
+	int npages = bp->b_bufsize >> PAGE_SHIFT;
 	struct vm_page **pgs;
 	vaddr_t va;
-	int pageout = 0;
+	int i, error;
+	bool write;
+
+	error = bp->b_error;
+	write = BUF_ISWRITE(bp);
 
 	KASSERT(npages > 0);
 	pgs = kmem_alloc(npages * sizeof(*pgs), KM_SLEEP);
@@ -59,29 +87,15 @@ uvm_aio_aiodone(struct buf *bp)
 		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++;
-			pgs[i]->flags &= ~PG_PAGEOUT;
-			pgs[i]->flags |= PG_RELEASED;
-		}
 	}
-	KASSERT(mutex_owned(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) {
+	uvm_aio_aiodone_pages(pgs, npages, write, error);
+
+	if (write && (bp->b_cflags & BC_AGE) != 0) {
 		mutex_enter(bp->b_objlock);
 		vwakeup(bp);
 		mutex_exit(bp->b_objlock);

Index: src/sys/uvm/uvm_anon.c
diff -u src/sys/uvm/uvm_anon.c:1.64 src/sys/uvm/uvm_anon.c:1.64.8.1
--- src/sys/uvm/uvm_anon.c:1.64	Sat Oct 28 00:37:13 2017
+++ src/sys/uvm/uvm_anon.c	Tue Jul  6 04:22:34 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvm_anon.c,v 1.64 2017/10/28 00:37:13 pgoyette Exp $	*/
+/*	$NetBSD: uvm_anon.c,v 1.64.8.1 2021/07/06 04:22:34 martin Exp $	*/
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_anon.c,v 1.64 2017/10/28 00:37:13 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_anon.c,v 1.64.8.1 2021/07/06 04:22:34 martin Exp $");
 
 #include "opt_uvmhist.h"
 
@@ -443,6 +443,11 @@ uvm_anon_release(struct vm_anon *anon)
 	KASSERT(pg->loan_count == 0);
 	KASSERT(anon->an_ref == 0);
 
+	if ((pg->flags & PG_PAGEOUT) != 0) {
+		pg->flags &= ~PG_PAGEOUT;
+		uvm_pageout_done(1);
+	}
+
 	mutex_enter(&uvm_pageqlock);
 	uvm_pagefree(pg);
 	mutex_exit(&uvm_pageqlock);

Index: src/sys/uvm/uvm_page.c
diff -u src/sys/uvm/uvm_page.c:1.199 src/sys/uvm/uvm_page.c:1.199.4.1
--- src/sys/uvm/uvm_page.c:1.199	Thu Mar 14 19:10:04 2019
+++ src/sys/uvm/uvm_page.c	Tue Jul  6 04:22:34 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvm_page.c,v 1.199 2019/03/14 19:10:04 kre Exp $	*/
+/*	$NetBSD: uvm_page.c,v 1.199.4.1 2021/07/06 04:22:34 martin Exp $	*/
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.199 2019/03/14 19:10:04 kre Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.199.4.1 2021/07/06 04:22:34 martin Exp $");
 
 #include "opt_ddb.h"
 #include "opt_uvm.h"
@@ -1362,9 +1362,10 @@ void
 uvm_page_unbusy(struct vm_page **pgs, int npgs)
 {
 	struct vm_page *pg;
-	int i;
+	int i, pageout_done;
 	UVMHIST_FUNC("uvm_page_unbusy"); UVMHIST_CALLED(ubchist);
 
+	pageout_done = 0;
 	for (i = 0; i < npgs; i++) {
 		pg = pgs[i];
 		if (pg == NULL || pg == PGO_DONTCARE) {
@@ -1373,7 +1374,13 @@ uvm_page_unbusy(struct vm_page **pgs, in
 
 		KASSERT(uvm_page_locked_p(pg));
 		KASSERT(pg->flags & PG_BUSY);
-		KASSERT((pg->flags & PG_PAGEOUT) == 0);
+
+		if (pg->flags & PG_PAGEOUT) {
+			pg->flags &= ~PG_PAGEOUT;
+			pg->flags |= PG_RELEASED;
+			pageout_done++;
+			atomic_inc_uint(&uvmexp.pdfreed);
+		}
 		if (pg->flags & PG_WANTED) {
 			wakeup(pg);
 		}
@@ -1392,6 +1399,9 @@ uvm_page_unbusy(struct vm_page **pgs, in
 			UVM_PAGE_OWN(pg, NULL);
 		}
 	}
+	if (pageout_done != 0) {
+		uvm_pageout_done(pageout_done);
+	}
 }
 
 #if defined(UVM_PAGE_TRKOWN)

Index: src/sys/uvm/uvm_pager.c
diff -u src/sys/uvm/uvm_pager.c:1.111.8.1 src/sys/uvm/uvm_pager.c:1.111.8.2
--- src/sys/uvm/uvm_pager.c:1.111.8.1	Fri Dec 27 06:58:56 2019
+++ src/sys/uvm/uvm_pager.c	Tue Jul  6 04:22:34 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvm_pager.c,v 1.111.8.1 2019/12/27 06:58:56 martin Exp $	*/
+/*	$NetBSD: uvm_pager.c,v 1.111.8.2 2021/07/06 04:22:34 martin Exp $	*/
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_pager.c,v 1.111.8.1 2019/12/27 06:58:56 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_pager.c,v 1.111.8.2 2021/07/06 04:22:34 martin Exp $");
 
 #include "opt_uvmhist.h"
 #include "opt_readahead.h"
@@ -428,18 +428,6 @@ uvm_aio_aiodone_pages(struct vm_page **p
 			pmap_clear_modify(pg);
 		}
 
-		/*
-		 * do accounting for pagedaemon i/o and arrange to free
-		 * the pages instead of just unbusying them.
-		 */
-
-		if (pg->flags & PG_PAGEOUT) {
-			pg->flags &= ~PG_PAGEOUT;
-			pageout_done++;
-			uvmexp.pdfreed++;
-			pg->flags |= PG_RELEASED;
-		}
-
 #if defined(VMSWAP)
 		/*
 		 * for swap pages, unlock everything for this page now.

Index: src/tests/rump/rumpkern/t_vm.c
diff -u src/tests/rump/rumpkern/t_vm.c:1.4 src/tests/rump/rumpkern/t_vm.c:1.4.16.1
--- src/tests/rump/rumpkern/t_vm.c:1.4	Fri Jan 13 21:30:43 2017
+++ src/tests/rump/rumpkern/t_vm.c	Tue Jul  6 04:22:34 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: t_vm.c,v 1.4 2017/01/13 21:30:43 christos Exp $	*/
+/*	$NetBSD: t_vm.c,v 1.4.16.1 2021/07/06 04:22:34 martin Exp $	*/
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -50,6 +50,10 @@ ATF_TC_HEAD(busypage, tc)
 ATF_TC_BODY(busypage, tc)
 {
 
+#if 0
+	atf_tc_expect_fail("test bug: unbusies an uninitialized page");
+#endif
+	atf_tc_skip("this test is buggy and hits an assertion, but atf doesn't provide any way to expect that a test program crashes, this all we can do is skip");
 	rump_init();
 
 	rump_schedule();

Reply via email to