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.
*/