From nobody Fri Apr 4 05:15:29 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=smartx.com ARC-Seal: i=1; a=rsa-sha256; t=1743520771; cv=none; d=zohomail.com; s=zohoarc; b=eHI8yKkSuQoNWIChlSmiZM6Vx8yWs3YuVMWKtWqgLtcRCZNIPtVKkhkOA1LWn/EhvPqGzwWeOwXyukLVA9if1fR0+A1CWzuSKJkiTNiH3TsJJ/3Umj61XPlFXK285kl+xN8TLF15VwMuAGXN7Jf9R8QIBXpNUL2JZy5Zbqsn0p0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1743520771; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=yqr3uR2LhGzaS3M6ZmJpQU2HECb2zzW7g8CYKFMP2vs=; b=nQJIXwO/8dZUu8BQvqsApfayEWmUYGvGVRxqTSy3c0x5S9VdPmWGwHNp0BAgFz8C8ibSQPlwtCw0FLn/MKbPVTUtc8iaIAUxIASlWDP6E6x7h1wueh6Ce+yUtyd++OyvVxOCQ9rHSQzPceMfCMPxG/jSRLGH0wl8wM/swFvE6IE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1743520771070717.6727339885441; Tue, 1 Apr 2025 08:19:31 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tzdO0-0005xh-Rl; Tue, 01 Apr 2025 11:18:44 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tzdNz-0005x5-AZ for qemu-devel@nongnu.org; Tue, 01 Apr 2025 11:18:43 -0400 Received: from mail-pl1-x630.google.com ([2607:f8b0:4864:20::630]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tzdNx-0005AI-4J for qemu-devel@nongnu.org; Tue, 01 Apr 2025 11:18:43 -0400 Received: by mail-pl1-x630.google.com with SMTP id d9443c01a7336-225477548e1so102415745ad.0 for ; Tue, 01 Apr 2025 08:18:40 -0700 (PDT) Received: from fedora.smartx.com ([2001:df0:a640:1::4]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2291eee029bsm90172195ad.62.2025.04.01.08.18.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 08:18:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=smartx-com.20230601.gappssmtp.com; s=20230601; t=1743520719; x=1744125519; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=yqr3uR2LhGzaS3M6ZmJpQU2HECb2zzW7g8CYKFMP2vs=; b=FOMsgFkHPITpn3zHKVGVAsb8gO6NLnP0hcl0LQFu+oahaYy9gEfEgAOlnJPkPNlQt3 0TzjAZONQFJmzNxfwQE1ffAd8z3QUKbPaDxboUArXwlxbpX/3Gn5QKBLOZl7/KPKzU1v /TYQR9CtK+5csr/dyV6P5JK/sGH1OSG6yK9zKIm1PcnDxDRCTzWwA2dbge8KtVzyEYFy 9ImFbS5fA2CG0Fl976eplPtddvzYPK5MfZ+jrAsDUYeCjr0V+3850MFHGbfYW7JFX706 O2AoF8UC0ZqF5U0fapbNzNkK10eHE2ctFQJKHpScbCzOkZRPECsMg0WanqMx9wS7PZkJ z/VA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743520719; x=1744125519; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=yqr3uR2LhGzaS3M6ZmJpQU2HECb2zzW7g8CYKFMP2vs=; b=sTTwmujgNlowVcH+qfmTqY80AwM+0QLFlP84SWuQBD32BEx8IvQUfx/0iAMrZa8YYj 5lCKQpP5A2rim7HhXj0jt8tuK/j9qQ01yfYaiHVu++cv0C/xnYk3001XnWDD4i3bUVWG ExRPBsDayDivQcoIR/o3fUebG8tsWkoi/iB4XmH5aQvlaYAYjOpCiAL45jW2FDc6o8Dq WXpTa+PhzsG0V/7v+gXB6JKzvcCNO134Zb/LmqJiebvUqB6R1KInRcZ5IEmWgLu4HH8i QyE/4hVaUpaTtSpn4d0ZUOjTHiSH8ZPHz+pLzFrYmQ0AT6/y6YCyZVzoEN22O9OjnlwM 54/g== X-Gm-Message-State: AOJu0YxPB6SVyKRKD6aGwgwaHIcbv38veT6iUX/+M2Ew9FPrkOxrZFCp uzLlvi17IytK3BE+QPy2ymLitHpgkYqlNdWcuNuk8i5mTp5mDltiA8sOkXjcS+yJI7hyxpxKDuY adBGE7w== X-Gm-Gg: ASbGncti2caqYxJ6qLR7K4KZPyXrFVru0cPfndzLqU9ZvgOyZ3Yx41VfGUGoosp905t Qql+iugKMuCqKrtXV0pTu/74fcXIYKi5uX7+Xi2HNZhhUUiaFb9YLqr3vt+UFogw0sE7FH5ApIW L3qS7sctpqKwymTxGiWzGvsZoCbB8rJN0ztv86xH7QInlu5/lkn5Ed+jYm3SQI3DLkuWmA89iXn HI9MZPp74dZ4grAg7vVJh8WTr2pJREY7Yi6vJpw7n5iZ9GCDiZnbPxEh5OORErKqfBOvlvg+jPD SevUhxUXPCY2yv4EE1nPGeHonyukZXg= X-Google-Smtp-Source: AGHT+IGLCwIEFPWFTsXgr+b/uP3mRmZx/L6BlK/7rG7reCmcerd0GQWnFAF3Rw5ak85a306kQGmSsw== X-Received: by 2002:a17:902:ccca:b0:225:b718:4dff with SMTP id d9443c01a7336-2292fa075efmr250857465ad.53.1743520719183; Tue, 01 Apr 2025 08:18:39 -0700 (PDT) From: Haoqian He To: qemu-devel@nongnu.org, sgarzare@redhat.com, mst@redhat.com, raphael@enfabrica.net Cc: fengli@smartx.com, yuhua@smartx.com, Kevin Wolf , Hanna Reitz , Stefan Hajnoczi , Laurent Vivier , Amit Shah , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , Paolo Bonzini , Gerd Hoffmann , Jason Wang , Fam Zheng , Alex Williamson , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , =?UTF-8?q?Alex=20Benn=C3=A9e?= , mzamazal@redhat.com (reviewer:vhost-user-scmi), David Hildenbrand , "Gonglei (Arei)" , Eric Auger , Richard Henderson , qemu-block@nongnu.org (open list:Block layer core), virtio-fs@lists.linux.dev (open list:virtiofs) Subject: [PATCH v4 1/3] system/runstate: add VM state change cb with return value Date: Tue, 1 Apr 2025 11:18:15 -0400 Message-ID: <20250401151819.1526461-2-haoqian.he@smartx.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20250401151819.1526461-1-haoqian.he@smartx.com> References: <20250327064348.3595732-1-haoqian.he@smartx.com> <20250401151819.1526461-1-haoqian.he@smartx.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::630; envelope-from=haoqian.he@smartx.com; helo=mail-pl1-x630.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @smartx-com.20230601.gappssmtp.com) X-ZM-MESSAGEID: 1743520773020019100 Content-Type: text/plain; charset="utf-8" This patch adds the new VM state change cb type `VMChangeStateHandlerWithRe= t`, which has return value for `VMChangeStateEntry`. Thus, we can register a new VM state change cb with return value for device. Note that `VMChangeStateHandler` and `VMChangeStateHandlerWithRet` are mutu= ally exclusive and cannot be provided at the same time. This patch is the pre patch for 'vhost-user: return failure if backend cras= hes when live migration', which makes the live migration aware of the loss of connection with the vhost-user backend and aborts the live migration. Virtio device will use VMChangeStateHandlerWithRet. Signed-off-by: Haoqian He --- hw/block/virtio-blk.c | 2 +- hw/core/vm-change-state-handler.c | 18 ++++++++++------ hw/scsi/scsi-bus.c | 2 +- hw/vfio/migration.c | 2 +- hw/virtio/virtio.c | 2 +- include/system/runstate.h | 13 +++++++++--- system/cpus.c | 8 +++++-- system/runstate.c | 35 ++++++++++++++++++++++++++----- 8 files changed, 62 insertions(+), 20 deletions(-) diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index 5135b4d8f1..4a48a16790 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -1928,7 +1928,7 @@ static void virtio_blk_device_realize(DeviceState *de= v, Error **errp) * called after ->start_ioeventfd() has already set blk's AioContext. */ s->change =3D - qdev_add_vm_change_state_handler(dev, virtio_blk_dma_restart_cb, s= ); + qdev_add_vm_change_state_handler(dev, virtio_blk_dma_restart_cb, N= ULL, s); =20 blk_ram_registrar_init(&s->blk_ram_registrar, s->blk); blk_set_dev_ops(s->blk, &virtio_block_ops, s); diff --git a/hw/core/vm-change-state-handler.c b/hw/core/vm-change-state-ha= ndler.c index 7064995578..99c642b558 100644 --- a/hw/core/vm-change-state-handler.c +++ b/hw/core/vm-change-state-handler.c @@ -40,6 +40,7 @@ static int qdev_get_dev_tree_depth(DeviceState *dev) * qdev_add_vm_change_state_handler: * @dev: the device that owns this handler * @cb: the callback function to be invoked + * @cb_ret: the callback function with return value to be invoked * @opaque: user data passed to the callback function * * This function works like qemu_add_vm_change_state_handler() except call= backs @@ -50,25 +51,30 @@ static int qdev_get_dev_tree_depth(DeviceState *dev) * controller's callback is invoked before the children on its bus when th= e VM * starts running. The order is reversed when the VM stops running. * + * Note that the parameter `cb` and `cb_ret` are mutually exclusive. + * * Returns: an entry to be freed with qemu_del_vm_change_state_handler() */ VMChangeStateEntry *qdev_add_vm_change_state_handler(DeviceState *dev, VMChangeStateHandler = *cb, + VMChangeStateHandlerW= ithRet *cb_ret, void *opaque) { - return qdev_add_vm_change_state_handler_full(dev, cb, NULL, opaque); + assert(!cb || !cb_ret); + return qdev_add_vm_change_state_handler_full(dev, cb, NULL, cb_ret, op= aque); } =20 /* * Exactly like qdev_add_vm_change_state_handler() but passes a prepare_cb - * argument too. + * and the cb_ret arguments too. */ VMChangeStateEntry *qdev_add_vm_change_state_handler_full( - DeviceState *dev, VMChangeStateHandler *cb, - VMChangeStateHandler *prepare_cb, void *opaque) + DeviceState *dev, VMChangeStateHandler *cb, VMChangeStateHandler *prep= are_cb, + VMChangeStateHandlerWithRet *cb_ret, void *opaque) { int depth =3D qdev_get_dev_tree_depth(dev); =20 - return qemu_add_vm_change_state_handler_prio_full(cb, prepare_cb, opaq= ue, - depth); + assert(!cb || !cb_ret); + return qemu_add_vm_change_state_handler_prio_full(cb, prepare_cb, cb_r= et, + opaque, depth); } diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index 7d4546800f..ec098f5f0a 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -356,7 +356,7 @@ static void scsi_qdev_realize(DeviceState *qdev, Error = **errp) return; } dev->vmsentry =3D qdev_add_vm_change_state_handler(DEVICE(dev), - scsi_dma_restart_cb, dev); + scsi_dma_restart_cb, NULL, dev); } =20 static void scsi_qdev_unrealize(DeviceState *qdev) diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c index 416643ddd6..f531db83ea 100644 --- a/hw/vfio/migration.c +++ b/hw/vfio/migration.c @@ -1015,7 +1015,7 @@ static int vfio_migration_init(VFIODevice *vbasedev) vfio_vmstate_change_prepare : NULL; migration->vm_state =3D qdev_add_vm_change_state_handler_full( - vbasedev->dev, vfio_vmstate_change, prepare_cb, vbasedev); + vbasedev->dev, vfio_vmstate_change, prepare_cb, NULL, vbasedev); migration_add_notifier(&migration->migration_state, vfio_migration_state_notifier); =20 diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 85110bce37..202a052053 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -3489,7 +3489,7 @@ void virtio_init(VirtIODevice *vdev, uint16_t device_= id, size_t config_size) vdev->config =3D NULL; } vdev->vmstate =3D qdev_add_vm_change_state_handler(DEVICE(vdev), - virtio_vmstate_change, vdev); + virtio_vmstate_change, NULL, vdev); vdev->device_endian =3D virtio_default_endian(); vdev->use_guest_notifier_mask =3D true; } diff --git a/include/system/runstate.h b/include/system/runstate.h index bffc3719d4..fdd5c4a517 100644 --- a/include/system/runstate.h +++ b/include/system/runstate.h @@ -12,6 +12,7 @@ bool runstate_needs_reset(void); void runstate_replay_enable(void); =20 typedef void VMChangeStateHandler(void *opaque, bool running, RunState sta= te); +typedef int VMChangeStateHandlerWithRet(void *opaque, bool running, RunSta= te state); =20 VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler = *cb, void *opaque); @@ -20,21 +21,27 @@ VMChangeStateEntry *qemu_add_vm_change_state_handler_pr= io( VMChangeStateEntry * qemu_add_vm_change_state_handler_prio_full(VMChangeStateHandler *cb, VMChangeStateHandler *prepare_c= b, + VMChangeStateHandlerWithRet *cb= _ret, void *opaque, int priority); VMChangeStateEntry *qdev_add_vm_change_state_handler(DeviceState *dev, VMChangeStateHandler = *cb, + VMChangeStateHandlerW= ithRet *cb_ret, void *opaque); VMChangeStateEntry *qdev_add_vm_change_state_handler_full( - DeviceState *dev, VMChangeStateHandler *cb, - VMChangeStateHandler *prepare_cb, void *opaque); + DeviceState *dev, VMChangeStateHandler *cb, VMChangeStateHandler *prep= are_cb, + VMChangeStateHandlerWithRet *cb_ret, void *opaque); void qemu_del_vm_change_state_handler(VMChangeStateEntry *e); /** * vm_state_notify: Notify the state of the VM * * @running: whether the VM is running or not. * @state: the #RunState of the VM. + * + * Return the result of the callback which has return value. + * If no callback has return value, still return 0 and the + * upper layer should not do additional processing. */ -void vm_state_notify(bool running, RunState state); +int vm_state_notify(bool running, RunState state); =20 static inline bool shutdown_caused_by_guest(ShutdownCause cause) { diff --git a/system/cpus.c b/system/cpus.c index 2cc5f887ab..d16b0dff98 100644 --- a/system/cpus.c +++ b/system/cpus.c @@ -299,14 +299,18 @@ static int do_vm_stop(RunState state, bool send_stop) if (oldstate =3D=3D RUN_STATE_RUNNING) { pause_all_vcpus(); } - vm_state_notify(0, state); + ret =3D vm_state_notify(0, state); if (send_stop) { qapi_event_send_stop(); } } =20 bdrv_drain_all(); - ret =3D bdrv_flush_all(); + /* + * Even if vm_state_notify() return failure, + * it would be better to flush as before. + */ + ret |=3D bdrv_flush_all(); trace_vm_stop_flush_all(ret); =20 return ret; diff --git a/system/runstate.c b/system/runstate.c index 272801d307..de74d962bc 100644 --- a/system/runstate.c +++ b/system/runstate.c @@ -297,6 +297,7 @@ void qemu_system_vmstop_request(RunState state) struct VMChangeStateEntry { VMChangeStateHandler *cb; VMChangeStateHandler *prepare_cb; + VMChangeStateHandlerWithRet *cb_ret; void *opaque; QTAILQ_ENTRY(VMChangeStateEntry) entries; int priority; @@ -320,14 +321,15 @@ static QTAILQ_HEAD(, VMChangeStateEntry) vm_change_st= ate_head =3D VMChangeStateEntry *qemu_add_vm_change_state_handler_prio( VMChangeStateHandler *cb, void *opaque, int priority) { - return qemu_add_vm_change_state_handler_prio_full(cb, NULL, opaque, - priority); + return qemu_add_vm_change_state_handler_prio_full(cb, NULL, NULL, + opaque, priority); } =20 /** * qemu_add_vm_change_state_handler_prio_full: * @cb: the main callback to invoke * @prepare_cb: a callback to invoke before the main callback + * @cb_ret: the main callback to invoke with return value * @opaque: user data passed to the callbacks * @priority: low priorities execute first when the vm runs and the revers= e is * true when the vm stops @@ -344,6 +346,7 @@ VMChangeStateEntry *qemu_add_vm_change_state_handler_pr= io( VMChangeStateEntry * qemu_add_vm_change_state_handler_prio_full(VMChangeStateHandler *cb, VMChangeStateHandler *prepare_c= b, + VMChangeStateHandlerWithRet *cb= _ret, void *opaque, int priority) { VMChangeStateEntry *e; @@ -352,6 +355,7 @@ qemu_add_vm_change_state_handler_prio_full(VMChangeStat= eHandler *cb, e =3D g_malloc0(sizeof(*e)); e->cb =3D cb; e->prepare_cb =3D prepare_cb; + e->cb_ret =3D cb_ret; e->opaque =3D opaque; e->priority =3D priority; =20 @@ -379,9 +383,10 @@ void qemu_del_vm_change_state_handler(VMChangeStateEnt= ry *e) g_free(e); } =20 -void vm_state_notify(bool running, RunState state) +int vm_state_notify(bool running, RunState state) { VMChangeStateEntry *e, *next; + int ret =3D 0; =20 trace_vm_state_notify(running, state, RunState_str(state)); =20 @@ -393,7 +398,17 @@ void vm_state_notify(bool running, RunState state) } =20 QTAILQ_FOREACH_SAFE(e, &vm_change_state_head, entries, next) { - e->cb(e->opaque, running, state); + if (e->cb) { + e->cb(e->opaque, running, state); + } else if (e->cb_ret) { + /* + * Here ignore the return value of cb_ret because + * we only care about the stopping the device during + * the VM live migration to indicate whether the + * connection between qemu and backend is normal. + */ + e->cb_ret(e->opaque, running, state); + } } } else { QTAILQ_FOREACH_REVERSE_SAFE(e, &vm_change_state_head, entries, nex= t) { @@ -403,9 +418,19 @@ void vm_state_notify(bool running, RunState state) } =20 QTAILQ_FOREACH_REVERSE_SAFE(e, &vm_change_state_head, entries, nex= t) { - e->cb(e->opaque, running, state); + if (e->cb) { + e->cb(e->opaque, running, state); + } else if (e->cb_ret) { + /* + * We should execute all registered callbacks even if + * one of them returns failure, otherwise, some cleanup + * work of the device will be skipped. + */ + ret |=3D e->cb_ret(e->opaque, running, state); + } } } + return ret; } =20 static ShutdownCause reset_requested; --=20 2.44.0 From nobody Fri Apr 4 05:15:29 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=smartx.com ARC-Seal: i=1; a=rsa-sha256; t=1743520832; cv=none; d=zohomail.com; s=zohoarc; b=HdANsFJnRW8Ic5JpwvPM4QWa+/UplI52lAthjiIClZkh5CY54H1NztG3haCUMH9MO5AfT/Fw2rAxYip6LLx1MKmYyQgEmIZIwzjK6D98yA367NycxKE0yDnhX6JeRUcYh7Xxc/F6snF1XzSmeoN93uBdw2IzzleHTtkAHX/rH+Q= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1743520831; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=4NXX1X4hRiRNZUknx8LsP9b/fPPtl0kWy3TtPAhKCeU=; b=GAPSNQ09fmNA3dEfIfZv2qR/rCEGM1H4J8VCdM7ScdsirglQ2WqW3sy+R8Jo7Ya4XT20I3CzKS0daCUif8qLURAg+TNoduMvCr1obER7SJmPdHixmiuixzmV/7S/jRHOdMmWCSQCYP6oEGntdpJ3+U9eHgEuG/DTK/0XuOUhzfw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1743520831941876.1239282717684; Tue, 1 Apr 2025 08:20:31 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tzdOc-0006E2-Tm; Tue, 01 Apr 2025 11:19:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tzdO7-0005yn-Cl for qemu-devel@nongnu.org; Tue, 01 Apr 2025 11:18:55 -0400 Received: from mail-pj1-x1031.google.com ([2607:f8b0:4864:20::1031]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tzdO4-0005Aa-4t for qemu-devel@nongnu.org; Tue, 01 Apr 2025 11:18:51 -0400 Received: by mail-pj1-x1031.google.com with SMTP id 98e67ed59e1d1-300fefb8e06so9269324a91.0 for ; Tue, 01 Apr 2025 08:18:47 -0700 (PDT) Received: from fedora.smartx.com ([2001:df0:a640:1::4]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2291eee029bsm90172195ad.62.2025.04.01.08.18.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 08:18:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=smartx-com.20230601.gappssmtp.com; s=20230601; t=1743520726; x=1744125526; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=4NXX1X4hRiRNZUknx8LsP9b/fPPtl0kWy3TtPAhKCeU=; b=THshtjMS56Ub/nZ829BiNQIPs1F+ArYlAkmLEinZOzLTwM5OHZ5TsI7NhtdhkmlLde OlzEjL+UB+pJsZj/nAWwUQwpN9RLxfzU71vvm5jVJp5seH/WL14UqUswJdo03dJ3McaL zM+QNtFfQFg4fHzm9z4nn7/CyzyGega6WsscuyCt91NLh2EJHKYF/Jo8qp6NFjHtYj+Z FnrWM82eDW4xGlEqWQRfyW77bDGVhA4NxwbeihpuhkzteL7U9Fqppu7vc3oHFboD/BJW f0PnxuoVutpUKVbUMz0CHpiJuSDCmF18TudJdHjsJ8nWxgDRi+jFwORd41yzagSEct/H 6a9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743520726; x=1744125526; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=4NXX1X4hRiRNZUknx8LsP9b/fPPtl0kWy3TtPAhKCeU=; b=gsLFxpXcnWz8//E5Zb+mLNoNydSScVK1EYLhOfG3yUOSoerT/GpGvRkWiGQCwfQc+Y +A0ZBtLzBTJ8NPlRRGA+9c7N8Rv2XYXvhBZZiV9w/joc+iL7YdgkK5+lA6I13EzqRhFG r4HnnokEzBmSkiVOQKtvMzak+Fi2m307tzDXfm4wuzCtcHwfn8VMBqeT9MBEhlX0kJJB bCDzh30BXHS/Ikem2jM2y7Oot82+Kg+OYZXe0izIfpD0vMuMOD0zdQCWIB4FwlVhzHmR rAeHwidpAuV+XxuWDmN7ARb8V4s8BEhtDy6tJxApOpkZtQJ15W7NDYHfQfmT2q3c9uCL DSKQ== X-Gm-Message-State: AOJu0YwwJRPu9MV6exuglx7SwV1VkLx0+zyo6COxy9oxf2A2wP2rmkI2 TYzpguW39vTUnsZbEbS73Q7oz0RKXDLXdEmfgccWoYyWSoAbIvbBRncpZKQVQYskMFd1PrVVgHZ /vmvFJQ== X-Gm-Gg: ASbGncuKXxTK2oQjhRMzjtu9PdbqgcNetmoHsc1I8C12dD1BX+YfS55OhLinVofS6MS NCvkjrdF/16XlhHpVcVotGlx987dGt+bzE21V18YBUkUATP6PkjQm+H/xid5jC3HxV/NDz5ss03 Vq6v6WaG1Mrg8DZhGHqhW0bKEcWmEwhauwnzODUKDf68FLWF9OR91hUA/T+7d8Y2eVXFDqgfHF8 3nS2/z7ub0JGvPXoJJPbC5AZNqBpCAGUbcLWOO4+IbnfLjVs8Zc8aoENlnTX7xMmk4/ANzR0kQ1 SJnI3+Glrdp+irQVq1xvGCAY9WQ3ZMI= X-Google-Smtp-Source: AGHT+IFtnBfm3iEUuKkmkY4Wgfbu6YeM2h6VlJT3NVowOQMfk4p479pWxi+aoJAGqxAnh7LQT7UBvw== X-Received: by 2002:a17:90b:5446:b0:2f9:c139:b61f with SMTP id 98e67ed59e1d1-305608793e6mr6498428a91.14.1743520726364; Tue, 01 Apr 2025 08:18:46 -0700 (PDT) From: Haoqian He To: qemu-devel@nongnu.org, sgarzare@redhat.com, mst@redhat.com, raphael@enfabrica.net Cc: fengli@smartx.com, yuhua@smartx.com, Kevin Wolf , Hanna Reitz , Stefan Hajnoczi , Laurent Vivier , Amit Shah , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , Paolo Bonzini , Gerd Hoffmann , Jason Wang , Fam Zheng , Alex Williamson , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , =?UTF-8?q?Alex=20Benn=C3=A9e?= , mzamazal@redhat.com (reviewer:vhost-user-scmi), David Hildenbrand , "Gonglei (Arei)" , Eric Auger , Richard Henderson , qemu-block@nongnu.org (open list:Block layer core), virtio-fs@lists.linux.dev (open list:virtiofs) Subject: [PATCH v4 2/3] vhost: return failure if stop virtqueue failed in vhost_dev_stop Date: Tue, 1 Apr 2025 11:18:16 -0400 Message-ID: <20250401151819.1526461-3-haoqian.he@smartx.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20250401151819.1526461-1-haoqian.he@smartx.com> References: <20250327064348.3595732-1-haoqian.he@smartx.com> <20250401151819.1526461-1-haoqian.he@smartx.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::1031; envelope-from=haoqian.he@smartx.com; helo=mail-pj1-x1031.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @smartx-com.20230601.gappssmtp.com) X-ZM-MESSAGEID: 1743520834253019000 Content-Type: text/plain; charset="utf-8" This patch captures the error of vhost_virtqueue_stop() in vhost_dev_stop() and returns the error upward. Specifically, if QEMU is disconnected from the vhost backend, some actions in vhost_dev_stop() will fail, such as sending vhost-user messages to the backend (GET_VRING_BASE, SET_VRING_ENABLE) and vhost_reset_status. Considering that both set_vring_enable and vhost_reset_status require setti= ng the specific virtio feature bit, we can capture vhost_virtqueue_stop()'s error to indicate that QEMU has lost connection with the backend. This patch is the pre patch for 'vhost-user: return failure if backend cras= hes when live migration', which makes the live migration aware of the loss of connection with the vhost-user backend and aborts the live migration. Signed-off-by: Haoqian He --- hw/virtio/vhost.c | 23 +++++++++++++---------- include/hw/virtio/vhost.h | 8 +++++--- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index 6aa72fd434..bdd945c18d 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -1368,10 +1368,10 @@ fail_alloc_desc: return r; } =20 -void vhost_virtqueue_stop(struct vhost_dev *dev, - struct VirtIODevice *vdev, - struct vhost_virtqueue *vq, - unsigned idx) +int vhost_virtqueue_stop(struct vhost_dev *dev, + struct VirtIODevice *vdev, + struct vhost_virtqueue *vq, + unsigned idx) { int vhost_vq_index =3D dev->vhost_ops->vhost_get_vq_index(dev, idx); struct vhost_vring_state state =3D { @@ -1381,7 +1381,7 @@ void vhost_virtqueue_stop(struct vhost_dev *dev, =20 if (virtio_queue_get_desc_addr(vdev, idx) =3D=3D 0) { /* Don't stop the virtqueue which might have not been started */ - return; + return 0; } =20 r =3D dev->vhost_ops->vhost_get_vring_base(dev, &state); @@ -1412,6 +1412,7 @@ void vhost_virtqueue_stop(struct vhost_dev *dev, 0, virtio_queue_get_avail_size(vdev, idx)); vhost_memory_unmap(dev, vq->desc, virtio_queue_get_desc_size(vdev, idx= ), 0, virtio_queue_get_desc_size(vdev, idx)); + return r; } =20 static int vhost_virtqueue_set_busyloop_timeout(struct vhost_dev *dev, @@ -2136,9 +2137,10 @@ fail_features: } =20 /* Host notifiers must be enabled at this point. */ -void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vring= s) +int vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings) { int i; + int rc =3D 0; =20 /* should only be called after backend is connected */ assert(hdev->vhost_ops); @@ -2157,10 +2159,10 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIOD= evice *vdev, bool vrings) vhost_dev_set_vring_enable(hdev, false); } for (i =3D 0; i < hdev->nvqs; ++i) { - vhost_virtqueue_stop(hdev, - vdev, - hdev->vqs + i, - hdev->vq_index + i); + rc |=3D vhost_virtqueue_stop(hdev, + vdev, + hdev->vqs + i, + hdev->vq_index + i); } if (hdev->vhost_ops->vhost_reset_status) { hdev->vhost_ops->vhost_reset_status(hdev); @@ -2177,6 +2179,7 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODev= ice *vdev, bool vrings) hdev->started =3D false; vdev->vhost_started =3D false; hdev->vdev =3D NULL; + return rc; } =20 int vhost_net_set_backend(struct vhost_dev *hdev, diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h index a9469d50bc..fd96ec9c39 100644 --- a/include/hw/virtio/vhost.h +++ b/include/hw/virtio/vhost.h @@ -232,8 +232,10 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevi= ce *vdev, bool vrings); * Stop the vhost device. After the device is stopped the notifiers * can be disabled (@vhost_dev_disable_notifiers) and the device can * be torn down (@vhost_dev_cleanup). + * + * Return: 0 on success, !=3D 0 on error when stopping dev. */ -void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vring= s); +int vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings= ); =20 /** * DOC: vhost device configuration handling @@ -333,8 +335,8 @@ int vhost_device_iotlb_miss(struct vhost_dev *dev, uint= 64_t iova, int write); =20 int vhost_virtqueue_start(struct vhost_dev *dev, struct VirtIODevice *vdev, struct vhost_virtqueue *vq, unsigned idx); -void vhost_virtqueue_stop(struct vhost_dev *dev, struct VirtIODevice *vdev, - struct vhost_virtqueue *vq, unsigned idx); +int vhost_virtqueue_stop(struct vhost_dev *dev, struct VirtIODevice *vdev, + struct vhost_virtqueue *vq, unsigned idx); =20 void vhost_dev_reset_inflight(struct vhost_inflight *inflight); void vhost_dev_free_inflight(struct vhost_inflight *inflight); --=20 2.44.0 From nobody Fri Apr 4 05:15:29 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=smartx.com ARC-Seal: i=1; a=rsa-sha256; t=1743520787; cv=none; d=zohomail.com; s=zohoarc; b=ZUCOqz1zKjXMWZIfQYgbyxEaBjxyxvAz4mkrg3wZCKFmGHu4YhnZXibkUZtKZMbTPkypqi+pMQX5x5fl1emL1gUYNSJqDZvRxPN7DcS559LHz981Ea+WLtl6jO8zZWIqjIcND9g3fvfbcM+hEa0hywB1VAPWNiiw6WR7o1yJKPQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1743520787; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=vm9MtFXWVln57lA7/IXTowGkEZthI5sffUa9dh8rVt8=; b=UStqzDe7oDjKDK2dLNwcpgmOb3koKGrwIp+wKfHqlZDrX6zHXPNCYzCjzIiLSoo1h9KK+sHPeA32bsy+ak9B8Q6fx3mApUYkNF2tznsnbiEleUAIyQ1UnE6hkO+t5BM3/0I599+X7olkmkWhq6/0OphG1RWsJqBpQjPzzZ0NT80= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1743520787309492.5147133611749; Tue, 1 Apr 2025 08:19:47 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tzdOh-0006Kn-SO; Tue, 01 Apr 2025 11:19:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tzdOI-00060Y-Gp for qemu-devel@nongnu.org; Tue, 01 Apr 2025 11:19:09 -0400 Received: from mail-pl1-x629.google.com ([2607:f8b0:4864:20::629]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tzdOE-0005BA-0r for qemu-devel@nongnu.org; Tue, 01 Apr 2025 11:19:02 -0400 Received: by mail-pl1-x629.google.com with SMTP id d9443c01a7336-22928d629faso72045075ad.3 for ; Tue, 01 Apr 2025 08:18:55 -0700 (PDT) Received: from fedora.smartx.com ([2001:df0:a640:1::4]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2291eee029bsm90172195ad.62.2025.04.01.08.18.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 08:18:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=smartx-com.20230601.gappssmtp.com; s=20230601; t=1743520734; x=1744125534; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=vm9MtFXWVln57lA7/IXTowGkEZthI5sffUa9dh8rVt8=; b=ymws/CRMYp131gK1gHMDR3sLUv790QnDs1uo6kHND+tiv7X27q1MgCPma7UVHkAuGg 6E9Ejqw3d7P2FhMumCCe33VhYcdJxVeg0QBwArbdwaGqkVrUt1XW2Yx5rwURx+Efb9nz 2Dk94t59HnlINwi1exjrbo/939gtGvlZnxLIGZkcbK48aKljKA6W68HumxykCkP9j3rD SfaptzTfyC2M+7BuyTU3BZIrk/CkZfWKjpaIS6MBdI6lQhQKfMcBikPSSXngxjdbbFFn ikj+/7EV8WK0iW7sYulq2IjzGxwl69J++cVvdVwy88SEssabwt6wzBCJ5luTXyjjisu/ K+XQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743520734; x=1744125534; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vm9MtFXWVln57lA7/IXTowGkEZthI5sffUa9dh8rVt8=; b=AtJMikPgfO/GUbFWM+IuumrHfke28SizFNp7P4UY+YIngAdzfAnd56f4/yHiT2ZDmJ UZQp/kD59KHc+wvtMSivi/ov/54N3Lbs9KjY0s1XaN9goSXhh5lB5W7jVzooSTVGag9M w+It6tvi+Tq9SR6GWBkFlDUQ2j46GUDFDWe15ojLwbDoWXFjKFso+yrQHFaz/N4GEQ4l znTjvBfGibQeJBl0MwDEuQJMhP33UyGwCt7ptYoXzb9bGUCM/ZHA3Tho562YHP+WwD76 zhfVIqKqC497ejcZeuzfQ4vqrXAZr1KZ+KQUNtOYj114snXY69vljp5Z3KyPMk8n2G8F g2QQ== X-Gm-Message-State: AOJu0Yyw+2OoM8aF0+nKQ3F/Emc5zzt4RbDLntF1oWGOB9fwCsOMQ9bR i1MrLoZbEqs2KJREzjo09IuNoQvsxh52OX6vhAjbENbHmnTeybHlq4bGabtRpPoYs19NgigIPg/ SkEvqaQ== X-Gm-Gg: ASbGncugK+VsCgJYN25pgTu3ayOuHG1diUB4JKaLD8bPREK86Dv2f9Q5o3cdKmKJZD8 9X0lYJ9MxM94/5gkOIroQnFN0C3ejaPSehVJhpB5gydeteF9D4WfGfZBBHJ9OKXl/3hs25D0V/K Y2+8/ZUKJTSPBbSp6y2J0q6RCVfNa/giYcIo3c8ZYZl2PqnvTAt4JnUqHapjjNWxtYJDwPXLGqz PARzfRsg6iN8y2OOGdq5qVx01PUGbUpY0BAIDlMBN2e2d1JbROSzFt+YFmxPlhsVy+1IwmsZpcy bc0oJbE6ize7SmQv3Ae0/82AI3jrOeI= X-Google-Smtp-Source: AGHT+IGteyF/P+76pb9JLnl2TfUX9lsiyV0kWd/JESCJi7PM7H/3e4lQDYV8px0pWKimZieZb2WEJg== X-Received: by 2002:a17:902:d48a:b0:220:f140:f7be with SMTP id d9443c01a7336-2292f9f31c2mr230316105ad.41.1743520734030; Tue, 01 Apr 2025 08:18:54 -0700 (PDT) From: Haoqian He To: qemu-devel@nongnu.org, sgarzare@redhat.com, mst@redhat.com, raphael@enfabrica.net Cc: fengli@smartx.com, yuhua@smartx.com, Kevin Wolf , Hanna Reitz , Stefan Hajnoczi , Laurent Vivier , Amit Shah , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , Paolo Bonzini , Gerd Hoffmann , Jason Wang , Fam Zheng , Alex Williamson , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , =?UTF-8?q?Alex=20Benn=C3=A9e?= , mzamazal@redhat.com (reviewer:vhost-user-scmi), David Hildenbrand , "Gonglei (Arei)" , Eric Auger , Richard Henderson , qemu-block@nongnu.org (open list:Block layer core), virtio-fs@lists.linux.dev (open list:virtiofs) Subject: [PATCH v4 3/3] vhost-user: return failure if backend crash when live migration Date: Tue, 1 Apr 2025 11:18:17 -0400 Message-ID: <20250401151819.1526461-4-haoqian.he@smartx.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20250401151819.1526461-1-haoqian.he@smartx.com> References: <20250327064348.3595732-1-haoqian.he@smartx.com> <20250401151819.1526461-1-haoqian.he@smartx.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::629; envelope-from=haoqian.he@smartx.com; helo=mail-pl1-x629.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @smartx-com.20230601.gappssmtp.com) X-ZM-MESSAGEID: 1743520788939019100 Content-Type: text/plain; charset="utf-8" Live migration should be terminated if the vhost-user backend crashes before the migration completes. Specifically, since the vhost device will be stopped when VM is stopped before the end of the live migration, in current implementation if the backend crashes, vhost-user device set_status() won't return failure, live migration won't perceive the disconnection between QEMU and the backend. When the VM is migrated to the destination, the inflight IO will be resubmitted, and if the IO was completed out of order before, it will cause IO error. To fix this issue: 1. Add the return value to set_status() for VirtioDeviceClass. a. For the vhost-user device, return failure when the backend crashes. b. For other virtio devices, always return 0. 2. Return failure if vhost_dev_stop() failed for vhost-user device. If QEMU loses connection with the vhost-user backend, virtio set_status() can return failure to the upper layer, migration_completion() can handle the error, terminate the live migration, and restore the VM, so that inflight IO can be completed normally. Signed-off-by: Haoqian He --- backends/vhost-user.c | 20 +++++++++---------- hw/block/vhost-user-blk.c | 27 ++++++++++++++------------ hw/block/virtio-blk.c | 5 +++-- hw/char/virtio-serial-bus.c | 3 ++- hw/display/vhost-user-gpu.c | 12 +++++++++--- hw/input/virtio-input.c | 3 ++- hw/net/virtio-net.c | 3 ++- hw/scsi/vhost-scsi-common.c | 13 +++++++------ hw/scsi/vhost-scsi.c | 5 +++-- hw/scsi/vhost-user-scsi.c | 18 ++++++++++------- hw/virtio/vdpa-dev.c | 5 +++-- hw/virtio/vhost-user-base.c | 23 +++++++++++++--------- hw/virtio/vhost-user-fs.c | 23 +++++++++++++--------- hw/virtio/vhost-user-scmi.c | 27 +++++++++++++++----------- hw/virtio/vhost-user-vsock.c | 15 +++++++++----- hw/virtio/vhost-vsock-common.c | 12 ++++++------ hw/virtio/vhost-vsock.c | 11 ++++++----- hw/virtio/virtio-balloon.c | 3 ++- hw/virtio/virtio-crypto.c | 3 ++- hw/virtio/virtio-iommu.c | 3 ++- hw/virtio/virtio-rng.c | 5 +++-- hw/virtio/virtio.c | 23 +++++++++++++++------- include/hw/virtio/vhost-scsi-common.h | 2 +- include/hw/virtio/vhost-vsock-common.h | 2 +- include/hw/virtio/virtio.h | 2 +- include/system/vhost-user-backend.h | 2 +- 26 files changed, 161 insertions(+), 109 deletions(-) diff --git a/backends/vhost-user.c b/backends/vhost-user.c index d0e4d71a63..5409e9d4eb 100644 --- a/backends/vhost-user.c +++ b/backends/vhost-user.c @@ -97,30 +97,28 @@ err_host_notifiers: vhost_dev_disable_notifiers(&b->dev, b->vdev); } =20 -void +int vhost_user_backend_stop(VhostUserBackend *b) { BusState *qbus =3D BUS(qdev_get_parent_bus(DEVICE(b->vdev))); VirtioBusClass *k =3D VIRTIO_BUS_GET_CLASS(qbus); - int ret =3D 0; + int ret; =20 if (!b->started) { - return; + return 0; } =20 - vhost_dev_stop(&b->dev, b->vdev, true); + ret =3D vhost_dev_stop(&b->dev, b->vdev, true); =20 - if (k->set_guest_notifiers) { - ret =3D k->set_guest_notifiers(qbus->parent, - b->dev.nvqs, false); - if (ret < 0) { - error_report("vhost guest notifier cleanup failed: %d", ret); - } + if (k->set_guest_notifiers && + k->set_guest_notifiers(qbus->parent, b->dev.nvqs, false)< 0) { + error_report("vhost guest notifier cleanup failed: %d", ret); + return -1; } - assert(ret >=3D 0); =20 vhost_dev_disable_notifiers(&b->dev, b->vdev); b->started =3D false; + return ret; } =20 static void set_chardev(Object *obj, const char *value, Error **errp) diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c index ae42327cf8..f355459123 100644 --- a/hw/block/vhost-user-blk.c +++ b/hw/block/vhost-user-blk.c @@ -204,7 +204,7 @@ err_host_notifiers: return ret; } =20 -static void vhost_user_blk_stop(VirtIODevice *vdev) +static int vhost_user_blk_stop(VirtIODevice *vdev) { VHostUserBlk *s =3D VHOST_USER_BLK(vdev); BusState *qbus =3D BUS(qdev_get_parent_bus(DEVICE(vdev))); @@ -212,26 +212,26 @@ static void vhost_user_blk_stop(VirtIODevice *vdev) int ret; =20 if (!s->started_vu) { - return; + return 0; } s->started_vu =3D false; =20 if (!k->set_guest_notifiers) { - return; + return 0; } =20 - vhost_dev_stop(&s->dev, vdev, true); + ret =3D vhost_dev_stop(&s->dev, vdev, true); =20 - ret =3D k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false); - if (ret < 0) { + if (k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false) < 0) { error_report("vhost guest notifier cleanup failed: %d", ret); - return; + return -1; } =20 vhost_dev_disable_notifiers(&s->dev, vdev); + return ret; } =20 -static void vhost_user_blk_set_status(VirtIODevice *vdev, uint8_t status) +static int vhost_user_blk_set_status(VirtIODevice *vdev, uint8_t status) { VHostUserBlk *s =3D VHOST_USER_BLK(vdev); bool should_start =3D virtio_device_should_start(vdev, status); @@ -239,11 +239,11 @@ static void vhost_user_blk_set_status(VirtIODevice *v= dev, uint8_t status) int ret; =20 if (!s->connected) { - return; + return -1; } =20 if (vhost_dev_is_started(&s->dev) =3D=3D should_start) { - return; + return 0; } =20 if (should_start) { @@ -253,9 +253,12 @@ static void vhost_user_blk_set_status(VirtIODevice *vd= ev, uint8_t status) qemu_chr_fe_disconnect(&s->chardev); } } else { - vhost_user_blk_stop(vdev); + ret =3D vhost_user_blk_stop(vdev); + if (ret < 0) { + return ret; + } } - + return 0; } =20 static uint64_t vhost_user_blk_get_features(VirtIODevice *vdev, diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index 4a48a16790..4244ee3410 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -1269,7 +1269,7 @@ static uint64_t virtio_blk_get_features(VirtIODevice = *vdev, uint64_t features, return features; } =20 -static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status) +static int virtio_blk_set_status(VirtIODevice *vdev, uint8_t status) { VirtIOBlock *s =3D VIRTIO_BLK(vdev); =20 @@ -1278,7 +1278,7 @@ static void virtio_blk_set_status(VirtIODevice *vdev,= uint8_t status) } =20 if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) { - return; + return 0; } =20 /* A guest that supports VIRTIO_BLK_F_CONFIG_WCE must be able to send @@ -1301,6 +1301,7 @@ static void virtio_blk_set_status(VirtIODevice *vdev,= uint8_t status) virtio_vdev_has_feature(vdev, VIRTIO_BLK_F_WC= E)); } + return 0; } =20 static void virtio_blk_save_device(VirtIODevice *vdev, QEMUFile *f) diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index b6d2743a9c..22accfd8e4 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -622,7 +622,7 @@ static void guest_reset(VirtIOSerial *vser) } } =20 -static void set_status(VirtIODevice *vdev, uint8_t status) +static int set_status(VirtIODevice *vdev, uint8_t status) { VirtIOSerial *vser; VirtIOSerialPort *port; @@ -650,6 +650,7 @@ static void set_status(VirtIODevice *vdev, uint8_t stat= us) vsc->enable_backend(port, vdev->vm_running); } } + return 0; } =20 static void vser_reset(VirtIODevice *vdev) diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c index 2aed6243f6..d7d159ecd9 100644 --- a/hw/display/vhost-user-gpu.c +++ b/hw/display/vhost-user-gpu.c @@ -513,7 +513,7 @@ vhost_user_gpu_set_config(VirtIODevice *vdev, } } =20 -static void +static int vhost_user_gpu_set_status(VirtIODevice *vdev, uint8_t val) { VhostUserGPU *g =3D VHOST_USER_GPU(vdev); @@ -522,18 +522,24 @@ vhost_user_gpu_set_status(VirtIODevice *vdev, uint8_t= val) if (val & VIRTIO_CONFIG_S_DRIVER_OK && vdev->vm_running) { if (!vhost_user_gpu_do_set_socket(g, &err)) { error_report_err(err); - return; + return 0; } vhost_user_backend_start(g->vhost); } else { + int ret; + /* unblock any wait and stop processing */ if (g->vhost_gpu_fd !=3D -1) { vhost_user_gpu_update_blocked(g, true); qemu_chr_fe_deinit(&g->vhost_chr, true); g->vhost_gpu_fd =3D -1; } - vhost_user_backend_stop(g->vhost); + ret =3D vhost_user_backend_stop(g->vhost); + if (ret < 0) { + return ret; + } } + return 0; } =20 static bool diff --git a/hw/input/virtio-input.c b/hw/input/virtio-input.c index 1394d99c6b..7ce53b7449 100644 --- a/hw/input/virtio-input.c +++ b/hw/input/virtio-input.c @@ -189,7 +189,7 @@ static uint64_t virtio_input_get_features(VirtIODevice = *vdev, uint64_t f, return f; } =20 -static void virtio_input_set_status(VirtIODevice *vdev, uint8_t val) +static int virtio_input_set_status(VirtIODevice *vdev, uint8_t val) { VirtIOInputClass *vic =3D VIRTIO_INPUT_GET_CLASS(vdev); VirtIOInput *vinput =3D VIRTIO_INPUT(vdev); @@ -202,6 +202,7 @@ static void virtio_input_set_status(VirtIODevice *vdev,= uint8_t val) } } } + return 0; } =20 static void virtio_input_reset(VirtIODevice *vdev) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index de87cfadff..b7de824baa 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -382,7 +382,7 @@ static void virtio_net_drop_tx_queue_data(VirtIODevice = *vdev, VirtQueue *vq) } } =20 -static void virtio_net_set_status(struct VirtIODevice *vdev, uint8_t statu= s) +static int virtio_net_set_status(struct VirtIODevice *vdev, uint8_t status) { VirtIONet *n =3D VIRTIO_NET(vdev); VirtIONetQueue *q; @@ -437,6 +437,7 @@ static void virtio_net_set_status(struct VirtIODevice *= vdev, uint8_t status) } } } + return 0; } =20 static void virtio_net_set_link_status(NetClientState *nc) diff --git a/hw/scsi/vhost-scsi-common.c b/hw/scsi/vhost-scsi-common.c index 4c8637045d..43525ba46d 100644 --- a/hw/scsi/vhost-scsi-common.c +++ b/hw/scsi/vhost-scsi-common.c @@ -101,24 +101,25 @@ err_host_notifiers: return ret; } =20 -void vhost_scsi_common_stop(VHostSCSICommon *vsc) +int vhost_scsi_common_stop(VHostSCSICommon *vsc) { VirtIODevice *vdev =3D VIRTIO_DEVICE(vsc); BusState *qbus =3D BUS(qdev_get_parent_bus(DEVICE(vdev))); VirtioBusClass *k =3D VIRTIO_BUS_GET_CLASS(qbus); int ret =3D 0; =20 - vhost_dev_stop(&vsc->dev, vdev, true); + ret =3D vhost_dev_stop(&vsc->dev, vdev, true); =20 if (k->set_guest_notifiers) { - ret =3D k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, false); - if (ret < 0) { - error_report("vhost guest notifier cleanup failed: %d", re= t); + int r =3D k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, fals= e); + if (r < 0) { + error_report("vhost guest notifier cleanup failed: %d", ret); + return r; } } - assert(ret >=3D 0); =20 vhost_dev_disable_notifiers(&vsc->dev, vdev); + return ret; } =20 uint64_t vhost_scsi_common_get_features(VirtIODevice *vdev, uint64_t featu= res, diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c index 8039d13fd9..19d5261019 100644 --- a/hw/scsi/vhost-scsi.c +++ b/hw/scsi/vhost-scsi.c @@ -114,7 +114,7 @@ static void vhost_scsi_stop(VHostSCSI *s) vhost_scsi_common_stop(vsc); } =20 -static void vhost_scsi_set_status(VirtIODevice *vdev, uint8_t val) +static int vhost_scsi_set_status(VirtIODevice *vdev, uint8_t val) { VHostSCSI *s =3D VHOST_SCSI(vdev); VHostSCSICommon *vsc =3D VHOST_SCSI_COMMON(s); @@ -125,7 +125,7 @@ static void vhost_scsi_set_status(VirtIODevice *vdev, u= int8_t val) } =20 if (vhost_dev_is_started(&vsc->dev) =3D=3D start) { - return; + return 0; } =20 if (start) { @@ -139,6 +139,7 @@ static void vhost_scsi_set_status(VirtIODevice *vdev, u= int8_t val) } else { vhost_scsi_stop(s); } + return 0; } =20 static void vhost_dummy_handle_output(VirtIODevice *vdev, VirtQueue *vq) diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c index adb41b9816..aba9fb82d2 100644 --- a/hw/scsi/vhost-user-scsi.c +++ b/hw/scsi/vhost-user-scsi.c @@ -52,19 +52,19 @@ static int vhost_user_scsi_start(VHostUserSCSI *s, Erro= r **errp) return ret; } =20 -static void vhost_user_scsi_stop(VHostUserSCSI *s) +static int vhost_user_scsi_stop(VHostUserSCSI *s) { VHostSCSICommon *vsc =3D VHOST_SCSI_COMMON(s); =20 if (!s->started_vu) { - return; + return 0; } s->started_vu =3D false; =20 - vhost_scsi_common_stop(vsc); + return vhost_scsi_common_stop(vsc); } =20 -static void vhost_user_scsi_set_status(VirtIODevice *vdev, uint8_t status) +static int vhost_user_scsi_set_status(VirtIODevice *vdev, uint8_t status) { VHostUserSCSI *s =3D (VHostUserSCSI *)vdev; DeviceState *dev =3D DEVICE(vdev); @@ -75,11 +75,11 @@ static void vhost_user_scsi_set_status(VirtIODevice *vd= ev, uint8_t status) int ret; =20 if (!s->connected) { - return; + return -1; } =20 if (vhost_dev_is_started(&vsc->dev) =3D=3D should_start) { - return; + return 0; } =20 if (should_start) { @@ -91,8 +91,12 @@ static void vhost_user_scsi_set_status(VirtIODevice *vde= v, uint8_t status) qemu_chr_fe_disconnect(&vs->conf.chardev); } } else { - vhost_user_scsi_stop(s); + ret =3D vhost_user_scsi_stop(s); + if (ret) { + return ret; + } } + return 0; } =20 static void vhost_user_scsi_handle_output(VirtIODevice *vdev, VirtQueue *v= q) diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c index a7e73b1c99..d80d46baed 100644 --- a/hw/virtio/vdpa-dev.c +++ b/hw/virtio/vdpa-dev.c @@ -312,7 +312,7 @@ static void vhost_vdpa_device_stop(VirtIODevice *vdev) vhost_dev_disable_notifiers(&s->dev, vdev); } =20 -static void vhost_vdpa_device_set_status(VirtIODevice *vdev, uint8_t statu= s) +static int vhost_vdpa_device_set_status(VirtIODevice *vdev, uint8_t status) { VhostVdpaDevice *s =3D VHOST_VDPA_DEVICE(vdev); bool should_start =3D virtio_device_started(vdev, status); @@ -324,7 +324,7 @@ static void vhost_vdpa_device_set_status(VirtIODevice *= vdev, uint8_t status) } =20 if (s->started =3D=3D should_start) { - return; + return 0; } =20 if (should_start) { @@ -335,6 +335,7 @@ static void vhost_vdpa_device_set_status(VirtIODevice *= vdev, uint8_t status) } else { vhost_vdpa_device_stop(vdev); } + return 0; } =20 static const Property vhost_vdpa_device_properties[] =3D { diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c index 2bc3423326..37718653bd 100644 --- a/hw/virtio/vhost-user-base.c +++ b/hw/virtio/vhost-user-base.c @@ -66,7 +66,7 @@ err_host_notifiers: vhost_dev_disable_notifiers(&vub->vhost_dev, vdev); } =20 -static void vub_stop(VirtIODevice *vdev) +static int vub_stop(VirtIODevice *vdev) { VHostUserBase *vub =3D VHOST_USER_BASE(vdev); BusState *qbus =3D BUS(qdev_get_parent_bus(DEVICE(vdev))); @@ -74,34 +74,39 @@ static void vub_stop(VirtIODevice *vdev) int ret; =20 if (!k->set_guest_notifiers) { - return; + return 0; } =20 - vhost_dev_stop(&vub->vhost_dev, vdev, true); + ret =3D vhost_dev_stop(&vub->vhost_dev, vdev, true); =20 - ret =3D k->set_guest_notifiers(qbus->parent, vub->vhost_dev.nvqs, fals= e); - if (ret < 0) { + if (k->set_guest_notifiers(qbus->parent, vub->vhost_dev.nvqs, false) <= 0) { error_report("vhost guest notifier cleanup failed: %d", ret); - return; + return -1; } =20 vhost_dev_disable_notifiers(&vub->vhost_dev, vdev); + return ret; } =20 -static void vub_set_status(VirtIODevice *vdev, uint8_t status) +static int vub_set_status(VirtIODevice *vdev, uint8_t status) { VHostUserBase *vub =3D VHOST_USER_BASE(vdev); bool should_start =3D virtio_device_should_start(vdev, status); =20 if (vhost_dev_is_started(&vub->vhost_dev) =3D=3D should_start) { - return; + return 0; } =20 if (should_start) { vub_start(vdev); } else { - vub_stop(vdev); + int ret; + ret =3D vub_stop(vdev); + if (ret < 0) { + return ret; + } } + return 0; } =20 /* diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c index 3f00d79ed0..266c179671 100644 --- a/hw/virtio/vhost-user-fs.c +++ b/hw/virtio/vhost-user-fs.c @@ -100,7 +100,7 @@ err_host_notifiers: vhost_dev_disable_notifiers(&fs->vhost_dev, vdev); } =20 -static void vuf_stop(VirtIODevice *vdev) +static int vuf_stop(VirtIODevice *vdev) { VHostUserFS *fs =3D VHOST_USER_FS(vdev); BusState *qbus =3D BUS(qdev_get_parent_bus(DEVICE(vdev))); @@ -108,34 +108,39 @@ static void vuf_stop(VirtIODevice *vdev) int ret; =20 if (!k->set_guest_notifiers) { - return; + return 0; } =20 - vhost_dev_stop(&fs->vhost_dev, vdev, true); + ret =3D vhost_dev_stop(&fs->vhost_dev, vdev, true); =20 - ret =3D k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, false= ); - if (ret < 0) { + if (k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, false) < = 0) { error_report("vhost guest notifier cleanup failed: %d", ret); - return; + return -1; } =20 vhost_dev_disable_notifiers(&fs->vhost_dev, vdev); + return ret; } =20 -static void vuf_set_status(VirtIODevice *vdev, uint8_t status) +static int vuf_set_status(VirtIODevice *vdev, uint8_t status) { VHostUserFS *fs =3D VHOST_USER_FS(vdev); bool should_start =3D virtio_device_should_start(vdev, status); =20 if (vhost_dev_is_started(&fs->vhost_dev) =3D=3D should_start) { - return; + return 0; } =20 if (should_start) { vuf_start(vdev); } else { - vuf_stop(vdev); + int ret; + ret =3D vuf_stop(vdev); + if (ret < 0) { + return ret; + } } + return 0; } =20 static uint64_t vuf_get_features(VirtIODevice *vdev, diff --git a/hw/virtio/vhost-user-scmi.c b/hw/virtio/vhost-user-scmi.c index 410a936ca7..a9778f1f4b 100644 --- a/hw/virtio/vhost-user-scmi.c +++ b/hw/virtio/vhost-user-scmi.c @@ -83,7 +83,7 @@ err_host_notifiers: return ret; } =20 -static void vu_scmi_stop(VirtIODevice *vdev) +static int vu_scmi_stop(VirtIODevice *vdev) { VHostUserSCMI *scmi =3D VHOST_USER_SCMI(vdev); BusState *qbus =3D BUS(qdev_get_parent_bus(DEVICE(vdev))); @@ -93,41 +93,46 @@ static void vu_scmi_stop(VirtIODevice *vdev) =20 /* vhost_dev_is_started() check in the callers is not fully reliable. = */ if (!scmi->started_vu) { - return; + return 0; } scmi->started_vu =3D false; =20 if (!k->set_guest_notifiers) { - return; + return 0; } =20 - vhost_dev_stop(vhost_dev, vdev, true); + ret =3D vhost_dev_stop(vhost_dev, vdev, true); =20 - ret =3D k->set_guest_notifiers(qbus->parent, vhost_dev->nvqs, false); - if (ret < 0) { + if (k->set_guest_notifiers(qbus->parent, vhost_dev->nvqs, false) < 0) { error_report("vhost guest notifier cleanup failed: %d", ret); - return; + return -1; } vhost_dev_disable_notifiers(vhost_dev, vdev); + return ret; } =20 -static void vu_scmi_set_status(VirtIODevice *vdev, uint8_t status) +static int vu_scmi_set_status(VirtIODevice *vdev, uint8_t status) { VHostUserSCMI *scmi =3D VHOST_USER_SCMI(vdev); bool should_start =3D virtio_device_should_start(vdev, status); =20 if (!scmi->connected) { - return; + return -1; } if (vhost_dev_is_started(&scmi->vhost_dev) =3D=3D should_start) { - return; + return 0; } =20 if (should_start) { vu_scmi_start(vdev); } else { - vu_scmi_stop(vdev); + int ret; + ret =3D vu_scmi_stop(vdev); + if (ret < 0) { + return ret; + } } + return 0; } =20 static uint64_t vu_scmi_get_features(VirtIODevice *vdev, uint64_t features, diff --git a/hw/virtio/vhost-user-vsock.c b/hw/virtio/vhost-user-vsock.c index 293273080b..7a4aec7bf4 100644 --- a/hw/virtio/vhost-user-vsock.c +++ b/hw/virtio/vhost-user-vsock.c @@ -54,23 +54,28 @@ const VhostDevConfigOps vsock_ops =3D { .vhost_dev_config_notifier =3D vuv_handle_config_change, }; =20 -static void vuv_set_status(VirtIODevice *vdev, uint8_t status) +static int vuv_set_status(VirtIODevice *vdev, uint8_t status) { VHostVSockCommon *vvc =3D VHOST_VSOCK_COMMON(vdev); bool should_start =3D virtio_device_should_start(vdev, status); + int ret; =20 if (vhost_dev_is_started(&vvc->vhost_dev) =3D=3D should_start) { - return; + return 0; } =20 if (should_start) { - int ret =3D vhost_vsock_common_start(vdev); + ret =3D vhost_vsock_common_start(vdev); if (ret < 0) { - return; + return ret; } } else { - vhost_vsock_common_stop(vdev); + ret =3D vhost_vsock_common_stop(vdev); + if (ret < 0) { + return ret; + } } + return 0; } =20 static uint64_t vuv_get_features(VirtIODevice *vdev, diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c index 9ac587d20c..bbfbbdb317 100644 --- a/hw/virtio/vhost-vsock-common.c +++ b/hw/virtio/vhost-vsock-common.c @@ -95,7 +95,7 @@ err_host_notifiers: return ret; } =20 -void vhost_vsock_common_stop(VirtIODevice *vdev) +int vhost_vsock_common_stop(VirtIODevice *vdev) { VHostVSockCommon *vvc =3D VHOST_VSOCK_COMMON(vdev); BusState *qbus =3D BUS(qdev_get_parent_bus(DEVICE(vdev))); @@ -103,18 +103,18 @@ void vhost_vsock_common_stop(VirtIODevice *vdev) int ret; =20 if (!k->set_guest_notifiers) { - return; + return 0; } =20 - vhost_dev_stop(&vvc->vhost_dev, vdev, true); + ret =3D vhost_dev_stop(&vvc->vhost_dev, vdev, true); =20 - ret =3D k->set_guest_notifiers(qbus->parent, vvc->vhost_dev.nvqs, fals= e); - if (ret < 0) { + if (k->set_guest_notifiers(qbus->parent, vvc->vhost_dev.nvqs, false) <= 0) { error_report("vhost guest notifier cleanup failed: %d", ret); - return; + return -1; } =20 vhost_dev_disable_notifiers(&vvc->vhost_dev, vdev); + return ret; } =20 =20 diff --git a/hw/virtio/vhost-vsock.c b/hw/virtio/vhost-vsock.c index 940b30fa27..62b36b28f5 100644 --- a/hw/virtio/vhost-vsock.c +++ b/hw/virtio/vhost-vsock.c @@ -67,37 +67,38 @@ static int vhost_vsock_set_running(VirtIODevice *vdev, = int start) } =20 =20 -static void vhost_vsock_set_status(VirtIODevice *vdev, uint8_t status) +static int vhost_vsock_set_status(VirtIODevice *vdev, uint8_t status) { VHostVSockCommon *vvc =3D VHOST_VSOCK_COMMON(vdev); bool should_start =3D virtio_device_should_start(vdev, status); int ret; =20 if (vhost_dev_is_started(&vvc->vhost_dev) =3D=3D should_start) { - return; + return 0; } =20 if (should_start) { ret =3D vhost_vsock_common_start(vdev); if (ret < 0) { - return; + return 0; } =20 ret =3D vhost_vsock_set_running(vdev, 1); if (ret < 0) { vhost_vsock_common_stop(vdev); error_report("Error starting vhost vsock: %d", -ret); - return; + return 0; } } else { ret =3D vhost_vsock_set_running(vdev, 0); if (ret < 0) { error_report("vhost vsock set running failed: %d", ret); - return; + return 0; } =20 vhost_vsock_common_stop(vdev); } + return 0; } =20 static uint64_t vhost_vsock_get_features(VirtIODevice *vdev, diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index 2eb5a14fa2..e719c078aa 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -958,7 +958,7 @@ static void virtio_balloon_device_reset(VirtIODevice *v= dev) s->poison_val =3D 0; } =20 -static void virtio_balloon_set_status(VirtIODevice *vdev, uint8_t status) +static int virtio_balloon_set_status(VirtIODevice *vdev, uint8_t status) { VirtIOBalloon *s =3D VIRTIO_BALLOON(vdev); =20 @@ -988,6 +988,7 @@ static void virtio_balloon_set_status(VirtIODevice *vde= v, uint8_t status) qemu_mutex_unlock(&s->free_page_lock); } } + return 0; } =20 static ResettableState *virtio_balloon_get_reset_state(Object *obj) diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c index a1b3c90618..626279dc5b 100644 --- a/hw/virtio/virtio-crypto.c +++ b/hw/virtio/virtio-crypto.c @@ -1197,11 +1197,12 @@ static void virtio_crypto_vhost_status(VirtIOCrypto= *c, uint8_t status) } } =20 -static void virtio_crypto_set_status(VirtIODevice *vdev, uint8_t status) +static int virtio_crypto_set_status(VirtIODevice *vdev, uint8_t status) { VirtIOCrypto *vcrypto =3D VIRTIO_CRYPTO(vdev); =20 virtio_crypto_vhost_status(vcrypto, status); + return 0; } =20 static void virtio_crypto_guest_notifier_mask(VirtIODevice *vdev, int idx, diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index b6e7e01ef7..63ec12014f 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -1522,9 +1522,10 @@ static void virtio_iommu_device_reset_exit(Object *o= bj, ResetType type) NULL, NULL, virtio_iommu_put_endpoint); } =20 -static void virtio_iommu_set_status(VirtIODevice *vdev, uint8_t status) +static int virtio_iommu_set_status(VirtIODevice *vdev, uint8_t status) { trace_virtio_iommu_device_status(status); + return 0; } =20 static void virtio_iommu_instance_init(Object *obj) diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c index a515fc5cd9..4748d039f9 100644 --- a/hw/virtio/virtio-rng.c +++ b/hw/virtio/virtio-rng.c @@ -159,17 +159,18 @@ static void check_rate_limit(void *opaque) vrng->activate_timer =3D true; } =20 -static void virtio_rng_set_status(VirtIODevice *vdev, uint8_t status) +static int virtio_rng_set_status(VirtIODevice *vdev, uint8_t status) { VirtIORNG *vrng =3D VIRTIO_RNG(vdev); =20 if (!vdev->vm_running) { - return; + return 0; } vdev->status =3D status; =20 /* Something changed, try to process buffers */ virtio_rng_process(vrng); + return 0; } =20 static void virtio_rng_device_realize(DeviceState *dev, Error **errp) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 202a052053..8d292b45c5 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -2221,12 +2221,12 @@ int virtio_set_status(VirtIODevice *vdev, uint8_t v= al) { VirtioDeviceClass *k =3D VIRTIO_DEVICE_GET_CLASS(vdev); trace_virtio_set_status(vdev, val); + int ret =3D 0; =20 if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) { if (!(vdev->status & VIRTIO_CONFIG_S_FEATURES_OK) && val & VIRTIO_CONFIG_S_FEATURES_OK) { - int ret =3D virtio_validate_features(vdev); - + ret =3D virtio_validate_features(vdev); if (ret) { return ret; } @@ -2239,11 +2239,15 @@ int virtio_set_status(VirtIODevice *vdev, uint8_t v= al) } =20 if (k->set_status) { - k->set_status(vdev, val); + ret =3D k->set_status(vdev, val); + if (ret) { + qemu_log("set %s status to %d failed, old status: %d\n", + vdev->name, val, vdev->status); + } } vdev->status =3D val; =20 - return 0; + return ret; } =20 static enum virtio_device_endian virtio_default_endian(void) @@ -3419,7 +3423,7 @@ void virtio_cleanup(VirtIODevice *vdev) qemu_del_vm_change_state_handler(vdev->vmstate); } =20 -static void virtio_vmstate_change(void *opaque, bool running, RunState sta= te) +static int virtio_vmstate_change(void *opaque, bool running, RunState stat= e) { VirtIODevice *vdev =3D opaque; BusState *qbus =3D qdev_get_parent_bus(DEVICE(vdev)); @@ -3436,8 +3440,13 @@ static void virtio_vmstate_change(void *opaque, bool= running, RunState state) } =20 if (!backend_run) { - virtio_set_status(vdev, vdev->status); + // the return value was used for stopping VM during migration + int ret =3D virtio_set_status(vdev, vdev->status); + if (ret) { + return ret; + } } + return 0; } =20 void virtio_instance_init_common(Object *proxy_obj, void *data, @@ -3489,7 +3498,7 @@ void virtio_init(VirtIODevice *vdev, uint16_t device_= id, size_t config_size) vdev->config =3D NULL; } vdev->vmstate =3D qdev_add_vm_change_state_handler(DEVICE(vdev), - virtio_vmstate_change, NULL, vdev); + NULL, virtio_vmstate_change, vdev); vdev->device_endian =3D virtio_default_endian(); vdev->use_guest_notifier_mask =3D true; } diff --git a/include/hw/virtio/vhost-scsi-common.h b/include/hw/virtio/vhos= t-scsi-common.h index c5d2c09455..d54d9c916f 100644 --- a/include/hw/virtio/vhost-scsi-common.h +++ b/include/hw/virtio/vhost-scsi-common.h @@ -40,7 +40,7 @@ struct VHostSCSICommon { }; =20 int vhost_scsi_common_start(VHostSCSICommon *vsc, Error **errp); -void vhost_scsi_common_stop(VHostSCSICommon *vsc); +int vhost_scsi_common_stop(VHostSCSICommon *vsc); char *vhost_scsi_common_get_fw_dev_path(FWPathProvider *p, BusState *bus, DeviceState *dev); void vhost_scsi_common_set_config(VirtIODevice *vdev, const uint8_t *confi= g); diff --git a/include/hw/virtio/vhost-vsock-common.h b/include/hw/virtio/vho= st-vsock-common.h index 75a74e8a99..01bf6062af 100644 --- a/include/hw/virtio/vhost-vsock-common.h +++ b/include/hw/virtio/vhost-vsock-common.h @@ -42,7 +42,7 @@ struct VHostVSockCommon { }; =20 int vhost_vsock_common_start(VirtIODevice *vdev); -void vhost_vsock_common_stop(VirtIODevice *vdev); +int vhost_vsock_common_stop(VirtIODevice *vdev); int vhost_vsock_common_pre_save(void *opaque); int vhost_vsock_common_post_load(void *opaque, int version_id); void vhost_vsock_common_realize(VirtIODevice *vdev); diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 6386910280..a7ee9bec75 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -186,7 +186,7 @@ struct VirtioDeviceClass { void (*get_config)(VirtIODevice *vdev, uint8_t *config); void (*set_config)(VirtIODevice *vdev, const uint8_t *config); void (*reset)(VirtIODevice *vdev); - void (*set_status)(VirtIODevice *vdev, uint8_t val); + int (*set_status)(VirtIODevice *vdev, uint8_t val); /* Device must validate queue_index. */ void (*queue_reset)(VirtIODevice *vdev, uint32_t queue_index); /* Device must validate queue_index. */ diff --git a/include/system/vhost-user-backend.h b/include/system/vhost-use= r-backend.h index 327b0b84f1..87765a1218 100644 --- a/include/system/vhost-user-backend.h +++ b/include/system/vhost-user-backend.h @@ -43,6 +43,6 @@ struct VhostUserBackend { int vhost_user_backend_dev_init(VhostUserBackend *b, VirtIODevice *vdev, unsigned nvqs, Error **errp); void vhost_user_backend_start(VhostUserBackend *b); -void vhost_user_backend_stop(VhostUserBackend *b); +int vhost_user_backend_stop(VhostUserBackend *b); =20 #endif --=20 2.44.0