From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=49752 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OxjM8-0006aE-WF for qemu-devel@nongnu.org; Mon, 20 Sep 2010 12:36:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OxjM7-0006vZ-Lm for qemu-devel@nongnu.org; Mon, 20 Sep 2010 12:36:40 -0400 Received: from mx1.redhat.com ([209.132.183.28]:9345) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OxjM7-0006vQ-Ce for qemu-devel@nongnu.org; Mon, 20 Sep 2010 12:36:39 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o8KGacdp011545 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 20 Sep 2010 12:36:38 -0400 Received: from redhat.com (vpn-6-59.tlv.redhat.com [10.35.6.59]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with SMTP id o8KGaaEJ020099 for ; Mon, 20 Sep 2010 12:36:37 -0400 Date: Mon, 20 Sep 2010 18:30:42 +0200 From: "Michael S. Tsirkin" Message-ID: <20100920163042.GA29466@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Subject: [Qemu-devel] [PATCH] net: delay peer host device delete List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org With -netdev, virtio devices present offload features to guest, depending on the backend used. Thus, removing host ntedev peer while guest is active leads to guest-visible inconsistency and/or crashes. See e.g. https://bugzilla.redhat.com/show_bug.cgi?id=623735 As a solution, while guest (NIC) peer device exists, we must prevent the host peer from being deleted. This patch does this by adding peer_deleted flag in nic state: if host device is going away while guest device is around, set this flag and keep host device around for as long as guest device exists. Signed-off-by: Michael S. Tsirkin --- net.c | 21 ++++++++++++++++++++- net.h | 1 + 2 files changed, 21 insertions(+), 1 deletions(-) diff --git a/net.c b/net.c index 3d0fde7..10855d1 100644 --- a/net.c +++ b/net.c @@ -286,12 +286,31 @@ void qemu_del_vlan_client(VLANClientState *vc) if (vc->vlan) { QTAILQ_REMOVE(&vc->vlan->clients, vc, next); } else { + /* Even if client will not be deleted yet, remove it from list so it + * does not appear in monitor. */ + QTAILQ_REMOVE(&non_vlan_clients, vc, next); + /* Detect that guest-visible (NIC) peer is active, and delay deletion. + * */ + if (vc->peer && vc->peer->info->type == NET_CLIENT_TYPE_NIC) { + NICState *nic = DO_UPCAST(NICState, nc, vc->peer); + assert(!nic->peer_deleted); + nic->peer_deleted = true; + return; + } if (vc->send_queue) { qemu_del_net_queue(vc->send_queue); } - QTAILQ_REMOVE(&non_vlan_clients, vc, next); if (vc->peer) { vc->peer->peer = NULL; + /* If this is a guest-visible (NIC) device, + * and peer has already been removed from monitor, + * delete it here. */ + if (vc->info->type == NET_CLIENT_TYPE_NIC) { + NICState *nic = DO_UPCAST(NICState, nc, vc); + if (nic->peer_deleted) { + qemu_del_vlan_client(vc->peer); + } + } } } diff --git a/net.h b/net.h index 518cf9c..44c31a9 100644 --- a/net.h +++ b/net.h @@ -72,6 +72,7 @@ typedef struct NICState { VLANClientState nc; NICConf *conf; void *opaque; + bool peer_deleted; } NICState; struct VLANState { -- 1.7.2.2