From patchwork Tue Oct 27 18:16:36 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark McLoughlin X-Patchwork-Id: 37020 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 A6B04B7BB9 for ; Wed, 28 Oct 2009 05:25:20 +1100 (EST) Received: from localhost ([127.0.0.1]:49183 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N2qjN-0007jX-P9 for incoming@patchwork.ozlabs.org; Tue, 27 Oct 2009 14:25:17 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1N2qdH-0004Y7-Kc for qemu-devel@nongnu.org; Tue, 27 Oct 2009 14:18:59 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1N2qdC-0004VR-FV for qemu-devel@nongnu.org; Tue, 27 Oct 2009 14:18:58 -0400 Received: from [199.232.76.173] (port=37356 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N2qdC-0004VG-BW for qemu-devel@nongnu.org; Tue, 27 Oct 2009 14:18:54 -0400 Received: from mx1.redhat.com ([209.132.183.28]:27184) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1N2qdA-0000eS-Nb for qemu-devel@nongnu.org; Tue, 27 Oct 2009 14:18:54 -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 n9RIIax1023232; Tue, 27 Oct 2009 14:18:36 -0400 Received: from blaa.localdomain (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx04.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id n9RIIYfW009013; Tue, 27 Oct 2009 14:18:35 -0400 Received: by blaa.localdomain (Postfix, from userid 500) id 884D6F33E; Tue, 27 Oct 2009 18:16:39 +0000 (GMT) From: Mark McLoughlin To: qemu-devel@nongnu.org Date: Tue, 27 Oct 2009 18:16:36 +0000 Message-Id: <1256667399-3149-3-git-send-email-markmc@redhat.com> In-Reply-To: <1256667399-3149-1-git-send-email-markmc@redhat.com> References: <1256667399-3149-1-git-send-email-markmc@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: Sven Rudolph , Scott Tsai , Mark McLoughlin Subject: [Qemu-devel] [PATCH 2/5] net: disable receiving if client returns zero 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 If a receiver returns zero, that means its queue is full and it will notify us when room is available using qemu_flush_queued_packets(). Take note of that and disable that receiver until it flushes its queue. This is a first step towards allowing can_receive() handlers to return true even if no buffer space is available. Signed-off-by: Mark McLoughlin --- net.c | 49 ++++++++++++++++++++++++++++++++++++++----------- net.h | 1 + 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/net.c b/net.c index 661bbc1..9dea615 100644 --- a/net.c +++ b/net.c @@ -423,11 +423,13 @@ int qemu_can_send_packet(VLANClientState *sender) VLANClientState *vc; if (sender->peer) { - if (!sender->peer->can_receive || - sender->peer->can_receive(sender->peer)) { - return 1; - } else { + if (sender->peer->receive_disabled) { return 0; + } else if (sender->peer->can_receive && + !sender->peer->can_receive(sender->peer)) { + return 0; + } else { + return 1; } } @@ -455,15 +457,27 @@ static ssize_t qemu_deliver_packet(VLANClientState *sender, void *opaque) { VLANClientState *vc = opaque; + ssize_t ret; if (vc->link_down) { return size; } - if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->receive_raw) - return vc->receive_raw(vc, data, size); - else - return vc->receive(vc, data, size); + if (vc->receive_disabled) { + return 0; + } + + if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->receive_raw) { + ret = vc->receive_raw(vc, data, size); + } else { + ret = vc->receive(vc, data, size); + } + + if (ret == 0) { + vc->receive_disabled = 1; + }; + + return ret; } static ssize_t qemu_vlan_deliver_packet(VLANClientState *sender, @@ -474,7 +488,7 @@ static ssize_t qemu_vlan_deliver_packet(VLANClientState *sender, { VLANState *vlan = opaque; VLANClientState *vc; - int ret = -1; + ssize_t ret = -1; QTAILQ_FOREACH(vc, &vlan->clients, next) { ssize_t len; @@ -488,12 +502,23 @@ static ssize_t qemu_vlan_deliver_packet(VLANClientState *sender, continue; } - if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->receive_raw) + if (vc->receive_disabled) { + ret = 0; + continue; + } + + if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->receive_raw) { len = vc->receive_raw(vc, buf, size); - else + } else { len = vc->receive(vc, buf, size); + } + + if (len == 0) { + vc->receive_disabled = 1; + } ret = (ret >= 0) ? ret : len; + } return ret; @@ -520,6 +545,8 @@ void qemu_flush_queued_packets(VLANClientState *vc) { NetQueue *queue; + vc->receive_disabled = 0; + if (vc->vlan) { queue = vc->vlan->send_queue; } else { diff --git a/net.h b/net.h index 8074c66..c1fe515 100644 --- a/net.h +++ b/net.h @@ -44,6 +44,7 @@ struct VLANClientState { char *model; char *name; char info_str[256]; + unsigned receive_disabled : 1; }; struct VLANState {