Module Name:    src
Committed By:   pooka
Date:           Mon Nov 22 20:42:19 UTC 2010

Modified Files:
        src/lib/librumpuser: rumpuser_sp.c
        src/sys/rump/include/rump: rumpuser.h
        src/sys/rump/librump/rumpkern: lwproc.c rump.c rumpcopy.c vm.c

Log Message:
Support physio for remote processes.
==> add support for remote vmspace vmapbuf/vunmapbuf
  ==> add proper support for copyin/out_vmspace
    ==> add support for remote vmspace uvm_io
      ==> add support for non-curproc rumpuser_sp_copyin/out
        ==> store remote context in vm_map->pmap instead of
            pthread_specificdata

In short, makes read/write of most (all?) block devices work from
a remote rump client via rump syscalls.


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/lib/librumpuser/rumpuser_sp.c
cvs rdiff -u -r1.51 -r1.52 src/sys/rump/include/rump/rumpuser.h
cvs rdiff -u -r1.5 -r1.6 src/sys/rump/librump/rumpkern/lwproc.c
cvs rdiff -u -r1.205 -r1.206 src/sys/rump/librump/rumpkern/rump.c
cvs rdiff -u -r1.10 -r1.11 src/sys/rump/librump/rumpkern/rumpcopy.c
cvs rdiff -u -r1.101 -r1.102 src/sys/rump/librump/rumpkern/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/lib/librumpuser/rumpuser_sp.c
diff -u src/lib/librumpuser/rumpuser_sp.c:1.9 src/lib/librumpuser/rumpuser_sp.c:1.10
--- src/lib/librumpuser/rumpuser_sp.c:1.9	Fri Nov 19 17:47:44 2010
+++ src/lib/librumpuser/rumpuser_sp.c	Mon Nov 22 20:42:19 2010
@@ -1,4 +1,4 @@
-/*      $NetBSD: rumpuser_sp.c,v 1.9 2010/11/19 17:47:44 pooka Exp $	*/
+/*      $NetBSD: rumpuser_sp.c,v 1.10 2010/11/22 20:42:19 pooka Exp $	*/
 
 /*
  * Copyright (c) 2010 Antti Kantee.  All Rights Reserved.
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: rumpuser_sp.c,v 1.9 2010/11/19 17:47:44 pooka Exp $");
+__RCSID("$NetBSD: rumpuser_sp.c,v 1.10 2010/11/22 20:42:19 pooka Exp $");
 
 #include <sys/types.h>
 #include <sys/mman.h>
@@ -68,7 +68,6 @@
 static struct pollfd pfdlist[MAXCLI];
 static struct spclient spclist[MAXCLI];
 static unsigned int nfds, maxidx;
-static pthread_key_t spclient_tls;
 
 static struct rumpuser_sp_ops spops;
 
@@ -96,12 +95,12 @@
 }
 
 static int
-lwproc_newproc(void)
+lwproc_newproc(struct spclient *spc)
 {
 	int rv;
 
 	spops.spop_schedule();
-	rv = spops.spop_lwproc_newproc();
+	rv = spops.spop_lwproc_newproc(spc);
 	spops.spop_unschedule();
 
 	return rv;
@@ -350,17 +349,17 @@
 		return error;
 	}
 
-	if ((error = lwproc_newproc()) != 0) {
-		close(newfd);
-		return error;
-	}
-
 	/* find empty slot the simple way */
 	for (i = 0; i < MAXCLI; i++) {
 		if (pfdlist[i].fd == -1)
 			break;
 	}
 
+	if ((error = lwproc_newproc(&spclist[i])) != 0) {
+		close(newfd);
+		return error;
+	}
+
 	assert(i < MAXCLI);
 	nfds++;
 
@@ -395,11 +394,9 @@
 	DPRINTF(("rump_sp: handling syscall %d from client %d\n",
 	    sysnum, 0));
 
-	pthread_setspecific(spclient_tls, spc);
 	lwproc_newlwp(spc->spc_pid);
 	rv = rumpsyscall(sysnum, data, retval);
 	lwproc_switch(NULL);
-	pthread_setspecific(spclient_tls, NULL);
 	free(data);
 
 	DPRINTF(("rump_sp: got return value %d & %d/%d\n",
@@ -424,15 +421,11 @@
 }
 
 int
-rumpuser_sp_copyin(const void *uaddr, void *kaddr, size_t len)
+rumpuser_sp_copyin(void *arg, const void *uaddr, void *kaddr, size_t len)
 {
-	struct spclient *spc;
+	struct spclient *spc = arg;
 	void *rdata = NULL; /* XXXuninit */
 
-	spc = pthread_getspecific(spclient_tls);
-	if (!spc)
-		return EFAULT;
-
 	copyin_req(spc, uaddr, len, &rdata);
 
 	memcpy(kaddr, rdata, len);
@@ -442,15 +435,9 @@
 }
 
 int
-rumpuser_sp_copyout(const void *kaddr, void *uaddr, size_t dlen)
+rumpuser_sp_copyout(void *arg, const void *kaddr, void *uaddr, size_t dlen)
 {
-	struct spclient *spc;
-
-	spc = pthread_getspecific(spclient_tls);
-	if (!spc) {
-		DPRINTF(("rump_sp: copyout curlwp not found\n"));
-		return EFAULT;
-	}
+	struct spclient *spc = arg;
 
 	if (send_copyout_req(spc, uaddr, kaddr, dlen) != 0)
 		return EFAULT;
@@ -458,16 +445,12 @@
 }
 
 int
-rumpuser_sp_anonmmap(size_t howmuch, void **addr)
+rumpuser_sp_anonmmap(void *arg, size_t howmuch, void **addr)
 {
-	struct spclient *spc;
+	struct spclient *spc = arg;
 	void *resp, *rdata;
 	int rv;
 
-	spc = pthread_getspecific(spclient_tls);
-	if (!spc)
-		return EFAULT;
-
 	rv = anonmmap_req(spc, howmuch, &rdata);
 	if (rv)
 		return rv;
@@ -638,12 +621,6 @@
 
 	/* sloppy error recovery */
 
-	error = pthread_key_create(&spclient_tls, NULL);
-	if (error) {
-		fprintf(stderr, "rump_sp: tls create failed\n");
-		return error;
-	}
-
 	/*LINTED*/
 	if (bind(s, sap, sap->sa_len) == -1) {
 		fprintf(stderr, "rump_sp: server bind failed\n");

Index: src/sys/rump/include/rump/rumpuser.h
diff -u src/sys/rump/include/rump/rumpuser.h:1.51 src/sys/rump/include/rump/rumpuser.h:1.52
--- src/sys/rump/include/rump/rumpuser.h:1.51	Fri Nov 19 17:06:57 2010
+++ src/sys/rump/include/rump/rumpuser.h	Mon Nov 22 20:42:19 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: rumpuser.h,v 1.51 2010/11/19 17:06:57 pooka Exp $	*/
+/*	$NetBSD: rumpuser.h,v 1.52 2010/11/22 20:42:19 pooka Exp $	*/
 
 /*
  * Copyright (c) 2007 Antti Kantee.  All Rights Reserved.
@@ -36,7 +36,7 @@
 #include <stdint.h>
 #endif
 
-#define RUMPUSER_VERSION 4
+#define RUMPUSER_VERSION 5
 int rumpuser_getversion(void);
 
 struct msghdr;
@@ -210,7 +210,7 @@
 
 	void (*spop_lwproc_switch)(struct lwp *);
 	void (*spop_lwproc_release)(void);
-	int (*spop_lwproc_newproc)(void);
+	int (*spop_lwproc_newproc)(void *);
 	int (*spop_lwproc_newlwp)(pid_t);
 	struct lwp * (*spop_lwproc_curlwp)(void);
 	int (*spop_syscall)(int, void *, register_t *);
@@ -218,8 +218,8 @@
 };
 
 int	rumpuser_sp_init(const struct rumpuser_sp_ops *, const char *);
-int	rumpuser_sp_copyin(const void *, void *, size_t);
-int	rumpuser_sp_copyout(const void *, void *, size_t);
-int	rumpuser_sp_anonmmap(size_t, void **);
+int	rumpuser_sp_copyin(void *, const void *, void *, size_t);
+int	rumpuser_sp_copyout(void *, const void *, void *, size_t);
+int	rumpuser_sp_anonmmap(void *, size_t, void **);
 
 #endif /* _RUMP_RUMPUSER_H_ */

Index: src/sys/rump/librump/rumpkern/lwproc.c
diff -u src/sys/rump/librump/rumpkern/lwproc.c:1.5 src/sys/rump/librump/rumpkern/lwproc.c:1.6
--- src/sys/rump/librump/rumpkern/lwproc.c:1.5	Wed Nov 17 19:54:09 2010
+++ src/sys/rump/librump/rumpkern/lwproc.c	Mon Nov 22 20:42:19 2010
@@ -1,4 +1,4 @@
-/*      $NetBSD: lwproc.c,v 1.5 2010/11/17 19:54:09 pooka Exp $	*/
+/*      $NetBSD: lwproc.c,v 1.6 2010/11/22 20:42:19 pooka Exp $	*/
 
 /*
  * Copyright (c) 2010 Antti Kantee.  All Rights Reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: lwproc.c,v 1.5 2010/11/17 19:54:09 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lwproc.c,v 1.6 2010/11/22 20:42:19 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -77,6 +77,12 @@
 	cv_destroy(&p->p_waitcv);
 	cv_destroy(&p->p_lwpcv);
 
+	/* non-kernel vmspaces are not shared */
+	if (p->p_vmspace != vmspace_kernel()) {
+		KASSERT(p->p_vmspace->vm_refcnt == 1);
+		kmem_free(p->p_vmspace, sizeof(*p->p_vmspace));
+	}
+
 	proc_free_mem(p);
 }
 

Index: src/sys/rump/librump/rumpkern/rump.c
diff -u src/sys/rump/librump/rumpkern/rump.c:1.205 src/sys/rump/librump/rumpkern/rump.c:1.206
--- src/sys/rump/librump/rumpkern/rump.c:1.205	Sun Nov 21 22:17:24 2010
+++ src/sys/rump/librump/rumpkern/rump.c	Mon Nov 22 20:42:19 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: rump.c,v 1.205 2010/11/21 22:17:24 pooka Exp $	*/
+/*	$NetBSD: rump.c,v 1.206 2010/11/22 20:42:19 pooka Exp $	*/
 
 /*
  * Copyright (c) 2007 Antti Kantee.  All Rights Reserved.
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.205 2010/11/21 22:17:24 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.206 2010/11/22 20:42:19 pooka Exp $");
 
 #include <sys/systm.h>
 #define ELFSIZE ARCH_ELFSIZE
@@ -100,13 +100,8 @@
 int rump_threads = 1;
 #endif
 
-/*
- * System call proxying support.  These deserve another look later,
- * but good enough for now.
- */
-static struct vmspace sp_vmspace;
-
 static int rump_proxy_syscall(int, void *, register_t *);
+static int rump_proxy_newproc(void *);
 
 static char rump_msgbuf[16*1024]; /* 16k should be enough for std rump needs */
 
@@ -202,7 +197,7 @@
 	.spop_unschedule	= rump_unschedule,
 	.spop_lwproc_switch	= rump_lwproc_switch,
 	.spop_lwproc_release	= rump_lwproc_releaselwp,
-	.spop_lwproc_newproc	= rump_lwproc_newproc,
+	.spop_lwproc_newproc	= rump_proxy_newproc,
 	.spop_lwproc_newlwp	= rump_lwproc_newlwp,
 	.spop_lwproc_curlwp	= rump_lwproc_curlwp,
 	.spop_syscall		= rump_proxy_syscall,
@@ -649,13 +644,33 @@
 
 	callp = rump_sysent + num;
 	l = curlwp;
-	curproc->p_vmspace = &sp_vmspace;
 	rv = sy_call(callp, l, (void *)arg, retval);
-	curproc->p_vmspace = vmspace_kernel();
 
 	return rv;
 }
 
+static int
+rump_proxy_newproc(void *priv)
+{
+	struct vmspace *newspace;
+	int error;
+
+	if ((error = rump_lwproc_newproc()) != 0)
+		return error;
+
+	/*
+	 * Since it's a proxy proc, adjust the vmspace.
+	 * Refcount will eternally be 1.
+	 */
+	newspace = kmem_alloc(sizeof(*newspace), KM_SLEEP);
+	newspace->vm_refcnt = 1;
+	newspace->vm_map.pmap = priv;
+	KASSERT(curproc->p_vmspace == vmspace_kernel());
+	curproc->p_vmspace = newspace;
+
+	return 0;
+}
+
 int
 rump_boot_gethowto()
 {

Index: src/sys/rump/librump/rumpkern/rumpcopy.c
diff -u src/sys/rump/librump/rumpkern/rumpcopy.c:1.10 src/sys/rump/librump/rumpkern/rumpcopy.c:1.11
--- src/sys/rump/librump/rumpkern/rumpcopy.c:1.10	Wed Nov 17 19:54:09 2010
+++ src/sys/rump/librump/rumpkern/rumpcopy.c	Mon Nov 22 20:42:19 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: rumpcopy.c,v 1.10 2010/11/17 19:54:09 pooka Exp $	*/
+/*	$NetBSD: rumpcopy.c,v 1.11 2010/11/22 20:42:19 pooka Exp $	*/
 
 /*
  * Copyright (c) 2009 Antti Kantee.  All Rights Reserved.
@@ -26,19 +26,21 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rumpcopy.c,v 1.10 2010/11/17 19:54:09 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rumpcopy.c,v 1.11 2010/11/22 20:42:19 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/lwp.h>
 #include <sys/systm.h>
+#include <sys/uio.h>
 
-#include <rump/rump.h>
+#include <rump/rumpuser.h>
 
 #include "rump_private.h"
 
 int
 copyin(const void *uaddr, void *kaddr, size_t len)
 {
+	int error = 0;
 
 	if (__predict_false(uaddr == NULL && len)) {
 		return EFAULT;
@@ -47,14 +49,17 @@
 	if (curproc->p_vmspace == vmspace_kernel()) {
 		memcpy(kaddr, uaddr, len);
 	} else {
-		rumpuser_sp_copyin(uaddr, kaddr, len);
+		error = rumpuser_sp_copyin(curproc->p_vmspace->vm_map.pmap,
+		    uaddr, kaddr, len);
 	}
-	return 0;
+
+	return error;
 }
 
 int
 copyout(const void *kaddr, void *uaddr, size_t len)
 {
+	int error = 0;
 
 	if (__predict_false(uaddr == NULL && len)) {
 		return EFAULT;
@@ -63,20 +68,24 @@
 	if (curproc->p_vmspace == vmspace_kernel()) {
 		memcpy(uaddr, kaddr, len);
 	} else {
-		rumpuser_sp_copyout(kaddr, uaddr, len);
+		error = rumpuser_sp_copyout(curproc->p_vmspace->vm_map.pmap,
+		    kaddr, uaddr, len);
 	}
-	return 0;
+	return error;
 }
 
 int
 subyte(void *uaddr, int byte)
 {
+	int error = 0;
 
 	if (curproc->p_vmspace == vmspace_kernel())
 		*(char *)uaddr = byte;
 	else
-		rumpuser_sp_copyout(&byte, uaddr, 1);
-	return 0;
+		error = rumpuser_sp_copyout(curproc->p_vmspace->vm_map.pmap,
+		    &byte, uaddr, 1);
+
+	return error;
 }
 
 int
@@ -109,7 +118,8 @@
 	if (curproc->p_vmspace == vmspace_kernel())
 		return copystr(uaddr, kaddr, len, done);
 
-	if ((rv = rumpuser_sp_copyin(uaddr, kaddr, len)) != 0)
+	if ((rv = rumpuser_sp_copyin(curproc->p_vmspace->vm_map.pmap,
+	    uaddr, kaddr, len)) != 0)
 		return rv;
 
 	/* figure out if we got a terminated string or not */
@@ -132,6 +142,7 @@
 copyoutstr(const void *kaddr, void *uaddr, size_t len, size_t *done)
 {
 	size_t slen;
+	int error;
 
 	if (curproc->p_vmspace == vmspace_kernel())
 		return copystr(kaddr, uaddr, len, done);
@@ -140,11 +151,12 @@
 	if (slen > len)
 		return ENAMETOOLONG;
 
-	rumpuser_sp_copyout(kaddr, uaddr, slen);
+	error = rumpuser_sp_copyout(curproc->p_vmspace->vm_map.pmap,
+	    kaddr, uaddr, slen);
 	if (done)
 		*done = slen;
 
-	return 0;
+	return error;
 }
 
 int
@@ -154,3 +166,43 @@
 	memcpy(dst, src, len);
 	return 0;
 }
+
+/*
+ * Low-level I/O routine.  This is used only when "all else fails",
+ * i.e. the current thread does not have an appropriate vm context.
+ */
+int
+uvm_io(struct vm_map *vm, struct uio *uio)
+{
+	int error;
+
+	/* loop over iovecs one-by-one and copyout */
+	for (; uio->uio_resid && uio->uio_iovcnt;
+	    uio->uio_iovcnt--, uio->uio_iov++) {
+		struct iovec *iov = uio->uio_iov;
+		size_t curlen = MIN(uio->uio_resid, iov->iov_len);
+
+		if (__predict_false(curlen == 0))
+			continue;
+
+		if (uio->uio_rw == UIO_READ) {
+			error = rumpuser_sp_copyin(vm->pmap,
+			    (void *)(vaddr_t)uio->uio_offset, iov->iov_base,
+			    curlen);
+		} else {
+			error = rumpuser_sp_copyout(vm->pmap,
+			    iov->iov_base, (void *)(vaddr_t)uio->uio_offset,
+			    curlen);
+		}
+		if (error)
+			break;
+
+		iov->iov_base = (uint8_t *)iov->iov_base + curlen;
+		iov->iov_len -= curlen;
+
+		uio->uio_resid -= curlen;
+		uio->uio_offset += curlen;
+	}
+
+	return error;
+}

Index: src/sys/rump/librump/rumpkern/vm.c
diff -u src/sys/rump/librump/rumpkern/vm.c:1.101 src/sys/rump/librump/rumpkern/vm.c:1.102
--- src/sys/rump/librump/rumpkern/vm.c:1.101	Wed Nov 17 19:54:09 2010
+++ src/sys/rump/librump/rumpkern/vm.c	Mon Nov 22 20:42:19 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: vm.c,v 1.101 2010/11/17 19:54:09 pooka Exp $	*/
+/*	$NetBSD: vm.c,v 1.102 2010/11/22 20:42:19 pooka Exp $	*/
 
 /*
  * Copyright (c) 2007-2010 Antti Kantee.  All Rights Reserved.
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm.c,v 1.101 2010/11/17 19:54:09 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm.c,v 1.102 2010/11/22 20:42:19 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -348,7 +348,8 @@
 	if (curproc->p_vmspace == vmspace_kernel()) {
 		uaddr = rumpuser_anonmmap(NULL, size, 0, 0, &error);
 	} else {
-		error = rumpuser_sp_anonmmap(size, &uaddr);
+		error = rumpuser_sp_anonmmap(curproc->p_vmspace->vm_map.pmap,
+		    size, &uaddr);
 	}
 	if (uaddr == NULL)
 		return error;
@@ -701,14 +702,13 @@
 }
 
 /*
- * Mapping and vm space locking routines.
- * XXX: these don't work for non-local vmspaces
+ * VM space locking routines.  We don't really have to do anything,
+ * since the pages are always "wired" (both local and remote processes).
  */
 int
 uvm_vslock(struct vmspace *vs, void *addr, size_t len, vm_prot_t access)
 {
 
-	KASSERT(vs == vmspace_kernel());
 	return 0;
 }
 
@@ -716,20 +716,41 @@
 uvm_vsunlock(struct vmspace *vs, void *addr, size_t len)
 {
 
-	KASSERT(vs == vmspace_kernel());
 }
 
+/*
+ * For the local case the buffer mappers don't need to do anything.
+ * For the remote case we need to reserve space and copy data in or
+ * out, depending on B_READ/B_WRITE.
+ */
 void
 vmapbuf(struct buf *bp, vsize_t len)
 {
 
 	bp->b_saveaddr = bp->b_data;
+
+	/* remote case */
+	if (curproc->p_vmspace != vmspace_kernel()) {
+		bp->b_data = rump_hypermalloc(len, 0, true, "vmapbuf");
+		if (BUF_ISWRITE(bp)) {
+			copyin(bp->b_saveaddr, bp->b_data, len);
+		}
+	}
 }
 
 void
 vunmapbuf(struct buf *bp, vsize_t len)
 {
 
+	/* remote case */
+	if (bp->b_proc->p_vmspace != vmspace_kernel()) {
+		if (BUF_ISREAD(bp)) {
+			copyout_proc(bp->b_proc,
+			    bp->b_data, bp->b_saveaddr, len);
+		}
+		rump_hyperfree(bp->b_data, len);
+	}
+
 	bp->b_data = bp->b_saveaddr;
 	bp->b_saveaddr = 0;
 }
@@ -751,17 +772,6 @@
 	/* nothing for now */
 }
 
-int
-uvm_io(struct vm_map *map, struct uio *uio)
-{
-
-	/*
-	 * just do direct uio for now.  but this needs some vmspace
-	 * olympics for rump_sysproxy.
-	 */
-	return uiomove((void *)(vaddr_t)uio->uio_offset, uio->uio_resid, uio);
-}
-
 /*
  * page life cycle stuff.  it really doesn't exist, so just stubs.
  */

Reply via email to