From patchwork Tue Jan 22 14:40:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Durrant X-Patchwork-Id: 10776171 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2B407746 for ; Tue, 22 Jan 2019 19:41:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1AA442B8D6 for ; Tue, 22 Jan 2019 19:41:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0E1D72B8D9; Tue, 22 Jan 2019 19:41:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.3 required=2.0 tests=BAYES_00,DATE_IN_PAST_03_06, MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9417D2B8D6 for ; Tue, 22 Jan 2019 19:41:17 +0000 (UTC) Received: from localhost ([127.0.0.1]:48093 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gm1vA-0007UB-K9 for patchwork-qemu-devel@patchwork.kernel.org; Tue, 22 Jan 2019 14:41:16 -0500 Received: from eggs.gnu.org ([209.51.188.92]:49684) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gm17h-0007L2-O8 for qemu-devel@nongnu.org; Tue, 22 Jan 2019 13:50:12 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gm17f-0007K4-W3 for qemu-devel@nongnu.org; Tue, 22 Jan 2019 13:50:09 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:13794) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gm17d-0007EA-TX for qemu-devel@nongnu.org; Tue, 22 Jan 2019 13:50:07 -0500 X-IronPort-AV: E=Sophos;i="5.56,506,1539648000"; d="scan'208";a="76137580" From: Paul Durrant To: , Date: Tue, 22 Jan 2019 14:40:28 +0000 Message-ID: <20190122144028.11518-1-paul.durrant@citrix.com> X-Mailer: git-send-email 2.20.1.2.gb21ebb6 MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PATCH] xen: fix xen-bus state model to allow frontend re-connection X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Anthony Perard , Paul Durrant , Stefano Stabellini Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP There is a flaw in the xen-bus state model. To allow a frontend to re- connect the backend state of an online XenDevice is transitioned from Closed to InitWait, but this is currently done unilaterally which is incorrect. The backend state should remain Closed until the frontend state transitions to Initialising. This patch removes the automatic backend state transition from xen_device_backend_state_changed() and, instead, adds an extra check in xen_device_frontend_state_changed() to determine whether a frontend is trying to re-connect to a previously Closed XenDevice. Only if this is found to be the case is the backend state transitioned from Closed to InitWait. Note that this transition will be common amongst all XenDevice classes and hence xen_device_frontend_state_changed() returns immediately afterwards without calling into the XenDeviceClass frontend_changed() method. Signed-off-by: Paul Durrant --- Cc: Stefano Stabellini Cc: Anthony Perard --- hw/xen/xen-bus.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c index 3aeccec69c..1b31a1dc50 100644 --- a/hw/xen/xen-bus.c +++ b/hw/xen/xen-bus.c @@ -547,20 +547,12 @@ static void xen_device_backend_changed(void *opaque) } /* - * If a backend is still 'online' then its state should be cycled - * back round to InitWait in order for a new frontend instance to - * connect. This may happen when, for example, a frontend driver is - * re-installed or updated. - * If a backend is not 'online' then the device should be destroyed. + * If a backend is still 'online' then we should leave it alone but, + * if a backend is not 'online', then the device should be destroyed + * once the state is Closed. */ - if (xendev->backend_online && + if (!xendev->backend_online && xendev->backend_state == XenbusStateClosed) { - xen_device_backend_set_state(xendev, XenbusStateInitWait); - } else if (!xendev->backend_online && - (xendev->backend_state == XenbusStateClosed || - xendev->backend_state == XenbusStateInitialising || - xendev->backend_state == XenbusStateInitWait || - xendev->backend_state == XenbusStateUnknown)) { Error *local_err = NULL; if (!xen_backend_try_device_destroy(xendev, &local_err)) { @@ -715,6 +707,17 @@ static void xen_device_frontend_changed(void *opaque) xen_device_frontend_set_state(xendev, state); + if (state == XenbusStateInitialising && + xendev->backend_state == XenbusStateClosed && + xendev->backend_online) { + /* + * The frontend is re-initializing so switch back to + * InitWait. + */ + xen_device_backend_set_state(xendev, XenbusStateInitWait); + return; + } + if (xendev_class->frontend_changed) { Error *local_err = NULL;