From patchwork Thu Oct 22 15:54:36 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 36696 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 07DF1B7BA6 for ; Fri, 23 Oct 2009 02:59:49 +1100 (EST) Received: from localhost ([127.0.0.1]:59315 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N104o-0003WL-6n for incoming@patchwork.ozlabs.org; Thu, 22 Oct 2009 11:59:46 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1N1017-0001H9-T8 for qemu-devel@nongnu.org; Thu, 22 Oct 2009 11:55:57 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1N1013-0001E1-3D for qemu-devel@nongnu.org; Thu, 22 Oct 2009 11:55:57 -0400 Received: from [199.232.76.173] (port=48089 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N1012-0001Dy-Tz for qemu-devel@nongnu.org; Thu, 22 Oct 2009 11:55:52 -0400 Received: from mx1.redhat.com ([209.132.183.28]:53899) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1N1012-00041I-6a for qemu-devel@nongnu.org; Thu, 22 Oct 2009 11:55:52 -0400 Received: from int-mx04.intmail.prod.int.phx2.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.17]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n9MFtppr000414 for ; Thu, 22 Oct 2009 11:55:51 -0400 Received: from localhost.localdomain (dhcp-5-175.str.redhat.com [10.32.5.175]) by int-mx04.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id n9MFtlNw003324; Thu, 22 Oct 2009 11:55:50 -0400 From: Kevin Wolf To: qemu-devel@nongnu.org Date: Thu, 22 Oct 2009 17:54:36 +0200 Message-Id: <1256226882-26434-3-git-send-email-kwolf@redhat.com> In-Reply-To: <1256226882-26434-1-git-send-email-kwolf@redhat.com> References: <1256226882-26434-1-git-send-email-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.17 X-detected-operating-system: by monty-python.gnu.org: Genre and OS details not recognized. Cc: Kevin Wolf Subject: [Qemu-devel] [PATCH 2/8] Add qemu_aio_process_queue() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list 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 We'll leave some AIO completions unhandled when we can't call the callback. qemu_aio_process_queue() is used later to run any callbacks that are left and can be run then. Signed-off-by: Kevin Wolf --- aio.c | 30 ++++++++++++++++++++++++++++++ block/curl.c | 8 ++++---- linux-aio.c | 2 +- posix-aio-compat.c | 3 ++- qemu-aio.h | 13 +++++++++++++ 5 files changed, 50 insertions(+), 6 deletions(-) diff --git a/aio.c b/aio.c index da18443..f164a47 100644 --- a/aio.c +++ b/aio.c @@ -33,6 +33,7 @@ struct AioHandler IOHandler *io_read; IOHandler *io_write; AioFlushHandler *io_flush; + AioProcessQueue *io_process_queue; int deleted; void *opaque; QLIST_ENTRY(AioHandler) node; @@ -55,6 +56,7 @@ int qemu_aio_set_fd_handler(int fd, IOHandler *io_read, IOHandler *io_write, AioFlushHandler *io_flush, + AioProcessQueue *io_process_queue, void *opaque) { AioHandler *node; @@ -87,6 +89,7 @@ int qemu_aio_set_fd_handler(int fd, node->io_read = io_read; node->io_write = io_write; node->io_flush = io_flush; + node->io_process_queue = io_process_queue; node->opaque = opaque; } @@ -115,6 +118,26 @@ void qemu_aio_flush(void) } while (qemu_bh_poll() || ret > 0); } +int qemu_aio_process_queue(void) +{ + AioHandler *node; + int ret = 0; + + walking_handlers = 1; + + QLIST_FOREACH(node, &aio_handlers, node) { + if (node->io_process_queue) { + if (node->io_process_queue(node->opaque)) { + ret = 1; + } + } + } + + walking_handlers = 0; + + return ret; +} + void qemu_aio_wait(void) { int ret; @@ -122,6 +145,13 @@ void qemu_aio_wait(void) if (qemu_bh_poll()) return; + /* + * If there are callbacks left that have been queued, we need to call then. + * Return afterwards to avoid waiting needlessly in select(). + */ + if (qemu_aio_process_queue()) + return; + do { AioHandler *node; fd_set rdfds, wrfds; diff --git a/block/curl.c b/block/curl.c index 3caa9be..5223ce8 100644 --- a/block/curl.c +++ b/block/curl.c @@ -83,17 +83,17 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action, dprintf("CURL (AIO): Sock action %d on fd %d\n", action, fd); switch (action) { case CURL_POLL_IN: - qemu_aio_set_fd_handler(fd, curl_multi_do, NULL, NULL, s); + qemu_aio_set_fd_handler(fd, curl_multi_do, NULL, NULL, NULL, s); break; case CURL_POLL_OUT: - qemu_aio_set_fd_handler(fd, NULL, curl_multi_do, NULL, s); + qemu_aio_set_fd_handler(fd, NULL, curl_multi_do, NULL, NULL, s); break; case CURL_POLL_INOUT: qemu_aio_set_fd_handler(fd, curl_multi_do, - curl_multi_do, NULL, s); + curl_multi_do, NULL, NULL, s); break; case CURL_POLL_REMOVE: - qemu_aio_set_fd_handler(fd, NULL, NULL, NULL, NULL); + qemu_aio_set_fd_handler(fd, NULL, NULL, NULL, NULL, NULL); break; } diff --git a/linux-aio.c b/linux-aio.c index f53a08c..19ad36d 100644 --- a/linux-aio.c +++ b/linux-aio.c @@ -192,7 +192,7 @@ void *laio_init(void) goto out_close_efd; qemu_aio_set_fd_handler(s->efd, qemu_laio_completion_cb, - NULL, qemu_laio_flush_cb, s); + NULL, qemu_laio_flush_cb, NULL, s); return s; diff --git a/posix-aio-compat.c b/posix-aio-compat.c index e9f789c..4901539 100644 --- a/posix-aio-compat.c +++ b/posix-aio-compat.c @@ -624,7 +624,8 @@ void *paio_init(void) fcntl(s->rfd, F_SETFL, O_NONBLOCK); fcntl(s->wfd, F_SETFL, O_NONBLOCK); - qemu_aio_set_fd_handler(s->rfd, posix_aio_read, NULL, posix_aio_flush, s); + qemu_aio_set_fd_handler(s->rfd, posix_aio_read, NULL, posix_aio_flush, + posix_aio_process_queue, s); ret = pthread_attr_init(&attr); if (ret) diff --git a/qemu-aio.h b/qemu-aio.h index f262344..3bdd749 100644 --- a/qemu-aio.h +++ b/qemu-aio.h @@ -20,6 +20,11 @@ /* Returns 1 if there are still outstanding AIO requests; 0 otherwise */ typedef int (AioFlushHandler)(void *opaque); +/* Runs all currently allowed AIO callbacks of completed requests in the + * respective AIO backend. Returns 0 if no requests was handled, non-zero + * if at least one queued request was handled. */ +typedef int (AioProcessQueue)(void *opaque); + /* Flush any pending AIO operation. This function will block until all * outstanding AIO operations have been completed or cancelled. */ void qemu_aio_flush(void); @@ -30,6 +35,13 @@ void qemu_aio_flush(void); * result of executing I/O completion or bh callbacks. */ void qemu_aio_wait(void); +/* + * Runs all currently allowed AIO callbacks of completed requests. Returns 0 + * if no requests were handled, non-zero if at least one request was + * processed. + */ +int qemu_aio_process_queue(void); + /* Register a file descriptor and associated callbacks. Behaves very similarly * to qemu_set_fd_handler2. Unlike qemu_set_fd_handler2, these callbacks will * be invoked when using either qemu_aio_wait() or qemu_aio_flush(). @@ -41,6 +53,7 @@ int qemu_aio_set_fd_handler(int fd, IOHandler *io_read, IOHandler *io_write, AioFlushHandler *io_flush, + AioProcessQueue *io_process_queue, void *opaque); #endif