From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=52089 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1P6MrQ-0007o8-9T for qemu-devel@nongnu.org; Thu, 14 Oct 2010 08:24:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1P6MrO-0003Xp-Vq for qemu-devel@nongnu.org; Thu, 14 Oct 2010 08:24:40 -0400 Received: from e28smtp02.in.ibm.com ([122.248.162.2]:41788) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1P6MrO-0003Xa-9z for qemu-devel@nongnu.org; Thu, 14 Oct 2010 08:24:38 -0400 Received: from d28relay05.in.ibm.com (d28relay05.in.ibm.com [9.184.220.62]) by e28smtp02.in.ibm.com (8.14.4/8.13.1) with ESMTP id o9ECOYTw018461 for ; Thu, 14 Oct 2010 17:54:34 +0530 Received: from d28av04.in.ibm.com (d28av04.in.ibm.com [9.184.220.66]) by d28relay05.in.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id o9ECOXmc2945028 for ; Thu, 14 Oct 2010 17:54:33 +0530 Received: from d28av04.in.ibm.com (loopback [127.0.0.1]) by d28av04.in.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id o9ECOXeJ032742 for ; Thu, 14 Oct 2010 23:24:33 +1100 Received: from localhost6.localdomain6 ([9.77.206.195]) by d28av04.in.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id o9ECOUtK032594 for ; Thu, 14 Oct 2010 23:24:31 +1100 From: Arun R Bharadwaj Date: Thu, 14 Oct 2010 17:54:25 +0530 Message-ID: <20101014122425.2238.13080.stgit@localhost6.localdomain6> In-Reply-To: <20101014122217.2238.94995.stgit@localhost6.localdomain6> References: <20101014122217.2238.94995.stgit@localhost6.localdomain6> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] [PATCH 4/9] Convert stat into 2nd threading model List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org From: Sripathi Kodi In this model we hand over the vcpu thread only executes till the first blocking operation. It then hands over the call to the worker thread, which does everything needed to complete the call. It can make multiple blocking calls. It finally signals the IO thread to do complete_pdu(). Gautham suggested that I use a generic function to call complete_pdu, which could further simplify the post_op structure. However, some of the calls (stat included) need to free up some memory after calling complete_pdu. Handling this becomes messy if I use a common complete function. Review comments welcome. Review comment from Gautham is a necessity. Signed-off-by: Sripathi Kodi --- hw/virtio-9p.c | 58 ++++++++++++++++++++++++++++++++------------------------ hw/virtio-9p.h | 4 ++++ 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c index ef6175a..d994293 100644 --- a/hw/virtio-9p.c +++ b/hw/virtio-9p.c @@ -1381,54 +1381,62 @@ out: v9fs_string_free(&aname); } -static void v9fs_stat_post_lstat(V9fsState *s, V9fsStatState *vs, int err) +/* This is called by the IO thread */ +static void v9fs_stat_do_complete(void *opaque) { - if (err == -1) { - err = -errno; + V9fsStatState *vs = (V9fsStatState *)opaque; + complete_pdu(vs->s, vs->pdu, vs->err); + v9fs_stat_free(&vs->v9stat); + qemu_free(vs); +} + +/* This is called by the async thread. It does everything + * other than calling complete_pdu + */ +static void v9fs_stat_worker(ThreadletWork *work) +{ + V9fsStatState *vs = container_of(work, V9fsStatState, work); + + vs->fidp = lookup_fid(vs->s, vs->fid); + if (vs->fidp == NULL) { + vs->err = -ENOENT; goto out; } - err = stat_to_v9stat(s, &vs->fidp->path, &vs->stbuf, &vs->v9stat); - if (err) { + qemu_rwmutex_rdlock(&global_rename_lock); + vs->err = v9fs_do_lstat(vs->s, &vs->fidp->path, &vs->stbuf); + if (vs->err == -1) { + vs->err = -errno; + goto out; + } + vs->err = stat_to_v9stat(vs->s, &vs->fidp->path, &vs->stbuf, &vs->v9stat); + if (vs->err) { goto out; } vs->offset += pdu_marshal(vs->pdu, vs->offset, "wS", 0, &vs->v9stat); - err = vs->offset; + vs->err = vs->offset; out: - complete_pdu(s, vs->pdu, err); - v9fs_stat_free(&vs->v9stat); - qemu_free(vs); + qemu_rwmutex_unlock(&global_rename_lock); + v9fs_async_helper_done(v9fs_stat_do_complete, vs); } static void v9fs_stat(V9fsState *s, V9fsPDU *pdu) { - int32_t fid; V9fsStatState *vs; - ssize_t err = 0; vs = qemu_malloc(sizeof(*vs)); vs->pdu = pdu; vs->offset = 7; + vs->s = s; memset(&vs->v9stat, 0, sizeof(vs->v9stat)); - pdu_unmarshal(vs->pdu, vs->offset, "d", &fid); - - vs->fidp = lookup_fid(s, fid); - if (vs->fidp == NULL) { - err = -ENOENT; - goto out; - } + pdu_unmarshal(vs->pdu, vs->offset, "d", &vs->fid); - err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf); - v9fs_stat_post_lstat(s, vs, err); + vs->work.func = v9fs_stat_worker; + submit_threadlet(&vs->work); return; - -out: - complete_pdu(s, vs->pdu, err); - v9fs_stat_free(&vs->v9stat); - qemu_free(vs); } static void v9fs_getattr_post_lstat(V9fsState *s, V9fsStatStateDotl *vs, diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h index f58d3d8..9ced508 100644 --- a/hw/virtio-9p.h +++ b/hw/virtio-9p.h @@ -248,6 +248,10 @@ typedef struct V9fsStatState { V9fsStat v9stat; V9fsFidState *fidp; struct stat stbuf; + V9fsState *s; + int32_t fid; + int32_t err; + ThreadletWork work; } V9fsStatState; typedef struct V9fsStatDotl {