From patchwork Mon Aug 1 14:23:02 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anthony Liguori X-Patchwork-Id: 107764 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 1FFB2B7090 for ; Tue, 2 Aug 2011 00:47:32 +1000 (EST) Received: from localhost ([::1]:47480 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QntPq-0003RT-Mv for incoming@patchwork.ozlabs.org; Mon, 01 Aug 2011 10:24:22 -0400 Received: from eggs.gnu.org ([140.186.70.92]:40706) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QntPN-0002Wy-70 for qemu-devel@nongnu.org; Mon, 01 Aug 2011 10:23:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QntPL-00057D-7u for qemu-devel@nongnu.org; Mon, 01 Aug 2011 10:23:53 -0400 Received: from e9.ny.us.ibm.com ([32.97.182.139]:41418) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QntPL-000573-58 for qemu-devel@nongnu.org; Mon, 01 Aug 2011 10:23:51 -0400 Received: from d01relay05.pok.ibm.com (d01relay05.pok.ibm.com [9.56.227.237]) by e9.ny.us.ibm.com (8.14.4/8.13.1) with ESMTP id p71Dp4AW015516 for ; Mon, 1 Aug 2011 09:51:04 -0400 Received: from d01av03.pok.ibm.com (d01av03.pok.ibm.com [9.56.224.217]) by d01relay05.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p71ENnKN100450 for ; Mon, 1 Aug 2011 10:23:50 -0400 Received: from d01av03.pok.ibm.com (loopback [127.0.0.1]) by d01av03.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p71AN6Yg017126 for ; Mon, 1 Aug 2011 07:23:06 -0300 Received: from titi.austin.rr.com (sig-9-76-195-114.mts.ibm.com [9.76.195.114]) by d01av03.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id p71AN0qD016760; Mon, 1 Aug 2011 07:23:05 -0300 From: Anthony Liguori To: qemu-devel@nongnu.org Date: Mon, 1 Aug 2011 09:23:02 -0500 Message-Id: <1312208590-25502-5-git-send-email-aliguori@us.ibm.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1312208590-25502-1-git-send-email-aliguori@us.ibm.com> References: <1312208590-25502-1-git-send-email-aliguori@us.ibm.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) X-Received-From: 32.97.182.139 Cc: Amit Shah , Hans de Goede , Anthony Liguori Subject: [Qemu-devel] [PATCH 04/12] char: introduce backend tx queue X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org While the front tx queue has no flow control, the backend tx queue uses a polling function to determine when the front end can receive data. To convert this to the new queue model, we simply try to flush the backend tx queue whenever we poll. We then return the remaining space in the queue as the value of the polling function. Signed-off-by: Anthony Liguori --- qemu-char.c | 49 ++++++++++++++++++++++++++++++++++++++++--------- qemu-char.h | 3 ++- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index 3f9b32c..2746652 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -173,6 +173,11 @@ static size_t char_queue_read(CharQueue *q, void *data, size_t size) return i; } +static uint32_t char_queue_get_avail(CharQueue *q) +{ + return sizeof(q->ring) - (q->prod - q->cons); +} + static void qemu_chr_flush_fe_tx(CharDriverState *s) { uint8_t buf[MAX_CHAR_QUEUE_RING]; @@ -200,23 +205,49 @@ int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len) return ret; } -int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg) +static void qemu_chr_flush_be_tx(CharDriverState *s) { - if (!s->chr_ioctl) - return -ENOTSUP; - return s->chr_ioctl(s, cmd, arg); + uint8_t buf[MAX_CHAR_QUEUE_RING]; + int len; + + /* Only drain what the be can handle */ + len = s->chr_can_read(s->handler_opaque); + if (len == 0) { + return; + } + + len = char_queue_read(&s->be_tx, buf, len); + + /* We only drained what we knew the be could handle so we don't need to + * requeue any data. */ + s->chr_read(s, buf, len); } int qemu_chr_be_can_write(CharDriverState *s) { - if (!s->chr_can_read) - return 0; - return s->chr_can_read(s->handler_opaque); + /* Try to flush any queued data before returning how much data we can + * accept. */ + qemu_chr_flush_be_tx(s); + + return char_queue_get_avail(&s->be_tx); } -void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len) +int qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len) { - s->chr_read(s->handler_opaque, buf, len); + int ret; + + ret = char_queue_write(&s->be_tx, buf, len); + + qemu_chr_flush_be_tx(s); + + return ret; +} + +int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg) +{ + if (!s->chr_ioctl) + return -ENOTSUP; + return s->chr_ioctl(s, cmd, arg); } int qemu_chr_get_msgfd(CharDriverState *s) diff --git a/qemu-char.h b/qemu-char.h index bb9c1a7..85735b5 100644 --- a/qemu-char.h +++ b/qemu-char.h @@ -85,6 +85,7 @@ struct CharDriverState { int avail_connections; CharQueue fe_tx; + CharQueue be_tx; QTAILQ_ENTRY(CharDriverState) next; }; @@ -109,7 +110,7 @@ void qemu_chr_add_handlers(CharDriverState *s, int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg); void qemu_chr_generic_open(CharDriverState *s); int qemu_chr_be_can_write(CharDriverState *s); -void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len); +int qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len); int qemu_chr_get_msgfd(CharDriverState *s); void qemu_chr_accept_input(CharDriverState *s); int qemu_chr_add_client(CharDriverState *s, int fd);