Module Name: src
Committed By: pooka
Date: Wed Nov 24 17:00:11 UTC 2010
Modified Files:
src/lib/librumpuser: rumpuser_sp.c sp_common.c
Log Message:
Unschedule from CPU for out-of-kernel blocking ops. Otherwise we
might even deadlock if the thread that wakes us up wants a CPU.
To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.13 src/lib/librumpuser/rumpuser_sp.c
cvs rdiff -u -r1.7 -r1.8 src/lib/librumpuser/sp_common.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.12 src/lib/librumpuser/rumpuser_sp.c:1.13
--- src/lib/librumpuser/rumpuser_sp.c:1.12 Wed Nov 24 15:17:46 2010
+++ src/lib/librumpuser/rumpuser_sp.c Wed Nov 24 17:00:10 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: rumpuser_sp.c,v 1.12 2010/11/24 15:17:46 pooka Exp $ */
+/* $NetBSD: rumpuser_sp.c,v 1.13 2010/11/24 17:00:10 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.12 2010/11/24 15:17:46 pooka Exp $");
+__RCSID("$NetBSD: rumpuser_sp.c,v 1.13 2010/11/24 17:00:10 pooka Exp $");
#include <sys/types.h>
#include <sys/atomic.h>
@@ -61,6 +61,7 @@
#include <unistd.h>
#include <rump/rumpuser.h>
+#include "rumpuser_int.h"
#include "sp_common.c"
@@ -211,13 +212,12 @@
copydata.rcp_len = dlen;
putwait(spc, &rw, &rhdr);
-
- sendlock(spc);
rv = dosend(spc, &rhdr, sizeof(rhdr));
rv = dosend(spc, ©data, sizeof(copydata));
- sendunlock(spc);
- if (rv)
- return rv; /* XXX: unputwait */
+ if (rv) {
+ unputwait(spc, &rw);
+ return rv;
+ }
rv = waitresp(spc, &rw);
@@ -271,15 +271,15 @@
rhdr.rsp_sysnum = 0;
putwait(spc, &rw, &rhdr);
-
- sendlock(spc);
rv = dosend(spc, &rhdr, sizeof(rhdr));
rv = dosend(spc, &howmuch, sizeof(howmuch));
- sendunlock(spc);
- if (rv)
- return rv; /* XXX: unputwait */
+ if (rv) {
+ unputwait(spc, &rw);
+ return rv;
+ }
rv = waitresp(spc, &rw);
+
*resp = rw.rw_data;
DPRINTF(("anonmmap: mapped at %p\n", **(void ***)resp));
@@ -310,7 +310,7 @@
DPRINTF(("spcrelease: spc %p fd %d\n", spc, spc->spc_fd));
- _DIAGASSERT(TAILQ_EMPTY(spc->spc_respwait));
+ _DIAGASSERT(TAILQ_EMPTY(&spc->spc_respwait));
_DIAGASSERT(spc->spc_buf == NULL);
lwproc_switch(spc->spc_mainlwp);
@@ -394,8 +394,8 @@
TAILQ_INIT(&spclist[i].spc_respwait);
- DPRINTF(("rump_sp: added new connection at idx %u, pid %d\n",
- i, lwproc_getpid()));
+ DPRINTF(("rump_sp: added new connection fd %d at idx %u, pid %d\n",
+ newfd, i, lwproc_getpid()));
lwproc_switch(NULL);
@@ -444,15 +444,21 @@
{
struct spclient *spc = arg;
void *rdata = NULL; /* XXXuninit */
- int rv;
+ int rv, nlocks;
+
+ rumpuser__kunlock(0, &nlocks, NULL);
rv = copyin_req(spc, uaddr, len, &rdata);
if (rv)
- return EFAULT;
+ goto out;
memcpy(kaddr, rdata, len);
free(rdata);
+ out:
+ rumpuser__klock(nlocks, NULL);
+ if (rv)
+ return EFAULT;
return 0;
}
@@ -460,8 +466,13 @@
rumpuser_sp_copyout(void *arg, const void *kaddr, void *uaddr, size_t dlen)
{
struct spclient *spc = arg;
+ int nlocks, rv;
+
+ rumpuser__kunlock(0, &nlocks, NULL);
+ rv = send_copyout_req(spc, uaddr, kaddr, dlen);
+ rumpuser__klock(nlocks, NULL);
- if (send_copyout_req(spc, uaddr, kaddr, dlen) != 0)
+ if (rv)
return EFAULT;
return 0;
}
@@ -471,20 +482,30 @@
{
struct spclient *spc = arg;
void *resp, *rdata;
- int rv;
+ int nlocks, rv;
+
+ rumpuser__kunlock(0, &nlocks, NULL);
rv = anonmmap_req(spc, howmuch, &rdata);
- if (rv)
- return rv;
+ if (rv) {
+ rv = EFAULT;
+ goto out;
+ }
resp = *(void **)rdata;
free(rdata);
if (resp == NULL) {
- return ENOMEM;
+ rv = ENOMEM;
}
*addr = resp;
+
+ out:
+ rumpuser__klock(nlocks, NULL);
+
+ if (rv)
+ return rv;
return 0;
}
Index: src/lib/librumpuser/sp_common.c
diff -u src/lib/librumpuser/sp_common.c:1.7 src/lib/librumpuser/sp_common.c:1.8
--- src/lib/librumpuser/sp_common.c:1.7 Wed Nov 24 14:32:42 2010
+++ src/lib/librumpuser/sp_common.c Wed Nov 24 17:00:10 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: sp_common.c,v 1.7 2010/11/24 14:32:42 pooka Exp $ */
+/* $NetBSD: sp_common.c,v 1.8 2010/11/24 17:00:10 pooka Exp $ */
/*
* Copyright (c) 2010 Antti Kantee. All Rights Reserved.
@@ -216,7 +216,15 @@
pthread_mutex_lock(&spc->spc_mtx);
rw->rw_reqno = rhdr->rsp_reqno = spc->spc_nextreq++;
TAILQ_INSERT_TAIL(&spc->spc_respwait, rw, rw_entries);
+}
+
+static void
+unputwait(struct spclient *spc, struct respwait *rw)
+{
+
+ TAILQ_REMOVE(&spc->spc_respwait, rw, rw_entries);
pthread_mutex_unlock(&spc->spc_mtx);
+ pthread_cond_destroy(&rw->rw_cv);
}
static void
@@ -258,7 +266,6 @@
struct pollfd pfd;
int rv = 0;
- pthread_mutex_lock(&spc->spc_mtx);
while (rw->rw_data == NULL && spc->spc_dying == 0) {
/* are we free to receive? */
if (spc->spc_istatus == SPCSTATUS_FREE) {
@@ -271,8 +278,17 @@
pfd.events = POLLIN;
for (gotresp = 0; !gotresp; ) {
- while (readframe(spc) < 1)
+ rv = readframe(spc);
+ switch (rv) {
+ case 0:
poll(&pfd, 1, INFTIM);
+ continue;
+ case -1:
+ spc->spc_dying = 1;
+ break;
+ default:
+ break;
+ }
switch (spc->spc_hdr.rsp_class) {
case RUMPSP_RESP: