From patchwork Tue Mar 15 10:38:03 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arun Bharadwaj X-Patchwork-Id: 86937 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 4A06FB6F01 for ; Tue, 15 Mar 2011 21:40:27 +1100 (EST) Received: from localhost ([127.0.0.1]:41300 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PzRfs-00007n-GM for incoming@patchwork.ozlabs.org; Tue, 15 Mar 2011 06:40:24 -0400 Received: from [140.186.70.92] (port=60099 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PzRdk-0007pO-Ox for qemu-devel@nongnu.org; Tue, 15 Mar 2011 06:38:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PzRdj-0003tv-H6 for qemu-devel@nongnu.org; Tue, 15 Mar 2011 06:38:12 -0400 Received: from e23smtp04.au.ibm.com ([202.81.31.146]:41040) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PzRdi-0003tm-V6 for qemu-devel@nongnu.org; Tue, 15 Mar 2011 06:38:11 -0400 Received: from d23relay05.au.ibm.com (d23relay05.au.ibm.com [202.81.31.247]) by e23smtp04.au.ibm.com (8.14.4/8.13.1) with ESMTP id p2FAWZWh002776 for ; Tue, 15 Mar 2011 21:32:35 +1100 Received: from d23av01.au.ibm.com (d23av01.au.ibm.com [9.190.234.96]) by d23relay05.au.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p2FAc9v92314426 for ; Tue, 15 Mar 2011 21:38:09 +1100 Received: from d23av01.au.ibm.com (loopback [127.0.0.1]) by d23av01.au.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p2FAc89p004079 for ; Tue, 15 Mar 2011 21:38:09 +1100 Received: from linux.vnet.ibm.com ([9.124.35.19]) by d23av01.au.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id p2FAc4QS004032 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Tue, 15 Mar 2011 21:38:07 +1100 Date: Tue, 15 Mar 2011 16:08:03 +0530 From: Arun R Bharadwaj To: qemu-devel@nongnu.org Message-ID: <20110315103803.GC23922@linux.vnet.ibm.com> References: <20110315103453.GA23922@linux.vnet.ibm.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20110315103453.GA23922@linux.vnet.ibm.com> User-Agent: Mutt/1.5.20 (2009-06-14) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) X-Received-From: 202.81.31.146 Cc: stefanha@gmail.com, aliguori@us.ibm.com, jvrao@linux.vnet.ibm.com, aneesh.kumar@linux.vnet.ibm.com, Arun Bharadwaj Subject: [Qemu-devel] [v1 PATCH 2/3]: Helper routines to use GLib threadpool infrastructure in 9pfs. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: arun@linux.vnet.ibm.com List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org * Arun R Bharadwaj [2011-03-15 16:04:53]: Author: Arun R Bharadwaj Date: Thu Mar 10 15:11:49 2011 +0530 Helper routines to use GLib threadpool infrastructure in 9pfs. This patch creates helper routines to make use of the threadpool infrastructure provided by GLib. This is based on the prototype patch by Anthony which does a similar thing for posix-aio-compat.c An example use case is provided in the next patch where one of the syscalls in 9pfs is converted into the threaded model using these helper routines. Signed-off-by: Arun R Bharadwaj Reviewed-by: Aneesh Kumar K.V diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index dceefd5..cf61345 100644 --- a/hw/9pfs/virtio-9p.c +++ b/hw/9pfs/virtio-9p.c @@ -18,6 +18,8 @@ #include "fsdev/qemu-fsdev.h" #include "virtio-9p-debug.h" #include "virtio-9p-xattr.h" +#include "signal.h" +#include "qemu-thread.h" int debug_9p_pdu; static void v9fs_reclaim_fd(V9fsState *s); @@ -36,6 +38,89 @@ enum { Oappend = 0x80, }; +typedef struct V9fsPool { + GThreadPool *pool; + GList *requests; + int rfd; + int wfd; +} V9fsPool; + +static V9fsPool v9fs_pool; + +static void v9fs_qemu_submit_request(V9fsRequest *req) +{ + V9fsPool *p = &v9fs_pool; + + p->requests = g_list_append(p->requests, req); + g_thread_pool_push(v9fs_pool.pool, req, NULL); +} + +static void die2(int err, const char *what) +{ + fprintf(stderr, "%s failed: %s\n", what, strerror(err)); + abort(); +} + +static void die(const char *what) +{ + die2(errno, what); +} + +static void v9fs_qemu_process_post_ops(void *arg) +{ + struct V9fsPool *p = &v9fs_pool; + struct V9fsPostOp *post_op; + char byte; + ssize_t len; + GList *cur_req, *next_req; + + do { + len = read(p->rfd, &byte, sizeof(byte)); + } while (len == -1 && errno == EINTR); + + for (cur_req = p->requests; cur_req != NULL; cur_req = next_req) { + V9fsRequest *req = cur_req->data; + next_req = g_list_next(cur_req); + + if (!req->done) { + continue; + } + + post_op = &req->post_op; + post_op->func(post_op->arg); + p->requests = g_list_remove_link(p->requests, cur_req); + g_list_free(p->requests); + } +} + +static inline void v9fs_thread_signal(void) +{ + struct V9fsPool *p = &v9fs_pool; + char byte = 0; + ssize_t ret; + + do { + ret = write(p->wfd, &byte, sizeof(byte)); + } while (ret == -1 && errno == EINTR); + + if (ret < 0 && errno != EAGAIN) { + die("write() in v9fs"); + } + + if (kill(getpid(), SIGUSR2)) { + die("kill failed"); + } +} + +static void v9fs_thread_routine(gpointer data, gpointer user_data) +{ + V9fsRequest *req = data; + + req->func(req); + v9fs_thread_signal(); + req->done = 1; +} + static int omode_to_uflags(int8_t mode) { int ret = 0; @@ -3850,7 +3935,8 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf) int i, len; struct stat stat; FsTypeEntry *fse; - + int fds[2]; + V9fsPool *p = &v9fs_pool; s = (V9fsState *)virtio_common_init("virtio-9p", VIRTIO_ID_9P, @@ -3939,5 +4025,21 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf) s->tag_len; s->vdev.get_config = virtio_9p_get_config; + if (qemu_pipe(fds) == -1) { + fprintf(stderr, "failed to create fd's for virtio-9p\n"); + exit(1); + } + + p->pool = g_thread_pool_new(v9fs_thread_routine, p, 8, FALSE, NULL); + p->rfd = fds[0]; + p->wfd = fds[1]; + + fcntl(p->rfd, F_SETFL, O_NONBLOCK); + fcntl(p->wfd, F_SETFL, O_NONBLOCK); + + qemu_set_fd_handler(p->rfd, v9fs_qemu_process_post_ops, NULL, NULL); + + (void) v9fs_qemu_submit_request; + return &s->vdev; } diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h index 10809ba..e7d2326 100644 --- a/hw/9pfs/virtio-9p.h +++ b/hw/9pfs/virtio-9p.h @@ -124,6 +124,20 @@ struct V9fsPDU QLIST_ENTRY(V9fsPDU) next; }; +typedef struct V9fsPostOp { + /* Post Operation routine to execute after executing syscall */ + void (*func)(void *arg); + void *arg; +} V9fsPostOp; + +typedef struct V9fsRequest { + void (*func)(struct V9fsRequest *req); + + /* Flag to indicate that request is satisfied, ready for post-processing */ + int done; + + V9fsPostOp post_op; +} V9fsRequest; /* FIXME * 1) change user needs to set groups and stuff