From nobody Tue May 21 05:12:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.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; Authentication-Results: mx.zohomail.com; spf=pass (zoho.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=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1553262613772996.2556315577483; Fri, 22 Mar 2019 06:50:13 -0700 (PDT) Received: from localhost ([127.0.0.1]:57686 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h7KYk-0008Bt-It for importer@patchew.org; Fri, 22 Mar 2019 09:50:10 -0400 Received: from eggs.gnu.org ([209.51.188.92]:32986) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h7KTl-0004TW-Kg for qemu-devel@nongnu.org; Fri, 22 Mar 2019 09:45:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h7KTj-0003OG-Rk for qemu-devel@nongnu.org; Fri, 22 Mar 2019 09:45:01 -0400 Received: from mx1.redhat.com ([209.132.183.28]:50884) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h7KTj-0003LB-DG for qemu-devel@nongnu.org; Fri, 22 Mar 2019 09:44:59 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8B5167D7BB; Fri, 22 Mar 2019 13:44:58 +0000 (UTC) Received: from localhost (ovpn-117-44.ams2.redhat.com [10.36.117.44]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CDA1A608A5; Fri, 22 Mar 2019 13:44:53 +0000 (UTC) From: Jens Freimann To: qemu-devel@nongnu.org Date: Fri, 22 Mar 2019 14:44:46 +0100 Message-Id: <20190322134447.14831-2-jfreimann@redhat.com> In-Reply-To: <20190322134447.14831-1-jfreimann@redhat.com> References: <20190322134447.14831-1-jfreimann@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Fri, 22 Mar 2019 13:44:58 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC PATCH 1/2] qdev/qbus: Add hidden device support 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: pkrempa@redhat.com, ehabkost@redhat.com, mst@redhat.com, mdroth@linux.vnet.ibm.com, liran.alon@oracle.com, laine@redhat.com, ogerlitz@mellanox.com, ailan@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Sameeh Jubran Signed-off-by: Jens Freimann --- hw/core/qdev.c | 27 ++++++++++++++++++++++++ hw/pci/pci.c | 1 + include/hw/pci/pci.h | 2 ++ include/hw/qdev-core.h | 8 +++++++ qdev-monitor.c | 48 ++++++++++++++++++++++++++++++++++++++---- vl.c | 7 ++++-- 6 files changed, 87 insertions(+), 6 deletions(-) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index f9b6efe509..5e1c8f0120 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -211,6 +211,33 @@ void device_listener_unregister(DeviceListener *listen= er) QTAILQ_REMOVE(&device_listeners, listener, link); } =20 +bool qdev_should_hide_device(QemuOpts *opts, Error **errp) +{ + bool res =3D false; + bool match_found =3D false; + =20 + DeviceListener *listener; + + QTAILQ_FOREACH(listener, &device_listeners, link) { + if (listener->should_be_hidden) { + listener->should_be_hidden(listener, opts, &match_found, &res); + } + + if (match_found) + { + break; + } + } + /* No suitable pair device was found */ + if (!match_found) + { + error_setg(errp, "An error occurred: Couln't attach to standby dev= ice" + " Please note that the primary device should be" + " must be placed after the standby device in the command line"); + } + return res; +} + void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id, int required_for_version) { diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 35451c1e99..67b1b7c500 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -70,6 +70,7 @@ static Property pci_props[] =3D { QEMU_PCIE_LNKSTA_DLLLA_BITNR, true), DEFINE_PROP_BIT("x-pcie-extcap-init", PCIDevice, cap_present, QEMU_PCIE_EXTCAP_INIT_BITNR, true), + DEFINE_PROP_STRING("standby", PCIDevice, standby_id_str), DEFINE_PROP_END_OF_LIST() }; =20 diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index d87f5f93e9..f75dace1ec 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -351,6 +351,8 @@ struct PCIDevice { MSIVectorUseNotifier msix_vector_use_notifier; MSIVectorReleaseNotifier msix_vector_release_notifier; MSIVectorPollNotifier msix_vector_poll_notifier; + + char *standby_id_str; }; =20 void pci_register_bar(PCIDevice *pci_dev, int region_num, diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 33ed3b8dde..e3b11f5503 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -144,6 +144,7 @@ struct DeviceState { char *canonical_path; bool realized; bool pending_deleted_event; + bool hidden; QemuOpts *opts; int hotplugged; BusState *parent_bus; @@ -157,6 +158,11 @@ struct DeviceState { struct DeviceListener { void (*realize)(DeviceListener *listener, DeviceState *dev); void (*unrealize)(DeviceListener *listener, DeviceState *dev); + /* This callback is called just upon init of the DeviceState + * and can be used by a standby device for informing qdev if this + * device should be hidden by checking the device opts + */ + void (*should_be_hidden)(DeviceListener *listener, QemuOpts *device_op= ts,bool *match_found, bool *res); QTAILQ_ENTRY(DeviceListener) link; }; =20 @@ -453,4 +459,6 @@ static inline bool qbus_is_hotpluggable(BusState *bus) void device_listener_register(DeviceListener *listener); void device_listener_unregister(DeviceListener *listener); =20 +bool qdev_should_hide_device(QemuOpts *opts, Error **errp); + #endif diff --git a/qdev-monitor.c b/qdev-monitor.c index d4320986a2..f4cfc8d4a1 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -33,6 +33,7 @@ #include "qemu/option.h" #include "sysemu/block-backend.h" #include "migration/misc.h" +#include "migration/migration.h" =20 /* * Aliases were a bad idea from the start. Let's keep them @@ -569,13 +570,49 @@ void qdev_set_id(DeviceState *dev, const char *id) } } =20 +static int has_standby_device(void *opaque, const char *name, const char *= value, + Error **errp) +{ + if (strcmp(name, "standby") =3D=3D 0) + { + QemuOpts *opts =3D (QemuOpts *)opaque; + if (qdev_should_hide_device(opts, errp) && errp && !*errp) + { + return 1; + } + else if (errp && *errp) + { + return -1; + } + } + return 0; +} + +static bool should_hide_device(QemuOpts *opts, Error **err) +{ + if (qemu_opt_foreach(opts, has_standby_device, opts, err) =3D=3D 0) + { + return false; + } + return true; +} + DeviceState *qdev_device_add(QemuOpts *opts, Error **errp) { DeviceClass *dc; const char *driver, *path; - DeviceState *dev; + DeviceState *dev =3D NULL; BusState *bus =3D NULL; Error *err =3D NULL; + =20 + if (opts && should_hide_device(opts, &err)) + { + if(err) + { + goto err_del_dev; + } + return NULL; + } =20 driver =3D qemu_opt_get(opts, "driver"); if (!driver) { @@ -648,8 +685,11 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **e= rrp) =20 err_del_dev: error_propagate(errp, err); - object_unparent(OBJECT(dev)); - object_unref(OBJECT(dev)); + if (dev) + { + object_unparent(OBJECT(dev)); + object_unref(OBJECT(dev)); + } return NULL; } =20 @@ -875,7 +915,7 @@ void qdev_unplug(DeviceState *dev, Error **errp) return; } =20 - if (!migration_is_idle()) { + if (!migration_is_idle() && !migration_in_setup(migrate_get_current())= ) { error_setg(errp, "device_del not allowed while migrating"); return; } diff --git a/vl.c b/vl.c index d61d5604e5..51e773a8a9 100644 --- a/vl.c +++ b/vl.c @@ -2337,10 +2337,13 @@ static int device_init_func(void *opaque, QemuOpts = *opts, Error **errp) DeviceState *dev; =20 dev =3D qdev_device_add(opts, errp); - if (!dev) { + if (!dev && *errp) { + error_report_err(*errp); return -1; + } else if (dev) + { + object_unref(OBJECT(dev)); } - object_unref(OBJECT(dev)); return 0; } =20 --=20 2.20.1 From nobody Tue May 21 05:12:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.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; Authentication-Results: mx.zohomail.com; spf=pass (zoho.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=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1553262709384959.0136990629978; Fri, 22 Mar 2019 06:51:49 -0700 (PDT) Received: from localhost ([127.0.0.1]:57729 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h7KaI-0001cE-27 for importer@patchew.org; Fri, 22 Mar 2019 09:51:46 -0400 Received: from eggs.gnu.org ([209.51.188.92]:33019) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h7KTn-0004Vm-MV for qemu-devel@nongnu.org; Fri, 22 Mar 2019 09:45:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h7KTm-0003Vg-6J for qemu-devel@nongnu.org; Fri, 22 Mar 2019 09:45:03 -0400 Received: from mx1.redhat.com ([209.132.183.28]:54426) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h7KTl-0003Rz-Mh for qemu-devel@nongnu.org; Fri, 22 Mar 2019 09:45:02 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id CAC5018DF6C; Fri, 22 Mar 2019 13:45:00 +0000 (UTC) Received: from localhost (ovpn-117-44.ams2.redhat.com [10.36.117.44]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 534B0600C4; Fri, 22 Mar 2019 13:45:00 +0000 (UTC) From: Jens Freimann To: qemu-devel@nongnu.org Date: Fri, 22 Mar 2019 14:44:47 +0100 Message-Id: <20190322134447.14831-3-jfreimann@redhat.com> In-Reply-To: <20190322134447.14831-1-jfreimann@redhat.com> References: <20190322134447.14831-1-jfreimann@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Fri, 22 Mar 2019 13:45:00 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC PATCH 2/2] net/virtio: add failover support 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: pkrempa@redhat.com, ehabkost@redhat.com, mst@redhat.com, mdroth@linux.vnet.ibm.com, liran.alon@oracle.com, laine@redhat.com, ogerlitz@mellanox.com, ailan@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Sameeh Jubran --- hw/net/virtio-net.c | 95 ++++++++++++++++++++++++++++++++++ include/hw/virtio/virtio-net.h | 7 +++ 2 files changed, 102 insertions(+) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 7e2c2a6f6a..880420a673 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -12,6 +12,7 @@ */ =20 #include "qemu/osdep.h" +#include "qemu/atomic.h" #include "qemu/iov.h" #include "hw/virtio/virtio.h" #include "net/net.h" @@ -19,6 +20,7 @@ #include "net/tap.h" #include "qemu/error-report.h" #include "qemu/timer.h" +#include "qemu/option.h" #include "hw/virtio/virtio-net.h" #include "net/vhost_net.h" #include "net/announce.h" @@ -29,6 +31,8 @@ #include "migration/misc.h" #include "standard-headers/linux/ethtool.h" #include "trace.h" +#include "monitor/qdev.h" +#include "hw/pci/pci.h" =20 #define VIRTIO_NET_VM_VERSION 11 =20 @@ -364,6 +368,9 @@ static void virtio_net_set_status(struct VirtIODevice *= vdev, uint8_t status) } } =20 + +static void virtio_net_primary_plug_timer(void *opaque); + static void virtio_net_set_link_status(NetClientState *nc) { VirtIONet *n =3D qemu_get_nic_opaque(nc); @@ -786,6 +793,14 @@ static void virtio_net_set_features(VirtIODevice *vdev= , uint64_t features) } else { memset(n->vlans, 0xff, MAX_VLAN >> 3); } + + if (virtio_has_feature(features, VIRTIO_NET_F_STANDBY)) { + atomic_set(&n->primary_should_be_hidden, false); + if (n->primary_device_timer) + timer_mod(n->primary_device_timer, + qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + + 4000); + } } =20 static int virtio_net_handle_rx_mode(VirtIONet *n, uint8_t cmd, @@ -2626,6 +2641,74 @@ void virtio_net_set_netclient_name(VirtIONet *n, con= st char *name, n->netclient_type =3D g_strdup(type); } =20 +static void virtio_net_primary_plug_timer(void *opaque) +{ + VirtIONet *n =3D opaque; + Error *err =3D NULL; + + n->primary_dev =3D qdev_device_add(n->primary_device_opts, &err); + if (!n->primary_dev && err) + { + if (n->primary_device_timer) + timer_mod(n->primary_device_timer, + qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + + 100); + } +} + +static void virtio_net_handle_migration_primary(VirtIONet *n, MigrationSta= te * s) +{ + Error *err =3D NULL; + bool should_be_hidden =3D atomic_read(&n->primary_should_be_hidden); + + if (migration_in_setup(s) && !should_be_hidden && n->primary_dev) { + /* Request unplug + * + * + */ + qdev_unplug(n->primary_dev, &err); + if (!err) + { + atomic_set(&n->primary_should_be_hidden, true); + n->primary_dev =3D NULL; + } + } else if (migration_has_failed(s)) { + if (should_be_hidden && !n->primary_dev) + { + /* We already unplugged the device let's plugged it back */ + n->primary_dev =3D qdev_device_add(n->primary_device_opts, &er= r); + } + else + { + } + } +} + +static void migration_state_notifier(Notifier *notifier, void *data) +{ + MigrationState *s =3D data; + VirtIONet *n =3D container_of(notifier, VirtIONet, migration_state); + virtio_net_handle_migration_primary(n,s); +} + +static void virtio_net_primary_should_be_hidden(DeviceListener *listener, = QemuOpts *device_opts, + bool *match_found, bool *res) +{ + VirtIONet *n =3D container_of(listener, VirtIONet, primary_listener); + const char * dev_id =3D qemu_opts_id(device_opts); + + *match_found =3D !strcmp(n->net_conf.primary_id_str ,dev_id); + if (atomic_read(&n->primary_should_be_hidden) && !strcmp(qemu_opt_get(= device_opts, "driver"), "vfio-pci") + && *match_found) + { + n->primary_device_opts =3D device_opts; + *res =3D true; + return; + } + + *res =3D false; +} + static void virtio_net_device_realize(DeviceState *dev, Error **errp) { VirtIODevice *vdev =3D VIRTIO_DEVICE(dev); @@ -2656,6 +2739,17 @@ static void virtio_net_device_realize(DeviceState *d= ev, Error **errp) n->host_features |=3D (1ULL << VIRTIO_NET_F_SPEED_DUPLEX); } =20 + if (n->net_conf.primary_id_str) { + n->primary_listener.should_be_hidden =3D virtio_net_primary_should= _be_hidden; + atomic_set(&n->primary_should_be_hidden, true); + device_listener_register(&n->primary_listener); + n->migration_state.notify =3D migration_state_notifier; + add_migration_state_change_notifier(&n->migration_state); + n->host_features |=3D (1ULL << VIRTIO_NET_F_STANDBY); + n->primary_device_timer =3D timer_new_ms(QEMU_CLOCK_VIRTUAL, + virtio_net_primary_plug_timer, n); + } + virtio_net_set_config_size(n, n->host_features); virtio_init(vdev, "virtio-net", VIRTIO_ID_NET, n->config_size); =20 @@ -2885,6 +2979,7 @@ static Property virtio_net_properties[] =3D { true), DEFINE_PROP_INT32("speed", VirtIONet, net_conf.speed, SPEED_UNKNOWN), DEFINE_PROP_STRING("duplex", VirtIONet, net_conf.duplex_str), + DEFINE_PROP_STRING("primary", VirtIONet, net_conf.primary_id_str), DEFINE_PROP_END_OF_LIST(), }; =20 diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h index b96f0c643f..ec5f387aa9 100644 --- a/include/hw/virtio/virtio-net.h +++ b/include/hw/virtio/virtio-net.h @@ -43,6 +43,7 @@ typedef struct virtio_net_conf int32_t speed; char *duplex_str; uint8_t duplex; + char *primary_id_str; } virtio_net_conf; =20 /* Coalesced packets type & status */ @@ -185,6 +186,12 @@ struct VirtIONet { AnnounceTimer announce_timer; bool needs_vnet_hdr_swap; bool mtu_bypass_backend; + QemuOpts *primary_device_opts; + DeviceState *primary_dev; + bool primary_should_be_hidden; + DeviceListener primary_listener; + QEMUTimer *primary_device_timer; + Notifier migration_state; }; =20 void virtio_net_set_netclient_name(VirtIONet *n, const char *name, --=20 2.20.1