[RFC 8/8] vdpa: Conditionally expose _F_LOG in vhost_net devices

Eugenio Pérez posted 8 patches 3 years, 6 months ago
There is a newer version of this series
[RFC 8/8] vdpa: Conditionally expose _F_LOG in vhost_net devices
Posted by Eugenio Pérez 3 years, 6 months ago
Vhost-vdpa networking devices need to met a few conditions to be
migratable. If SVQ is not enabled from the beginnig, to suspend the
device to retrieve the vq state is the first requirement.

However, qemu also needs to be able to intercept SVQ from the beginning.
To be able to do so, the vdpa device needs to expose certains features.

Expose _F_LOG only if all of these are met.

Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
---
 net/vhost-vdpa.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 4c6947feb8..73c27cd315 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -49,6 +49,9 @@ typedef struct VhostVDPAState {
     /* Device log enabled */
     bool log_enabled;
 
+    /* Device can suspend */
+    bool feature_suspend;
+
     bool started;
 } VhostVDPAState;
 
@@ -431,6 +434,7 @@ static int vhost_vdpa_net_cvq_start(NetClientState *nc)
     /* Default values */
     v->listener_shadow_vq = s->always_svq || s->log_enabled;
     v->shadow_vqs_enabled = s->always_svq || s->log_enabled;
+    v->feature_log = s->always_svq || s->log_enabled;
     s->vhost_vdpa.address_space_id = VHOST_VDPA_NET_CVQ_PASSTHROUGH;
 
     if (s->address_space_num < 2) {
@@ -455,6 +459,7 @@ static int vhost_vdpa_net_cvq_start(NetClientState *nc)
         if (unlikely(vq_group.num == cvq_group.num)) {
             warn_report("CVQ %u group is the same as VQ %u one (%u)",
                          cvq_group.index, vq_group.index, cvq_group.num);
+            v->feature_log = false;
             return 0;
         }
     }
@@ -464,6 +469,7 @@ static int vhost_vdpa_net_cvq_start(NetClientState *nc)
     if (r == 0) {
         v->shadow_vqs_enabled = true;
         s->vhost_vdpa.address_space_id = VHOST_VDPA_NET_CVQ_ASID;
+        v->feature_log = s->feature_suspend;
     }
 
 out:
@@ -728,6 +734,7 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer,
                                            unsigned nas,
                                            bool is_datapath,
                                            bool svq,
+                                           bool feature_suspend,
                                            VhostIOVATree *iova_tree)
 {
     NetClientState *nc = NULL;
@@ -748,9 +755,11 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer,
     s->vhost_vdpa.device_fd = vdpa_device_fd;
     s->vhost_vdpa.index = queue_pair_index;
     s->always_svq = svq;
+    s->feature_suspend = feature_suspend;
     s->vhost_vdpa.shadow_vqs_enabled = svq;
     s->vhost_vdpa.listener_shadow_vq = svq;
     s->vhost_vdpa.iova_tree = iova_tree;
+    s->vhost_vdpa.feature_log = feature_suspend;
     if (queue_pair_index == 0) {
         s->memory_listener = (MemoryListener) {
             .log_global_start = vhost_vdpa_net_log_global_start,
@@ -839,7 +848,7 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
     NetClientState *nc;
     int queue_pairs, r, i = 0, has_cvq = 0;
     unsigned num_as = 1;
-    bool svq_cvq;
+    bool svq_cvq, feature_suspend;
 
     assert(netdev->type == NET_CLIENT_DRIVER_VHOST_VDPA);
     opts = &netdev->u.vhost_vdpa;
@@ -892,10 +901,11 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
 
     ncs = g_malloc0(sizeof(*ncs) * queue_pairs);
 
+    feature_suspend = backend_features & BIT_ULL(VHOST_BACKEND_F_SUSPEND);
     for (i = 0; i < queue_pairs; i++) {
         ncs[i] = net_vhost_vdpa_init(peer, TYPE_VHOST_VDPA, name,
                                      vdpa_device_fd, i, 2, num_as, true,
-                                     opts->x_svq, iova_tree);
+                                     opts->x_svq, feature_suspend, iova_tree);
         if (!ncs[i])
             goto err;
     }
@@ -903,7 +913,7 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
     if (has_cvq) {
         nc = net_vhost_vdpa_init(peer, TYPE_VHOST_VDPA, name,
                                  vdpa_device_fd, i, 1, num_as, false,
-                                 opts->x_svq, iova_tree);
+                                 opts->x_svq, feature_suspend, iova_tree);
         if (!nc)
             goto err;
     }
-- 
2.31.1