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: