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, &copydata, 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:

Reply via email to