All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] virtio-net: Convert feature properties to OnOffAuto
@ 2024-04-28  7:21 Akihiko Odaki
  2024-04-28  7:21 ` [PATCH 1/3] qdev-properties: Add DEFINE_PROP_ON_OFF_AUTO_BIT64() Akihiko Odaki
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Akihiko Odaki @ 2024-04-28  7:21 UTC (permalink / raw)
  To: Jason Wang, Dmitry Fleytman, Sriram Yagnaraman,
	Michael S. Tsirkin, Luigi Rizzo, Giuseppe Lettieri,
	Vincenzo Maffione, Andrew Melnychenko, Yuri Benditovich,
	Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost
  Cc: qemu-devel, 20240428-rss-v10-0-73cbaa91aeb6, Akihiko Odaki

Based-on: <20240428-rss-v10-0-73cbaa91aeb6@daynix.com>
("[PATCH v10 00/18] virtio-net RSS/hash report fixes and improvements")

Some features are not always available, and virtio-net used to disable
them when not available even if the corresponding properties were
explicitly set to "on".

Convert feature properties to OnOffAuto so that the user can explicitly
tell QEMU to automatically select the value by setting them "auto".
QEMU will give an error if they are set "on".

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
Akihiko Odaki (3):
      qdev-properties: Add DEFINE_PROP_ON_OFF_AUTO_BIT64()
      virtio-net: Convert feature properties to OnOffAuto
      virtio-net: Report RSS warning at device realization

 include/hw/qdev-properties.h   |  18 +++
 include/hw/virtio/virtio-net.h |   2 +-
 hw/core/qdev-properties.c      |  65 ++++++++++-
 hw/net/virtio-net.c            | 259 +++++++++++++++++++++++++----------------
 4 files changed, 239 insertions(+), 105 deletions(-)
---
base-commit: ec6325eec995018983a3f88f0e78ebf733a47b7e
change-id: 20240428-auto-be0dc010dda5

Best regards,
-- 
Akihiko Odaki <akihiko.odaki@daynix.com>



^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/3] qdev-properties: Add DEFINE_PROP_ON_OFF_AUTO_BIT64()
  2024-04-28  7:21 [PATCH 0/3] virtio-net: Convert feature properties to OnOffAuto Akihiko Odaki
@ 2024-04-28  7:21 ` Akihiko Odaki
  2024-04-30 14:41   ` Yuri Benditovich
  2024-04-28  7:21 ` [PATCH 2/3] virtio-net: Convert feature properties to OnOffAuto Akihiko Odaki
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 11+ messages in thread
From: Akihiko Odaki @ 2024-04-28  7:21 UTC (permalink / raw)
  To: Jason Wang, Dmitry Fleytman, Sriram Yagnaraman,
	Michael S. Tsirkin, Luigi Rizzo, Giuseppe Lettieri,
	Vincenzo Maffione, Andrew Melnychenko, Yuri Benditovich,
	Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost
  Cc: qemu-devel, 20240428-rss-v10-0-73cbaa91aeb6, Akihiko Odaki

DEFINE_PROP_ON_OFF_AUTO_BIT64() corresponds to DEFINE_PROP_ON_OFF_AUTO()
as DEFINE_PROP_BIT64() corresponds to DEFINE_PROP_BOOL(). The difference
is that DEFINE_PROP_ON_OFF_AUTO_BIT64() exposes OnOffAuto instead of
bool.

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
 include/hw/qdev-properties.h | 18 ++++++++++++
 hw/core/qdev-properties.c    | 65 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 82 insertions(+), 1 deletion(-)

diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 09aa04ca1e27..afec53a48470 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -43,11 +43,22 @@ struct PropertyInfo {
     ObjectPropertyRelease *release;
 };
 
+/**
+ * struct OnOffAutoBit64 - OnOffAuto storage with 64 elements.
+ * @on_bits: Bitmap of elements with "on".
+ * @auto_bits: Bitmap of elements with "auto".
+ */
+typedef struct OnOffAutoBit64 {
+    uint64_t on_bits;
+    uint64_t auto_bits;
+} OnOffAutoBit64;
+
 
 /*** qdev-properties.c ***/
 
 extern const PropertyInfo qdev_prop_bit;
 extern const PropertyInfo qdev_prop_bit64;
+extern const PropertyInfo qdev_prop_on_off_auto_bit64;
 extern const PropertyInfo qdev_prop_bool;
 extern const PropertyInfo qdev_prop_enum;
 extern const PropertyInfo qdev_prop_uint8;
@@ -100,6 +111,13 @@ extern const PropertyInfo qdev_prop_link;
                 .set_default = true,                              \
                 .defval.u  = (bool)_defval)
 
+#define DEFINE_PROP_ON_OFF_AUTO_BIT64(_name, _state, _field, _bit, _defval) \
+    DEFINE_PROP(_name, _state, _field, qdev_prop_on_off_auto_bit64,         \
+                OnOffAutoBit64,                                             \
+                .bitnr    = (_bit),                                         \
+                .set_default = true,                                        \
+                .defval.i = (OnOffAuto)_defval)
+
 #define DEFINE_PROP_BOOL(_name, _state, _field, _defval)     \
     DEFINE_PROP(_name, _state, _field, qdev_prop_bool, bool, \
                 .set_default = true,                         \
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 7d6fa726fdf2..b96f54a1b912 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -188,7 +188,8 @@ const PropertyInfo qdev_prop_bit = {
 
 static uint64_t qdev_get_prop_mask64(Property *prop)
 {
-    assert(prop->info == &qdev_prop_bit64);
+    assert(prop->info == &qdev_prop_bit64 ||
+           prop->info == &qdev_prop_on_off_auto_bit64);
     return 0x1ull << prop->bitnr;
 }
 
@@ -233,6 +234,68 @@ const PropertyInfo qdev_prop_bit64 = {
     .set_default_value = set_default_value_bool,
 };
 
+static void prop_get_on_off_auto_bit64(Object *obj, Visitor *v,
+                                       const char *name, void *opaque,
+                                       Error **errp)
+{
+    Property *prop = opaque;
+    OnOffAutoBit64 *p = object_field_prop_ptr(obj, prop);
+    int value;
+    uint64_t mask = qdev_get_prop_mask64(prop);
+
+    if (p->auto_bits & mask) {
+        value = ON_OFF_AUTO_AUTO;
+    } else if (p->on_bits & mask) {
+        value = ON_OFF_AUTO_ON;
+    } else {
+        value = ON_OFF_AUTO_OFF;
+    }
+
+    visit_type_enum(v, name, &value, &OnOffAuto_lookup, errp);
+}
+
+static void prop_set_on_off_auto_bit64(Object *obj, Visitor *v,
+                                       const char *name, void *opaque,
+                                       Error **errp)
+{
+    Property *prop = opaque;
+    OnOffAutoBit64 *p = object_field_prop_ptr(obj, prop);
+    int value;
+    uint64_t mask = qdev_get_prop_mask64(prop);
+
+    if (!visit_type_enum(v, name, &value, &OnOffAuto_lookup, errp)) {
+        return;
+    }
+
+    switch (value) {
+    case ON_OFF_AUTO_AUTO:
+        p->on_bits &= ~mask;
+        p->auto_bits |= mask;
+        break;
+
+    case ON_OFF_AUTO_ON:
+        p->on_bits |= mask;
+        p->auto_bits &= ~mask;
+        break;
+
+    case ON_OFF_AUTO_OFF:
+        p->on_bits &= ~mask;
+        p->auto_bits &= ~mask;
+        break;
+    }
+}
+
+const PropertyInfo qdev_prop_on_off_auto_bit64 = {
+    .name  = "bool",
+    .description = "on/off/auto",
+    .enum_table = &OnOffAuto_lookup,
+    .get = qdev_propinfo_get_enum,
+    .set = qdev_propinfo_set_enum,
+    .get = prop_get_on_off_auto_bit64,
+    .set = prop_set_on_off_auto_bit64,
+    .set_default_value = qdev_propinfo_set_default_value_enum,
+};
+
 /* --- bool --- */
 
 static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,

-- 
2.44.0



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/3] virtio-net: Convert feature properties to OnOffAuto
  2024-04-28  7:21 [PATCH 0/3] virtio-net: Convert feature properties to OnOffAuto Akihiko Odaki
  2024-04-28  7:21 ` [PATCH 1/3] qdev-properties: Add DEFINE_PROP_ON_OFF_AUTO_BIT64() Akihiko Odaki
@ 2024-04-28  7:21 ` Akihiko Odaki
  2024-04-30 15:02   ` Yuri Benditovich
  2024-04-28  7:21 ` [PATCH 3/3] virtio-net: Report RSS warning at device realization Akihiko Odaki
  2024-04-29  7:05 ` [PATCH 0/3] virtio-net: Convert feature properties to OnOffAuto Michael S. Tsirkin
  3 siblings, 1 reply; 11+ messages in thread
From: Akihiko Odaki @ 2024-04-28  7:21 UTC (permalink / raw)
  To: Jason Wang, Dmitry Fleytman, Sriram Yagnaraman,
	Michael S. Tsirkin, Luigi Rizzo, Giuseppe Lettieri,
	Vincenzo Maffione, Andrew Melnychenko, Yuri Benditovich,
	Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost
  Cc: qemu-devel, 20240428-rss-v10-0-73cbaa91aeb6, Akihiko Odaki

Some features are not always available, and virtio-net used to disable
them when not available even if the corresponding properties were
explicitly set to "on".

Convert feature properties to OnOffAuto so that the user can explicitly
tell QEMU to automatically select the value by setting them "auto".
QEMU will give an error if they are set "on".

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
 include/hw/virtio/virtio-net.h |   2 +-
 hw/net/virtio-net.c            | 247 +++++++++++++++++++++++++----------------
 2 files changed, 152 insertions(+), 97 deletions(-)

diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index 060c23c04d2d..ff32e30f001b 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -178,7 +178,7 @@ struct VirtIONet {
     uint32_t has_vnet_hdr;
     size_t host_hdr_len;
     size_t guest_hdr_len;
-    uint64_t host_features;
+    OnOffAutoBit64 host_features;
     uint32_t rsc_timeout;
     uint8_t rsc4_enabled;
     uint8_t rsc6_enabled;
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index c8059dc99bd4..5b6c901915a9 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -750,58 +750,96 @@ static void virtio_net_set_queue_pairs(VirtIONet *n)
 
 static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue);
 
+static bool virtio_net_clear_features(OnOffAutoBit64 *features,
+                                      uint64_t clear_bits,
+                                      const char *reason, Error **errp)
+{
+    if (features->on_bits & clear_bits) {
+        error_setg(errp, "%s", reason);
+        return false;
+    }
+
+    features->auto_bits &= ~clear_bits;
+
+    return true;
+}
+
 static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features,
                                         Error **errp)
 {
     VirtIONet *n = VIRTIO_NET(vdev);
     NetClientState *nc = qemu_get_queue(n->nic);
-
-    /* Firstly sync all virtio-net possible supported features */
-    features |= n->host_features;
-
-    virtio_add_feature(&features, VIRTIO_NET_F_MAC);
-
-    if (!peer_has_vnet_hdr(n)) {
-        virtio_clear_feature(&features, VIRTIO_NET_F_CSUM);
-        virtio_clear_feature(&features, VIRTIO_NET_F_HOST_TSO4);
-        virtio_clear_feature(&features, VIRTIO_NET_F_HOST_TSO6);
-        virtio_clear_feature(&features, VIRTIO_NET_F_HOST_ECN);
-
-        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_CSUM);
-        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_TSO4);
-        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_TSO6);
-        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_ECN);
-
-        virtio_clear_feature(&features, VIRTIO_NET_F_HOST_USO);
-        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_USO4);
-        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_USO6);
-
-        virtio_clear_feature(&features, VIRTIO_NET_F_HASH_REPORT);
-    }
-
-    if (!peer_has_vnet_hdr(n) || !peer_has_ufo(n)) {
-        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_UFO);
-        virtio_clear_feature(&features, VIRTIO_NET_F_HOST_UFO);
-    }
-
-    if (!peer_has_uso(n)) {
-        virtio_clear_feature(&features, VIRTIO_NET_F_HOST_USO);
-        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_USO4);
-        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_USO6);
+    OnOffAutoBit64 on_off_auto_features = n->host_features;
+
+    on_off_auto_features.on_bits |= features;
+    virtio_add_feature(&on_off_auto_features.auto_bits, VIRTIO_NET_F_MAC);
+
+    if (!((peer_has_vnet_hdr(n) ||
+           virtio_net_clear_features(&on_off_auto_features,
+                                     BIT_ULL(VIRTIO_NET_F_CSUM) |
+                                     BIT_ULL(VIRTIO_NET_F_HOST_TSO4) |
+                                     BIT_ULL(VIRTIO_NET_F_HOST_TSO6) |
+                                     BIT_ULL(VIRTIO_NET_F_HOST_ECN) |
+                                     BIT_ULL(VIRTIO_NET_F_GUEST_UFO) |
+                                     BIT_ULL(VIRTIO_NET_F_GUEST_CSUM) |
+                                     BIT_ULL(VIRTIO_NET_F_GUEST_TSO4) |
+                                     BIT_ULL(VIRTIO_NET_F_GUEST_TSO6) |
+                                     BIT_ULL(VIRTIO_NET_F_GUEST_ECN) |
+                                     BIT_ULL(VIRTIO_NET_F_HOST_UFO) |
+                                     BIT_ULL(VIRTIO_NET_F_HOST_USO) |
+                                     BIT_ULL(VIRTIO_NET_F_GUEST_USO4) |
+                                     BIT_ULL(VIRTIO_NET_F_GUEST_USO6) |
+                                     BIT_ULL(VIRTIO_NET_F_HASH_REPORT),
+                                     "A requested feature requires the peer to support virtio-net headers.",
+                                     errp)) &&
+          (peer_has_ufo(n) ||
+           virtio_net_clear_features(&on_off_auto_features,
+                                     BIT_ULL(VIRTIO_NET_F_GUEST_UFO) |
+                                     BIT_ULL(VIRTIO_NET_F_HOST_UFO),
+                                     "UFO is on but the peer does not support it.",
+                                     errp)) &&
+          (peer_has_uso(n) ||
+           virtio_net_clear_features(&on_off_auto_features,
+                                     BIT_ULL(VIRTIO_NET_F_HOST_USO) |
+                                     BIT_ULL(VIRTIO_NET_F_GUEST_USO4) |
+                                     BIT_ULL(VIRTIO_NET_F_GUEST_USO6),
+                                     "USO is on but the peer does not support it.",
+                                     errp)) &&
+          (virtio_has_feature(on_off_auto_features.on_bits |
+                              on_off_auto_features.auto_bits,
+                              VIRTIO_NET_F_CTRL_VQ) ||
+           virtio_net_clear_features(&on_off_auto_features,
+                                     BIT_ULL(VIRTIO_NET_F_GUEST_ANNOUNCE),
+                                     "guest_announce is on but ctrl_vq is off.",
+                                     errp)))) {
+        return 0;
     }
 
     if (!get_vhost_net(nc->peer)) {
-        return features;
+        if (!ebpf_rss_is_loaded(&n->ebpf_rss)) {
+            virtio_clear_feature(&on_off_auto_features.auto_bits,
+                                 VIRTIO_NET_F_RSS);
+        }
+
+        return on_off_auto_features.on_bits | on_off_auto_features.auto_bits;
     }
 
-    if (!ebpf_rss_is_loaded(&n->ebpf_rss)) {
-        virtio_clear_feature(&features, VIRTIO_NET_F_RSS);
+    if (!ebpf_rss_is_loaded(&n->ebpf_rss) &&
+        !virtio_net_clear_features(&on_off_auto_features,
+                                   BIT_ULL(VIRTIO_NET_F_RSS),
+                                   "Both RSS and vhost are on but eBPF is unavailable; fix eBPF or disable RSS.",
+                                   errp)) {
+        return 0;
     }
-    features = vhost_net_get_features(get_vhost_net(nc->peer), features);
+    features = vhost_net_get_features(get_vhost_net(nc->peer),
+                                      on_off_auto_features.on_bits |
+                                      on_off_auto_features.auto_bits);
     vdev->backend_features = features;
 
     if (n->mtu_bypass_backend &&
-            (n->host_features & 1ULL << VIRTIO_NET_F_MTU)) {
+        virtio_has_feature(on_off_auto_features.on_bits |
+                           on_off_auto_features.auto_bits,
+                           VIRTIO_NET_F_MTU)) {
         features |= (1ULL << VIRTIO_NET_F_MTU);
     }
 
@@ -820,6 +858,12 @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features,
         virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_ANNOUNCE);
     }
 
+    if ((features & on_off_auto_features.on_bits) !=
+        on_off_auto_features.on_bits) {
+        error_setg(errp, "A requested feature is incompatible with vhost.");
+        return 0;
+    }
+
     return features;
 }
 
@@ -3598,7 +3642,7 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
     int i;
 
     if (n->net_conf.mtu) {
-        n->host_features |= (1ULL << VIRTIO_NET_F_MTU);
+        n->host_features.on_bits |= (1ULL << VIRTIO_NET_F_MTU);
     }
 
     if (n->net_conf.duplex_str) {
@@ -3610,7 +3654,7 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
             error_setg(errp, "'duplex' must be 'half' or 'full'");
             return;
         }
-        n->host_features |= (1ULL << VIRTIO_NET_F_SPEED_DUPLEX);
+        n->host_features.on_bits |= (1ULL << VIRTIO_NET_F_SPEED_DUPLEX);
     } else {
         n->net_conf.duplex = DUPLEX_UNKNOWN;
     }
@@ -3620,7 +3664,7 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
         return;
     }
     if (n->net_conf.speed >= 0) {
-        n->host_features |= (1ULL << VIRTIO_NET_F_SPEED_DUPLEX);
+        n->host_features.on_bits |= (1ULL << VIRTIO_NET_F_SPEED_DUPLEX);
     }
 
     if (n->failover) {
@@ -3629,10 +3673,12 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
         device_listener_register(&n->primary_listener);
         migration_add_notifier(&n->migration_state,
                                virtio_net_migration_state_notifier);
-        n->host_features |= (1ULL << VIRTIO_NET_F_STANDBY);
+        n->host_features.on_bits |= (1ULL << VIRTIO_NET_F_STANDBY);
     }
 
-    virtio_net_set_config_size(n, n->host_features);
+    virtio_net_set_config_size(n,
+                               n->host_features.on_bits |
+                               n->host_features.auto_bits);
     virtio_init(vdev, VIRTIO_ID_NET, n->config_size);
 
     /*
@@ -3759,7 +3805,9 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
 
     net_rx_pkt_init(&n->rx_pkt);
 
-    if (virtio_has_feature(n->host_features, VIRTIO_NET_F_RSS)) {
+    if (virtio_has_feature(n->host_features.on_bits |
+                           n->host_features.auto_bits,
+                           VIRTIO_NET_F_RSS)) {
         virtio_net_load_ebpf(n);
     }
 }
@@ -3770,7 +3818,9 @@ static void virtio_net_device_unrealize(DeviceState *dev)
     VirtIONet *n = VIRTIO_NET(dev);
     int i, max_queue_pairs;
 
-    if (virtio_has_feature(n->host_features, VIRTIO_NET_F_RSS)) {
+    if (virtio_has_feature(n->host_features.on_bits |
+                           n->host_features.auto_bits,
+                           VIRTIO_NET_F_RSS)) {
         virtio_net_unload_ebpf(n);
     }
 
@@ -3914,53 +3964,58 @@ static const VMStateDescription vmstate_virtio_net = {
 };
 
 static Property virtio_net_properties[] = {
-    DEFINE_PROP_BIT64("csum", VirtIONet, host_features,
-                    VIRTIO_NET_F_CSUM, true),
-    DEFINE_PROP_BIT64("guest_csum", VirtIONet, host_features,
-                    VIRTIO_NET_F_GUEST_CSUM, true),
-    DEFINE_PROP_BIT64("gso", VirtIONet, host_features, VIRTIO_NET_F_GSO, true),
-    DEFINE_PROP_BIT64("guest_tso4", VirtIONet, host_features,
-                    VIRTIO_NET_F_GUEST_TSO4, true),
-    DEFINE_PROP_BIT64("guest_tso6", VirtIONet, host_features,
-                    VIRTIO_NET_F_GUEST_TSO6, true),
-    DEFINE_PROP_BIT64("guest_ecn", VirtIONet, host_features,
-                    VIRTIO_NET_F_GUEST_ECN, true),
-    DEFINE_PROP_BIT64("guest_ufo", VirtIONet, host_features,
-                    VIRTIO_NET_F_GUEST_UFO, true),
-    DEFINE_PROP_BIT64("guest_announce", VirtIONet, host_features,
-                    VIRTIO_NET_F_GUEST_ANNOUNCE, true),
-    DEFINE_PROP_BIT64("host_tso4", VirtIONet, host_features,
-                    VIRTIO_NET_F_HOST_TSO4, true),
-    DEFINE_PROP_BIT64("host_tso6", VirtIONet, host_features,
-                    VIRTIO_NET_F_HOST_TSO6, true),
-    DEFINE_PROP_BIT64("host_ecn", VirtIONet, host_features,
-                    VIRTIO_NET_F_HOST_ECN, true),
-    DEFINE_PROP_BIT64("host_ufo", VirtIONet, host_features,
-                    VIRTIO_NET_F_HOST_UFO, true),
-    DEFINE_PROP_BIT64("mrg_rxbuf", VirtIONet, host_features,
-                    VIRTIO_NET_F_MRG_RXBUF, true),
-    DEFINE_PROP_BIT64("status", VirtIONet, host_features,
-                    VIRTIO_NET_F_STATUS, true),
-    DEFINE_PROP_BIT64("ctrl_vq", VirtIONet, host_features,
-                    VIRTIO_NET_F_CTRL_VQ, true),
-    DEFINE_PROP_BIT64("ctrl_rx", VirtIONet, host_features,
-                    VIRTIO_NET_F_CTRL_RX, true),
-    DEFINE_PROP_BIT64("ctrl_vlan", VirtIONet, host_features,
-                    VIRTIO_NET_F_CTRL_VLAN, true),
-    DEFINE_PROP_BIT64("ctrl_rx_extra", VirtIONet, host_features,
-                    VIRTIO_NET_F_CTRL_RX_EXTRA, true),
-    DEFINE_PROP_BIT64("ctrl_mac_addr", VirtIONet, host_features,
-                    VIRTIO_NET_F_CTRL_MAC_ADDR, true),
-    DEFINE_PROP_BIT64("ctrl_guest_offloads", VirtIONet, host_features,
-                    VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, true),
-    DEFINE_PROP_BIT64("mq", VirtIONet, host_features, VIRTIO_NET_F_MQ, false),
-    DEFINE_PROP_BIT64("rss", VirtIONet, host_features,
-                    VIRTIO_NET_F_RSS, false),
-    DEFINE_PROP_BIT64("hash", VirtIONet, host_features,
-                    VIRTIO_NET_F_HASH_REPORT, false),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("csum", VirtIONet, host_features,
+                                  VIRTIO_NET_F_CSUM, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("guest_csum", VirtIONet, host_features,
+                                  VIRTIO_NET_F_GUEST_CSUM, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("gso", VirtIONet, host_features,
+                                  VIRTIO_NET_F_GSO, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("guest_tso4", VirtIONet, host_features,
+                                  VIRTIO_NET_F_GUEST_TSO4, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("guest_tso6", VirtIONet, host_features,
+                                  VIRTIO_NET_F_GUEST_TSO6, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("guest_ecn", VirtIONet, host_features,
+                                  VIRTIO_NET_F_GUEST_ECN, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("guest_ufo", VirtIONet, host_features,
+                                  VIRTIO_NET_F_GUEST_UFO, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("guest_announce", VirtIONet, host_features,
+                                  VIRTIO_NET_F_GUEST_ANNOUNCE,
+                                  ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("host_tso4", VirtIONet, host_features,
+                                  VIRTIO_NET_F_HOST_TSO4, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("host_tso6", VirtIONet, host_features,
+                                  VIRTIO_NET_F_HOST_TSO6, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("host_ecn", VirtIONet, host_features,
+                                  VIRTIO_NET_F_HOST_ECN, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("host_ufo", VirtIONet, host_features,
+                                  VIRTIO_NET_F_HOST_UFO, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("mrg_rxbuf", VirtIONet, host_features,
+                                  VIRTIO_NET_F_MRG_RXBUF, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("status", VirtIONet, host_features,
+                                  VIRTIO_NET_F_STATUS, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("ctrl_vq", VirtIONet, host_features,
+                                  VIRTIO_NET_F_CTRL_VQ, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("ctrl_rx", VirtIONet, host_features,
+                                  VIRTIO_NET_F_CTRL_RX, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("ctrl_vlan", VirtIONet, host_features,
+                                  VIRTIO_NET_F_CTRL_VLAN, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("ctrl_rx_extra", VirtIONet, host_features,
+                                  VIRTIO_NET_F_CTRL_RX_EXTRA, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("ctrl_mac_addr", VirtIONet, host_features,
+                                  VIRTIO_NET_F_CTRL_MAC_ADDR, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("ctrl_guest_offloads", VirtIONet,
+                                  host_features,
+                                  VIRTIO_NET_F_CTRL_GUEST_OFFLOADS,
+                                  ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("mq", VirtIONet, host_features,
+                                  VIRTIO_NET_F_MQ, ON_OFF_AUTO_OFF),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("rss", VirtIONet, host_features,
+                                  VIRTIO_NET_F_RSS, ON_OFF_AUTO_OFF),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("hash", VirtIONet, host_features,
+                                  VIRTIO_NET_F_HASH_REPORT, ON_OFF_AUTO_OFF),
     DEFINE_PROP_ARRAY("ebpf-rss-fds", VirtIONet, nr_ebpf_rss_fds,
                       ebpf_rss_fds, qdev_prop_string, char*),
-    DEFINE_PROP_BIT64("guest_rsc_ext", VirtIONet, host_features,
+    DEFINE_PROP_BIT64("guest_rsc_ext", VirtIONet, host_features.on_bits,
                     VIRTIO_NET_F_RSC_EXT, false),
     DEFINE_PROP_UINT32("rsc_interval", VirtIONet, rsc_timeout,
                        VIRTIO_NET_RSC_DEFAULT_INTERVAL),
@@ -3979,12 +4034,12 @@ static Property virtio_net_properties[] = {
     DEFINE_PROP_INT32("speed", VirtIONet, net_conf.speed, SPEED_UNKNOWN),
     DEFINE_PROP_STRING("duplex", VirtIONet, net_conf.duplex_str),
     DEFINE_PROP_BOOL("failover", VirtIONet, failover, false),
-    DEFINE_PROP_BIT64("guest_uso4", VirtIONet, host_features,
-                      VIRTIO_NET_F_GUEST_USO4, true),
-    DEFINE_PROP_BIT64("guest_uso6", VirtIONet, host_features,
-                      VIRTIO_NET_F_GUEST_USO6, true),
-    DEFINE_PROP_BIT64("host_uso", VirtIONet, host_features,
-                      VIRTIO_NET_F_HOST_USO, true),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("guest_uso4", VirtIONet, host_features,
+                                  VIRTIO_NET_F_GUEST_USO4, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("guest_uso6", VirtIONet, host_features,
+                                  VIRTIO_NET_F_GUEST_USO6, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT64("host_uso", VirtIONet, host_features,
+                                  VIRTIO_NET_F_HOST_USO, ON_OFF_AUTO_AUTO),
     DEFINE_PROP_END_OF_LIST(),
 };
 

-- 
2.44.0



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/3] virtio-net: Report RSS warning at device realization
  2024-04-28  7:21 [PATCH 0/3] virtio-net: Convert feature properties to OnOffAuto Akihiko Odaki
  2024-04-28  7:21 ` [PATCH 1/3] qdev-properties: Add DEFINE_PROP_ON_OFF_AUTO_BIT64() Akihiko Odaki
  2024-04-28  7:21 ` [PATCH 2/3] virtio-net: Convert feature properties to OnOffAuto Akihiko Odaki
@ 2024-04-28  7:21 ` Akihiko Odaki
  2024-04-29  7:05 ` [PATCH 0/3] virtio-net: Convert feature properties to OnOffAuto Michael S. Tsirkin
  3 siblings, 0 replies; 11+ messages in thread
From: Akihiko Odaki @ 2024-04-28  7:21 UTC (permalink / raw)
  To: Jason Wang, Dmitry Fleytman, Sriram Yagnaraman,
	Michael S. Tsirkin, Luigi Rizzo, Giuseppe Lettieri,
	Vincenzo Maffione, Andrew Melnychenko, Yuri Benditovich,
	Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost
  Cc: qemu-devel, 20240428-rss-v10-0-73cbaa91aeb6, Akihiko Odaki

Warning about RSS fallback at device realization allows the user to
notice the configuration problem early.

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
 hw/net/virtio-net.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 5b6c901915a9..e1a6d43de283 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -817,6 +817,10 @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features,
 
     if (!get_vhost_net(nc->peer)) {
         if (!ebpf_rss_is_loaded(&n->ebpf_rss)) {
+            if (on_off_auto_features.on_bits & VIRTIO_NET_F_RSS) {
+                warn_report("Can't load eBPF RSS - fallback to software RSS");
+            }
+
             virtio_clear_feature(&on_off_auto_features.auto_bits,
                                  VIRTIO_NET_F_RSS);
         }
@@ -1327,16 +1331,10 @@ static void virtio_net_detach_epbf_rss(VirtIONet *n)
 static void virtio_net_commit_rss_config(VirtIONet *n)
 {
     if (n->rss_data.enabled) {
-        n->rss_data.enabled_software_rss = n->rss_data.populate_hash;
+        n->rss_data.enabled_software_rss = n->rss_data.populate_hash ||
+                                           !virtio_net_attach_epbf_rss(n);
         if (n->rss_data.populate_hash) {
             virtio_net_detach_epbf_rss(n);
-        } else if (!virtio_net_attach_epbf_rss(n)) {
-            if (get_vhost_net(qemu_get_queue(n->nic)->peer)) {
-                warn_report("Can't load eBPF RSS for vhost");
-            } else {
-                warn_report("Can't load eBPF RSS - fallback to software RSS");
-                n->rss_data.enabled_software_rss = true;
-            }
         }
 
         trace_virtio_net_rss_enable(n->rss_data.hash_types,

-- 
2.44.0



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 0/3] virtio-net: Convert feature properties to OnOffAuto
  2024-04-28  7:21 [PATCH 0/3] virtio-net: Convert feature properties to OnOffAuto Akihiko Odaki
                   ` (2 preceding siblings ...)
  2024-04-28  7:21 ` [PATCH 3/3] virtio-net: Report RSS warning at device realization Akihiko Odaki
@ 2024-04-29  7:05 ` Michael S. Tsirkin
  2024-05-01  7:20   ` Akihiko Odaki
  3 siblings, 1 reply; 11+ messages in thread
From: Michael S. Tsirkin @ 2024-04-29  7:05 UTC (permalink / raw)
  To: Akihiko Odaki
  Cc: Jason Wang, Dmitry Fleytman, Sriram Yagnaraman, Luigi Rizzo,
	Giuseppe Lettieri, Vincenzo Maffione, Andrew Melnychenko,
	Yuri Benditovich, Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost, qemu-devel, 20240428-rss-v10-0-73cbaa91aeb6

On Sun, Apr 28, 2024 at 04:21:06PM +0900, Akihiko Odaki wrote:
> Based-on: <20240428-rss-v10-0-73cbaa91aeb6@daynix.com>
> ("[PATCH v10 00/18] virtio-net RSS/hash report fixes and improvements")
> 
> Some features are not always available, and virtio-net used to disable
> them when not available even if the corresponding properties were
> explicitly set to "on".
> 
> Convert feature properties to OnOffAuto so that the user can explicitly
> tell QEMU to automatically select the value by setting them "auto".
> QEMU will give an error if they are set "on".
> 
> Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>

Should we maybe bite the bullet allow "auto" for all binary/boolean
properties? Just ignore "auto" if no one cares ATM.



> ---
> Akihiko Odaki (3):
>       qdev-properties: Add DEFINE_PROP_ON_OFF_AUTO_BIT64()
>       virtio-net: Convert feature properties to OnOffAuto
>       virtio-net: Report RSS warning at device realization
> 
>  include/hw/qdev-properties.h   |  18 +++
>  include/hw/virtio/virtio-net.h |   2 +-
>  hw/core/qdev-properties.c      |  65 ++++++++++-
>  hw/net/virtio-net.c            | 259 +++++++++++++++++++++++++----------------
>  4 files changed, 239 insertions(+), 105 deletions(-)
> ---
> base-commit: ec6325eec995018983a3f88f0e78ebf733a47b7e
> change-id: 20240428-auto-be0dc010dda5
> 
> Best regards,
> -- 
> Akihiko Odaki <akihiko.odaki@daynix.com>



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/3] qdev-properties: Add DEFINE_PROP_ON_OFF_AUTO_BIT64()
  2024-04-28  7:21 ` [PATCH 1/3] qdev-properties: Add DEFINE_PROP_ON_OFF_AUTO_BIT64() Akihiko Odaki
@ 2024-04-30 14:41   ` Yuri Benditovich
  2024-05-01  6:36     ` Akihiko Odaki
  0 siblings, 1 reply; 11+ messages in thread
From: Yuri Benditovich @ 2024-04-30 14:41 UTC (permalink / raw)
  To: Akihiko Odaki
  Cc: Jason Wang, Dmitry Fleytman, Sriram Yagnaraman,
	Michael S. Tsirkin, Luigi Rizzo, Giuseppe Lettieri,
	Vincenzo Maffione, Andrew Melnychenko, Paolo Bonzini,
	Daniel P. Berrangé,
	Eduardo Habkost, qemu-devel, 20240428-rss-v10-0-73cbaa91aeb6

On Sun, Apr 28, 2024 at 10:21 AM Akihiko Odaki <akihiko.odaki@daynix.com> wrote:
>
> DEFINE_PROP_ON_OFF_AUTO_BIT64() corresponds to DEFINE_PROP_ON_OFF_AUTO()
> as DEFINE_PROP_BIT64() corresponds to DEFINE_PROP_BOOL(). The difference
> is that DEFINE_PROP_ON_OFF_AUTO_BIT64() exposes OnOffAuto instead of
> bool.
>
> Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
> ---
>  include/hw/qdev-properties.h | 18 ++++++++++++
>  hw/core/qdev-properties.c    | 65 +++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 82 insertions(+), 1 deletion(-)
>
> diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
> index 09aa04ca1e27..afec53a48470 100644
> --- a/include/hw/qdev-properties.h
> +++ b/include/hw/qdev-properties.h
> @@ -43,11 +43,22 @@ struct PropertyInfo {
>      ObjectPropertyRelease *release;
>  };
>
> +/**
> + * struct OnOffAutoBit64 - OnOffAuto storage with 64 elements.
> + * @on_bits: Bitmap of elements with "on".
> + * @auto_bits: Bitmap of elements with "auto".
> + */
> +typedef struct OnOffAutoBit64 {
> +    uint64_t on_bits;
> +    uint64_t auto_bits;
> +} OnOffAutoBit64;
> +
>
>  /*** qdev-properties.c ***/
>
>  extern const PropertyInfo qdev_prop_bit;
>  extern const PropertyInfo qdev_prop_bit64;
> +extern const PropertyInfo qdev_prop_on_off_auto_bit64;
>  extern const PropertyInfo qdev_prop_bool;
>  extern const PropertyInfo qdev_prop_enum;
>  extern const PropertyInfo qdev_prop_uint8;
> @@ -100,6 +111,13 @@ extern const PropertyInfo qdev_prop_link;
>                  .set_default = true,                              \
>                  .defval.u  = (bool)_defval)
>
> +#define DEFINE_PROP_ON_OFF_AUTO_BIT64(_name, _state, _field, _bit, _defval) \
> +    DEFINE_PROP(_name, _state, _field, qdev_prop_on_off_auto_bit64,         \
> +                OnOffAutoBit64,                                             \
> +                .bitnr    = (_bit),                                         \
> +                .set_default = true,                                        \
> +                .defval.i = (OnOffAuto)_defval)
> +
>  #define DEFINE_PROP_BOOL(_name, _state, _field, _defval)     \
>      DEFINE_PROP(_name, _state, _field, qdev_prop_bool, bool, \
>                  .set_default = true,                         \
> diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
> index 7d6fa726fdf2..b96f54a1b912 100644
> --- a/hw/core/qdev-properties.c
> +++ b/hw/core/qdev-properties.c
> @@ -188,7 +188,8 @@ const PropertyInfo qdev_prop_bit = {
>
>  static uint64_t qdev_get_prop_mask64(Property *prop)
>  {
> -    assert(prop->info == &qdev_prop_bit64);
> +    assert(prop->info == &qdev_prop_bit64 ||
> +           prop->info == &qdev_prop_on_off_auto_bit64);
>      return 0x1ull << prop->bitnr;
>  }
>
> @@ -233,6 +234,68 @@ const PropertyInfo qdev_prop_bit64 = {
>      .set_default_value = set_default_value_bool,
>  };
>
> +static void prop_get_on_off_auto_bit64(Object *obj, Visitor *v,
> +                                       const char *name, void *opaque,
> +                                       Error **errp)
> +{
> +    Property *prop = opaque;
> +    OnOffAutoBit64 *p = object_field_prop_ptr(obj, prop);
> +    int value;
> +    uint64_t mask = qdev_get_prop_mask64(prop);
> +
> +    if (p->auto_bits & mask) {
> +        value = ON_OFF_AUTO_AUTO;
> +    } else if (p->on_bits & mask) {
> +        value = ON_OFF_AUTO_ON;
> +    } else {
> +        value = ON_OFF_AUTO_OFF;
> +    }
> +
> +    visit_type_enum(v, name, &value, &OnOffAuto_lookup, errp);
> +}
> +
> +static void prop_set_on_off_auto_bit64(Object *obj, Visitor *v,
> +                                       const char *name, void *opaque,
> +                                       Error **errp)
> +{
> +    Property *prop = opaque;
> +    OnOffAutoBit64 *p = object_field_prop_ptr(obj, prop);
> +    int value;
> +    uint64_t mask = qdev_get_prop_mask64(prop);
> +
> +    if (!visit_type_enum(v, name, &value, &OnOffAuto_lookup, errp)) {
> +        return;
> +    }
> +
> +    switch (value) {
> +    case ON_OFF_AUTO_AUTO:
> +        p->on_bits &= ~mask;
> +        p->auto_bits |= mask;
> +        break;
> +
> +    case ON_OFF_AUTO_ON:
> +        p->on_bits |= mask;
> +        p->auto_bits &= ~mask;
> +        break;
> +
> +    case ON_OFF_AUTO_OFF:
> +        p->on_bits &= ~mask;
> +        p->auto_bits &= ~mask;
> +        break;
> +    }
> +}
> +
> +const PropertyInfo qdev_prop_on_off_auto_bit64 = {
> +    .name  = "bool",

Does it mean that the name of this tristate type is "bool"? Or I miss something?

> +    .description = "on/off/auto",
> +    .enum_table = &OnOffAuto_lookup,
> +    .get = qdev_propinfo_get_enum,
> +    .set = qdev_propinfo_set_enum,
> +    .get = prop_get_on_off_auto_bit64,
> +    .set = prop_set_on_off_auto_bit64,
> +    .set_default_value = qdev_propinfo_set_default_value_enum,
> +};
> +
>  /* --- bool --- */
>
>  static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
>
> --
> 2.44.0
>


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/3] virtio-net: Convert feature properties to OnOffAuto
  2024-04-28  7:21 ` [PATCH 2/3] virtio-net: Convert feature properties to OnOffAuto Akihiko Odaki
@ 2024-04-30 15:02   ` Yuri Benditovich
  2024-05-01  7:06     ` Akihiko Odaki
  0 siblings, 1 reply; 11+ messages in thread
From: Yuri Benditovich @ 2024-04-30 15:02 UTC (permalink / raw)
  To: Akihiko Odaki
  Cc: Jason Wang, Dmitry Fleytman, Sriram Yagnaraman,
	Michael S. Tsirkin, Luigi Rizzo, Giuseppe Lettieri,
	Vincenzo Maffione, Andrew Melnychenko, Paolo Bonzini,
	Daniel P. Berrangé,
	Eduardo Habkost, qemu-devel

Question:
How will libvirt (as an example) work with this change. In the
existing semantic of libvirt profile the "on" means "on if possible"
and using existing profile after qemu update will still use "on" with
meaning "force"?
Typically this is solved by machine type - if libvirt uses
'machine='pc-q35-8.1'' this will be backward-compatible.
How will this change be accepted?

On Sun, Apr 28, 2024 at 10:21 AM Akihiko Odaki <akihiko.odaki@daynix.com> wrote:
>
> Some features are not always available, and virtio-net used to disable
> them when not available even if the corresponding properties were
> explicitly set to "on".
>
> Convert feature properties to OnOffAuto so that the user can explicitly
> tell QEMU to automatically select the value by setting them "auto".
> QEMU will give an error if they are set "on".
>
> Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
> ---
>  include/hw/virtio/virtio-net.h |   2 +-
>  hw/net/virtio-net.c            | 247 +++++++++++++++++++++++++----------------
>  2 files changed, 152 insertions(+), 97 deletions(-)
>
> diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
> index 060c23c04d2d..ff32e30f001b 100644
> --- a/include/hw/virtio/virtio-net.h
> +++ b/include/hw/virtio/virtio-net.h
> @@ -178,7 +178,7 @@ struct VirtIONet {
>      uint32_t has_vnet_hdr;
>      size_t host_hdr_len;
>      size_t guest_hdr_len;
> -    uint64_t host_features;
> +    OnOffAutoBit64 host_features;
>      uint32_t rsc_timeout;
>      uint8_t rsc4_enabled;
>      uint8_t rsc6_enabled;
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index c8059dc99bd4..5b6c901915a9 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -750,58 +750,96 @@ static void virtio_net_set_queue_pairs(VirtIONet *n)
>
>  static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue);
>
> +static bool virtio_net_clear_features(OnOffAutoBit64 *features,
> +                                      uint64_t clear_bits,
> +                                      const char *reason, Error **errp)
> +{
> +    if (features->on_bits & clear_bits) {
> +        error_setg(errp, "%s", reason);
> +        return false;
> +    }
> +
> +    features->auto_bits &= ~clear_bits;
> +
> +    return true;
> +}
> +
>  static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features,
>                                          Error **errp)
>  {
>      VirtIONet *n = VIRTIO_NET(vdev);
>      NetClientState *nc = qemu_get_queue(n->nic);
> -
> -    /* Firstly sync all virtio-net possible supported features */
> -    features |= n->host_features;
> -
> -    virtio_add_feature(&features, VIRTIO_NET_F_MAC);
> -
> -    if (!peer_has_vnet_hdr(n)) {
> -        virtio_clear_feature(&features, VIRTIO_NET_F_CSUM);
> -        virtio_clear_feature(&features, VIRTIO_NET_F_HOST_TSO4);
> -        virtio_clear_feature(&features, VIRTIO_NET_F_HOST_TSO6);
> -        virtio_clear_feature(&features, VIRTIO_NET_F_HOST_ECN);
> -
> -        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_CSUM);
> -        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_TSO4);
> -        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_TSO6);
> -        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_ECN);
> -
> -        virtio_clear_feature(&features, VIRTIO_NET_F_HOST_USO);
> -        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_USO4);
> -        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_USO6);
> -
> -        virtio_clear_feature(&features, VIRTIO_NET_F_HASH_REPORT);
> -    }
> -
> -    if (!peer_has_vnet_hdr(n) || !peer_has_ufo(n)) {
> -        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_UFO);
> -        virtio_clear_feature(&features, VIRTIO_NET_F_HOST_UFO);
> -    }
> -
> -    if (!peer_has_uso(n)) {
> -        virtio_clear_feature(&features, VIRTIO_NET_F_HOST_USO);
> -        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_USO4);
> -        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_USO6);
> +    OnOffAutoBit64 on_off_auto_features = n->host_features;
> +
> +    on_off_auto_features.on_bits |= features;
> +    virtio_add_feature(&on_off_auto_features.auto_bits, VIRTIO_NET_F_MAC);
> +
> +    if (!((peer_has_vnet_hdr(n) ||
> +           virtio_net_clear_features(&on_off_auto_features,
> +                                     BIT_ULL(VIRTIO_NET_F_CSUM) |
> +                                     BIT_ULL(VIRTIO_NET_F_HOST_TSO4) |
> +                                     BIT_ULL(VIRTIO_NET_F_HOST_TSO6) |
> +                                     BIT_ULL(VIRTIO_NET_F_HOST_ECN) |
> +                                     BIT_ULL(VIRTIO_NET_F_GUEST_UFO) |
> +                                     BIT_ULL(VIRTIO_NET_F_GUEST_CSUM) |
> +                                     BIT_ULL(VIRTIO_NET_F_GUEST_TSO4) |
> +                                     BIT_ULL(VIRTIO_NET_F_GUEST_TSO6) |
> +                                     BIT_ULL(VIRTIO_NET_F_GUEST_ECN) |
> +                                     BIT_ULL(VIRTIO_NET_F_HOST_UFO) |
> +                                     BIT_ULL(VIRTIO_NET_F_HOST_USO) |
> +                                     BIT_ULL(VIRTIO_NET_F_GUEST_USO4) |
> +                                     BIT_ULL(VIRTIO_NET_F_GUEST_USO6) |
> +                                     BIT_ULL(VIRTIO_NET_F_HASH_REPORT),
> +                                     "A requested feature requires the peer to support virtio-net headers.",
> +                                     errp)) &&
> +          (peer_has_ufo(n) ||
> +           virtio_net_clear_features(&on_off_auto_features,
> +                                     BIT_ULL(VIRTIO_NET_F_GUEST_UFO) |
> +                                     BIT_ULL(VIRTIO_NET_F_HOST_UFO),
> +                                     "UFO is on but the peer does not support it.",
> +                                     errp)) &&
> +          (peer_has_uso(n) ||
> +           virtio_net_clear_features(&on_off_auto_features,
> +                                     BIT_ULL(VIRTIO_NET_F_HOST_USO) |
> +                                     BIT_ULL(VIRTIO_NET_F_GUEST_USO4) |
> +                                     BIT_ULL(VIRTIO_NET_F_GUEST_USO6),
> +                                     "USO is on but the peer does not support it.",
> +                                     errp)) &&
> +          (virtio_has_feature(on_off_auto_features.on_bits |
> +                              on_off_auto_features.auto_bits,
> +                              VIRTIO_NET_F_CTRL_VQ) ||
> +           virtio_net_clear_features(&on_off_auto_features,
> +                                     BIT_ULL(VIRTIO_NET_F_GUEST_ANNOUNCE),
> +                                     "guest_announce is on but ctrl_vq is off.",
> +                                     errp)))) {
> +        return 0;
>      }
>
>      if (!get_vhost_net(nc->peer)) {
> -        return features;
> +        if (!ebpf_rss_is_loaded(&n->ebpf_rss)) {
> +            virtio_clear_feature(&on_off_auto_features.auto_bits,
> +                                 VIRTIO_NET_F_RSS);
> +        }
> +
> +        return on_off_auto_features.on_bits | on_off_auto_features.auto_bits;
>      }
>
> -    if (!ebpf_rss_is_loaded(&n->ebpf_rss)) {
> -        virtio_clear_feature(&features, VIRTIO_NET_F_RSS);
> +    if (!ebpf_rss_is_loaded(&n->ebpf_rss) &&
> +        !virtio_net_clear_features(&on_off_auto_features,
> +                                   BIT_ULL(VIRTIO_NET_F_RSS),
> +                                   "Both RSS and vhost are on but eBPF is unavailable; fix eBPF or disable RSS.",
> +                                   errp)) {
> +        return 0;
>      }
> -    features = vhost_net_get_features(get_vhost_net(nc->peer), features);
> +    features = vhost_net_get_features(get_vhost_net(nc->peer),
> +                                      on_off_auto_features.on_bits |
> +                                      on_off_auto_features.auto_bits);
>      vdev->backend_features = features;
>
>      if (n->mtu_bypass_backend &&
> -            (n->host_features & 1ULL << VIRTIO_NET_F_MTU)) {
> +        virtio_has_feature(on_off_auto_features.on_bits |
> +                           on_off_auto_features.auto_bits,
> +                           VIRTIO_NET_F_MTU)) {
>          features |= (1ULL << VIRTIO_NET_F_MTU);
>      }
>
> @@ -820,6 +858,12 @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features,
>          virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_ANNOUNCE);
>      }
>
> +    if ((features & on_off_auto_features.on_bits) !=
> +        on_off_auto_features.on_bits) {
> +        error_setg(errp, "A requested feature is incompatible with vhost.");
> +        return 0;
> +    }
> +
>      return features;
>  }
>
> @@ -3598,7 +3642,7 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
>      int i;
>
>      if (n->net_conf.mtu) {
> -        n->host_features |= (1ULL << VIRTIO_NET_F_MTU);
> +        n->host_features.on_bits |= (1ULL << VIRTIO_NET_F_MTU);
>      }
>
>      if (n->net_conf.duplex_str) {
> @@ -3610,7 +3654,7 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
>              error_setg(errp, "'duplex' must be 'half' or 'full'");
>              return;
>          }
> -        n->host_features |= (1ULL << VIRTIO_NET_F_SPEED_DUPLEX);
> +        n->host_features.on_bits |= (1ULL << VIRTIO_NET_F_SPEED_DUPLEX);
>      } else {
>          n->net_conf.duplex = DUPLEX_UNKNOWN;
>      }
> @@ -3620,7 +3664,7 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
>          return;
>      }
>      if (n->net_conf.speed >= 0) {
> -        n->host_features |= (1ULL << VIRTIO_NET_F_SPEED_DUPLEX);
> +        n->host_features.on_bits |= (1ULL << VIRTIO_NET_F_SPEED_DUPLEX);
>      }
>
>      if (n->failover) {
> @@ -3629,10 +3673,12 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
>          device_listener_register(&n->primary_listener);
>          migration_add_notifier(&n->migration_state,
>                                 virtio_net_migration_state_notifier);
> -        n->host_features |= (1ULL << VIRTIO_NET_F_STANDBY);
> +        n->host_features.on_bits |= (1ULL << VIRTIO_NET_F_STANDBY);
>      }
>
> -    virtio_net_set_config_size(n, n->host_features);
> +    virtio_net_set_config_size(n,
> +                               n->host_features.on_bits |
> +                               n->host_features.auto_bits);
>      virtio_init(vdev, VIRTIO_ID_NET, n->config_size);
>
>      /*
> @@ -3759,7 +3805,9 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
>
>      net_rx_pkt_init(&n->rx_pkt);
>
> -    if (virtio_has_feature(n->host_features, VIRTIO_NET_F_RSS)) {
> +    if (virtio_has_feature(n->host_features.on_bits |
> +                           n->host_features.auto_bits,
> +                           VIRTIO_NET_F_RSS)) {
>          virtio_net_load_ebpf(n);
>      }
>  }
> @@ -3770,7 +3818,9 @@ static void virtio_net_device_unrealize(DeviceState *dev)
>      VirtIONet *n = VIRTIO_NET(dev);
>      int i, max_queue_pairs;
>
> -    if (virtio_has_feature(n->host_features, VIRTIO_NET_F_RSS)) {
> +    if (virtio_has_feature(n->host_features.on_bits |
> +                           n->host_features.auto_bits,
> +                           VIRTIO_NET_F_RSS)) {
>          virtio_net_unload_ebpf(n);
>      }
>
> @@ -3914,53 +3964,58 @@ static const VMStateDescription vmstate_virtio_net = {
>  };
>
>  static Property virtio_net_properties[] = {
> -    DEFINE_PROP_BIT64("csum", VirtIONet, host_features,
> -                    VIRTIO_NET_F_CSUM, true),
> -    DEFINE_PROP_BIT64("guest_csum", VirtIONet, host_features,
> -                    VIRTIO_NET_F_GUEST_CSUM, true),
> -    DEFINE_PROP_BIT64("gso", VirtIONet, host_features, VIRTIO_NET_F_GSO, true),
> -    DEFINE_PROP_BIT64("guest_tso4", VirtIONet, host_features,
> -                    VIRTIO_NET_F_GUEST_TSO4, true),
> -    DEFINE_PROP_BIT64("guest_tso6", VirtIONet, host_features,
> -                    VIRTIO_NET_F_GUEST_TSO6, true),
> -    DEFINE_PROP_BIT64("guest_ecn", VirtIONet, host_features,
> -                    VIRTIO_NET_F_GUEST_ECN, true),
> -    DEFINE_PROP_BIT64("guest_ufo", VirtIONet, host_features,
> -                    VIRTIO_NET_F_GUEST_UFO, true),
> -    DEFINE_PROP_BIT64("guest_announce", VirtIONet, host_features,
> -                    VIRTIO_NET_F_GUEST_ANNOUNCE, true),
> -    DEFINE_PROP_BIT64("host_tso4", VirtIONet, host_features,
> -                    VIRTIO_NET_F_HOST_TSO4, true),
> -    DEFINE_PROP_BIT64("host_tso6", VirtIONet, host_features,
> -                    VIRTIO_NET_F_HOST_TSO6, true),
> -    DEFINE_PROP_BIT64("host_ecn", VirtIONet, host_features,
> -                    VIRTIO_NET_F_HOST_ECN, true),
> -    DEFINE_PROP_BIT64("host_ufo", VirtIONet, host_features,
> -                    VIRTIO_NET_F_HOST_UFO, true),
> -    DEFINE_PROP_BIT64("mrg_rxbuf", VirtIONet, host_features,
> -                    VIRTIO_NET_F_MRG_RXBUF, true),
> -    DEFINE_PROP_BIT64("status", VirtIONet, host_features,
> -                    VIRTIO_NET_F_STATUS, true),
> -    DEFINE_PROP_BIT64("ctrl_vq", VirtIONet, host_features,
> -                    VIRTIO_NET_F_CTRL_VQ, true),
> -    DEFINE_PROP_BIT64("ctrl_rx", VirtIONet, host_features,
> -                    VIRTIO_NET_F_CTRL_RX, true),
> -    DEFINE_PROP_BIT64("ctrl_vlan", VirtIONet, host_features,
> -                    VIRTIO_NET_F_CTRL_VLAN, true),
> -    DEFINE_PROP_BIT64("ctrl_rx_extra", VirtIONet, host_features,
> -                    VIRTIO_NET_F_CTRL_RX_EXTRA, true),
> -    DEFINE_PROP_BIT64("ctrl_mac_addr", VirtIONet, host_features,
> -                    VIRTIO_NET_F_CTRL_MAC_ADDR, true),
> -    DEFINE_PROP_BIT64("ctrl_guest_offloads", VirtIONet, host_features,
> -                    VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, true),
> -    DEFINE_PROP_BIT64("mq", VirtIONet, host_features, VIRTIO_NET_F_MQ, false),
> -    DEFINE_PROP_BIT64("rss", VirtIONet, host_features,
> -                    VIRTIO_NET_F_RSS, false),
> -    DEFINE_PROP_BIT64("hash", VirtIONet, host_features,
> -                    VIRTIO_NET_F_HASH_REPORT, false),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("csum", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_CSUM, ON_OFF_AUTO_AUTO),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("guest_csum", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_GUEST_CSUM, ON_OFF_AUTO_AUTO),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("gso", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_GSO, ON_OFF_AUTO_AUTO),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("guest_tso4", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_GUEST_TSO4, ON_OFF_AUTO_AUTO),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("guest_tso6", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_GUEST_TSO6, ON_OFF_AUTO_AUTO),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("guest_ecn", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_GUEST_ECN, ON_OFF_AUTO_AUTO),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("guest_ufo", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_GUEST_UFO, ON_OFF_AUTO_AUTO),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("guest_announce", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_GUEST_ANNOUNCE,
> +                                  ON_OFF_AUTO_AUTO),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("host_tso4", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_HOST_TSO4, ON_OFF_AUTO_AUTO),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("host_tso6", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_HOST_TSO6, ON_OFF_AUTO_AUTO),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("host_ecn", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_HOST_ECN, ON_OFF_AUTO_AUTO),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("host_ufo", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_HOST_UFO, ON_OFF_AUTO_AUTO),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("mrg_rxbuf", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_MRG_RXBUF, ON_OFF_AUTO_AUTO),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("status", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_STATUS, ON_OFF_AUTO_AUTO),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("ctrl_vq", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_CTRL_VQ, ON_OFF_AUTO_AUTO),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("ctrl_rx", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_CTRL_RX, ON_OFF_AUTO_AUTO),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("ctrl_vlan", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_CTRL_VLAN, ON_OFF_AUTO_AUTO),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("ctrl_rx_extra", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_CTRL_RX_EXTRA, ON_OFF_AUTO_AUTO),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("ctrl_mac_addr", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_CTRL_MAC_ADDR, ON_OFF_AUTO_AUTO),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("ctrl_guest_offloads", VirtIONet,
> +                                  host_features,
> +                                  VIRTIO_NET_F_CTRL_GUEST_OFFLOADS,
> +                                  ON_OFF_AUTO_AUTO),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("mq", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_MQ, ON_OFF_AUTO_OFF),

Probably for 'mq' there is no difference between 'auto' and 'on' ?

> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("rss", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_RSS, ON_OFF_AUTO_OFF),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("hash", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_HASH_REPORT, ON_OFF_AUTO_OFF),
>      DEFINE_PROP_ARRAY("ebpf-rss-fds", VirtIONet, nr_ebpf_rss_fds,
>                        ebpf_rss_fds, qdev_prop_string, char*),
> -    DEFINE_PROP_BIT64("guest_rsc_ext", VirtIONet, host_features,
> +    DEFINE_PROP_BIT64("guest_rsc_ext", VirtIONet, host_features.on_bits,
>                      VIRTIO_NET_F_RSC_EXT, false),
>      DEFINE_PROP_UINT32("rsc_interval", VirtIONet, rsc_timeout,
>                         VIRTIO_NET_RSC_DEFAULT_INTERVAL),
> @@ -3979,12 +4034,12 @@ static Property virtio_net_properties[] = {
>      DEFINE_PROP_INT32("speed", VirtIONet, net_conf.speed, SPEED_UNKNOWN),
>      DEFINE_PROP_STRING("duplex", VirtIONet, net_conf.duplex_str),
>      DEFINE_PROP_BOOL("failover", VirtIONet, failover, false),
> -    DEFINE_PROP_BIT64("guest_uso4", VirtIONet, host_features,
> -                      VIRTIO_NET_F_GUEST_USO4, true),
> -    DEFINE_PROP_BIT64("guest_uso6", VirtIONet, host_features,
> -                      VIRTIO_NET_F_GUEST_USO6, true),
> -    DEFINE_PROP_BIT64("host_uso", VirtIONet, host_features,
> -                      VIRTIO_NET_F_HOST_USO, true),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("guest_uso4", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_GUEST_USO4, ON_OFF_AUTO_AUTO),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("guest_uso6", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_GUEST_USO6, ON_OFF_AUTO_AUTO),
> +    DEFINE_PROP_ON_OFF_AUTO_BIT64("host_uso", VirtIONet, host_features,
> +                                  VIRTIO_NET_F_HOST_USO, ON_OFF_AUTO_AUTO),
>      DEFINE_PROP_END_OF_LIST(),
>  };
>
>
> --
> 2.44.0
>


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/3] qdev-properties: Add DEFINE_PROP_ON_OFF_AUTO_BIT64()
  2024-04-30 14:41   ` Yuri Benditovich
@ 2024-05-01  6:36     ` Akihiko Odaki
  0 siblings, 0 replies; 11+ messages in thread
From: Akihiko Odaki @ 2024-05-01  6:36 UTC (permalink / raw)
  To: Yuri Benditovich
  Cc: Jason Wang, Dmitry Fleytman, Sriram Yagnaraman,
	Michael S. Tsirkin, Luigi Rizzo, Giuseppe Lettieri,
	Vincenzo Maffione, Andrew Melnychenko, Paolo Bonzini,
	Daniel P. Berrangé,
	Eduardo Habkost, qemu-devel, 20240428-rss-v10-0-73cbaa91aeb6

On 2024/04/30 23:41, Yuri Benditovich wrote:
> On Sun, Apr 28, 2024 at 10:21 AM Akihiko Odaki <akihiko.odaki@daynix.com> wrote:
>>
>> DEFINE_PROP_ON_OFF_AUTO_BIT64() corresponds to DEFINE_PROP_ON_OFF_AUTO()
>> as DEFINE_PROP_BIT64() corresponds to DEFINE_PROP_BOOL(). The difference
>> is that DEFINE_PROP_ON_OFF_AUTO_BIT64() exposes OnOffAuto instead of
>> bool.
>>
>> Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
>> ---
>>   include/hw/qdev-properties.h | 18 ++++++++++++
>>   hw/core/qdev-properties.c    | 65 +++++++++++++++++++++++++++++++++++++++++++-
>>   2 files changed, 82 insertions(+), 1 deletion(-)
>>
>> diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
>> index 09aa04ca1e27..afec53a48470 100644
>> --- a/include/hw/qdev-properties.h
>> +++ b/include/hw/qdev-properties.h
>> @@ -43,11 +43,22 @@ struct PropertyInfo {
>>       ObjectPropertyRelease *release;
>>   };
>>
>> +/**
>> + * struct OnOffAutoBit64 - OnOffAuto storage with 64 elements.
>> + * @on_bits: Bitmap of elements with "on".
>> + * @auto_bits: Bitmap of elements with "auto".
>> + */
>> +typedef struct OnOffAutoBit64 {
>> +    uint64_t on_bits;
>> +    uint64_t auto_bits;
>> +} OnOffAutoBit64;
>> +
>>
>>   /*** qdev-properties.c ***/
>>
>>   extern const PropertyInfo qdev_prop_bit;
>>   extern const PropertyInfo qdev_prop_bit64;
>> +extern const PropertyInfo qdev_prop_on_off_auto_bit64;
>>   extern const PropertyInfo qdev_prop_bool;
>>   extern const PropertyInfo qdev_prop_enum;
>>   extern const PropertyInfo qdev_prop_uint8;
>> @@ -100,6 +111,13 @@ extern const PropertyInfo qdev_prop_link;
>>                   .set_default = true,                              \
>>                   .defval.u  = (bool)_defval)
>>
>> +#define DEFINE_PROP_ON_OFF_AUTO_BIT64(_name, _state, _field, _bit, _defval) \
>> +    DEFINE_PROP(_name, _state, _field, qdev_prop_on_off_auto_bit64,         \
>> +                OnOffAutoBit64,                                             \
>> +                .bitnr    = (_bit),                                         \
>> +                .set_default = true,                                        \
>> +                .defval.i = (OnOffAuto)_defval)
>> +
>>   #define DEFINE_PROP_BOOL(_name, _state, _field, _defval)     \
>>       DEFINE_PROP(_name, _state, _field, qdev_prop_bool, bool, \
>>                   .set_default = true,                         \
>> diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
>> index 7d6fa726fdf2..b96f54a1b912 100644
>> --- a/hw/core/qdev-properties.c
>> +++ b/hw/core/qdev-properties.c
>> @@ -188,7 +188,8 @@ const PropertyInfo qdev_prop_bit = {
>>
>>   static uint64_t qdev_get_prop_mask64(Property *prop)
>>   {
>> -    assert(prop->info == &qdev_prop_bit64);
>> +    assert(prop->info == &qdev_prop_bit64 ||
>> +           prop->info == &qdev_prop_on_off_auto_bit64);
>>       return 0x1ull << prop->bitnr;
>>   }
>>
>> @@ -233,6 +234,68 @@ const PropertyInfo qdev_prop_bit64 = {
>>       .set_default_value = set_default_value_bool,
>>   };
>>
>> +static void prop_get_on_off_auto_bit64(Object *obj, Visitor *v,
>> +                                       const char *name, void *opaque,
>> +                                       Error **errp)
>> +{
>> +    Property *prop = opaque;
>> +    OnOffAutoBit64 *p = object_field_prop_ptr(obj, prop);
>> +    int value;
>> +    uint64_t mask = qdev_get_prop_mask64(prop);
>> +
>> +    if (p->auto_bits & mask) {
>> +        value = ON_OFF_AUTO_AUTO;
>> +    } else if (p->on_bits & mask) {
>> +        value = ON_OFF_AUTO_ON;
>> +    } else {
>> +        value = ON_OFF_AUTO_OFF;
>> +    }
>> +
>> +    visit_type_enum(v, name, &value, &OnOffAuto_lookup, errp);
>> +}
>> +
>> +static void prop_set_on_off_auto_bit64(Object *obj, Visitor *v,
>> +                                       const char *name, void *opaque,
>> +                                       Error **errp)
>> +{
>> +    Property *prop = opaque;
>> +    OnOffAutoBit64 *p = object_field_prop_ptr(obj, prop);
>> +    int value;
>> +    uint64_t mask = qdev_get_prop_mask64(prop);
>> +
>> +    if (!visit_type_enum(v, name, &value, &OnOffAuto_lookup, errp)) {
>> +        return;
>> +    }
>> +
>> +    switch (value) {
>> +    case ON_OFF_AUTO_AUTO:
>> +        p->on_bits &= ~mask;
>> +        p->auto_bits |= mask;
>> +        break;
>> +
>> +    case ON_OFF_AUTO_ON:
>> +        p->on_bits |= mask;
>> +        p->auto_bits &= ~mask;
>> +        break;
>> +
>> +    case ON_OFF_AUTO_OFF:
>> +        p->on_bits &= ~mask;
>> +        p->auto_bits &= ~mask;
>> +        break;
>> +    }
>> +}
>> +
>> +const PropertyInfo qdev_prop_on_off_auto_bit64 = {
>> +    .name  = "bool",
> 
> Does it mean that the name of this tristate type is "bool"? Or I miss something?

No, this should be OnOffAuto. Thanks for pointing out this; I'll fix 
this in the next version.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/3] virtio-net: Convert feature properties to OnOffAuto
  2024-04-30 15:02   ` Yuri Benditovich
@ 2024-05-01  7:06     ` Akihiko Odaki
  0 siblings, 0 replies; 11+ messages in thread
From: Akihiko Odaki @ 2024-05-01  7:06 UTC (permalink / raw)
  To: Yuri Benditovich
  Cc: Jason Wang, Dmitry Fleytman, Sriram Yagnaraman,
	Michael S. Tsirkin, Luigi Rizzo, Giuseppe Lettieri,
	Vincenzo Maffione, Andrew Melnychenko, Paolo Bonzini,
	Daniel P. Berrangé,
	Eduardo Habkost, qemu-devel

On 2024/05/01 0:02, Yuri Benditovich wrote:
> Question:
> How will libvirt (as an example) work with this change. In the
> existing semantic of libvirt profile the "on" means "on if possible"
> and using existing profile after qemu update will still use "on" with
> meaning "force"? > Typically this is solved by machine type - if libvirt uses
> 'machine='pc-q35-8.1'' this will be backward-compatible.
> How will this change be accepted?

The reasoning here is that this patch only changes the configuration 
validation and, once the validation passes, QEMU can load the state of a 
machine created with an old version of QEMU.

It is still a good idea to add a compatibility property. I'll do so in 
the next version.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 0/3] virtio-net: Convert feature properties to OnOffAuto
  2024-04-29  7:05 ` [PATCH 0/3] virtio-net: Convert feature properties to OnOffAuto Michael S. Tsirkin
@ 2024-05-01  7:20   ` Akihiko Odaki
  2024-05-06  3:48     ` Jason Wang
  0 siblings, 1 reply; 11+ messages in thread
From: Akihiko Odaki @ 2024-05-01  7:20 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Jason Wang, Dmitry Fleytman, Sriram Yagnaraman, Luigi Rizzo,
	Giuseppe Lettieri, Vincenzo Maffione, Andrew Melnychenko,
	Yuri Benditovich, Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost, qemu-devel, 20240428-rss-v10-0-73cbaa91aeb6

On 2024/04/29 16:05, Michael S. Tsirkin wrote:
> On Sun, Apr 28, 2024 at 04:21:06PM +0900, Akihiko Odaki wrote:
>> Based-on: <20240428-rss-v10-0-73cbaa91aeb6@daynix.com>
>> ("[PATCH v10 00/18] virtio-net RSS/hash report fixes and improvements")
>>
>> Some features are not always available, and virtio-net used to disable
>> them when not available even if the corresponding properties were
>> explicitly set to "on".
>>
>> Convert feature properties to OnOffAuto so that the user can explicitly
>> tell QEMU to automatically select the value by setting them "auto".
>> QEMU will give an error if they are set "on".
>>
>> Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
> 
> Should we maybe bite the bullet allow "auto" for all binary/boolean
> properties? Just ignore "auto" if no one cares ATM.

It is not always obvious whether "auto" should be considered as "on" or 
"off" for existing boolean properties. The properties this patch deals 
with are to enable features so "auto" should be considered as "on" if 
possible. However, other properties may mean to disable features, and in 
such a case, "auto" should be considered as "off".

It may still make sense to accept "auto" for all virtio-net feature bits 
for consistency. In particular, I left guest_rsc_ext property boolean 
since nobody cares "auto" for that feature, but this can be converted to 
OnOffAuto.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 0/3] virtio-net: Convert feature properties to OnOffAuto
  2024-05-01  7:20   ` Akihiko Odaki
@ 2024-05-06  3:48     ` Jason Wang
  0 siblings, 0 replies; 11+ messages in thread
From: Jason Wang @ 2024-05-06  3:48 UTC (permalink / raw)
  To: Akihiko Odaki
  Cc: Michael S. Tsirkin, Dmitry Fleytman, Sriram Yagnaraman,
	Luigi Rizzo, Giuseppe Lettieri, Vincenzo Maffione,
	Andrew Melnychenko, Yuri Benditovich, Paolo Bonzini,
	Daniel P. Berrangé,
	Eduardo Habkost, qemu-devel, 20240428-rss-v10-0-73cbaa91aeb6,
	Jonathon Jongsma

On Wed, May 1, 2024 at 3:20 PM Akihiko Odaki <akihiko.odaki@daynix.com> wrote:
>
> On 2024/04/29 16:05, Michael S. Tsirkin wrote:
> > On Sun, Apr 28, 2024 at 04:21:06PM +0900, Akihiko Odaki wrote:
> >> Based-on: <20240428-rss-v10-0-73cbaa91aeb6@daynix.com>
> >> ("[PATCH v10 00/18] virtio-net RSS/hash report fixes and improvements")
> >>
> >> Some features are not always available, and virtio-net used to disable
> >> them when not available even if the corresponding properties were
> >> explicitly set to "on".

I think we'd better fail the initialization in this case, otherwise it
might confuse libvirt.

Adding Jonathon for more comments.

> >>
> >> Convert feature properties to OnOffAuto so that the user can explicitly
> >> tell QEMU to automatically select the value by setting them "auto".
> >> QEMU will give an error if they are set "on".
> >>
> >> Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
> >
> > Should we maybe bite the bullet allow "auto" for all binary/boolean
> > properties? Just ignore "auto" if no one cares ATM.
>
> It is not always obvious whether "auto" should be considered as "on" or
> "off" for existing boolean properties. The properties this patch deals
> with are to enable features so "auto" should be considered as "on" if
> possible. However, other properties may mean to disable features, and in
> such a case, "auto" should be considered as "off".
>
> It may still make sense to accept "auto" for all virtio-net feature bits
> for consistency. In particular, I left guest_rsc_ext property boolean
> since nobody cares "auto" for that feature, but this can be converted to
> OnOffAuto.
>

Thanks



^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2024-05-06  3:49 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-28  7:21 [PATCH 0/3] virtio-net: Convert feature properties to OnOffAuto Akihiko Odaki
2024-04-28  7:21 ` [PATCH 1/3] qdev-properties: Add DEFINE_PROP_ON_OFF_AUTO_BIT64() Akihiko Odaki
2024-04-30 14:41   ` Yuri Benditovich
2024-05-01  6:36     ` Akihiko Odaki
2024-04-28  7:21 ` [PATCH 2/3] virtio-net: Convert feature properties to OnOffAuto Akihiko Odaki
2024-04-30 15:02   ` Yuri Benditovich
2024-05-01  7:06     ` Akihiko Odaki
2024-04-28  7:21 ` [PATCH 3/3] virtio-net: Report RSS warning at device realization Akihiko Odaki
2024-04-29  7:05 ` [PATCH 0/3] virtio-net: Convert feature properties to OnOffAuto Michael S. Tsirkin
2024-05-01  7:20   ` Akihiko Odaki
2024-05-06  3:48     ` Jason Wang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.