]> git.droids-corp.org - dpdk.git/commitdiff
vhost: fix async access
authorDavid Marchand <david.marchand@redhat.com>
Mon, 11 Apr 2022 11:00:08 +0000 (13:00 +0200)
committerMaxime Coquelin <maxime.coquelin@redhat.com>
Wed, 1 Jun 2022 09:50:09 +0000 (11:50 +0200)
vq->async accesses must be protected with vq->access_lock.

Fixes: eb666d24085f ("vhost: fix async unregister deadlock")
Fixes: 0c0935c5f794 ("vhost: allow to check in-flight packets for async vhost")
Cc: stable@dpdk.org
Signed-off-by: David Marchand <david.marchand@redhat.com>
Acked-by: Sunil Pai G <sunil.pai.g@intel.com>
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
lib/vhost/vhost.c

index df0bb9d04372ebaa45b568abedfbafac68158982..14863144f39c065d5697b70bb27f7eaa0c9468a3 100644 (file)
@@ -1753,27 +1753,23 @@ rte_vhost_async_channel_unregister(int vid, uint16_t queue_id)
        if (vq == NULL)
                return ret;
 
-       ret = 0;
-
-       if (!vq->async)
-               return ret;
-
        if (!rte_spinlock_trylock(&vq->access_lock)) {
                VHOST_LOG_CONFIG(ERR, "(%s) failed to unregister async channel, virtqueue busy.\n",
                                dev->ifname);
-               return -1;
+               return ret;
        }
 
-       if (vq->async->pkts_inflight_n) {
+       if (!vq->async) {
+               ret = 0;
+       } else if (vq->async->pkts_inflight_n) {
                VHOST_LOG_CONFIG(ERR, "(%s) failed to unregister async channel.\n", dev->ifname);
                VHOST_LOG_CONFIG(ERR, "(%s) inflight packets must be completed before unregistration.\n",
                        dev->ifname);
-               ret = -1;
-               goto out;
+       } else {
+               vhost_free_async_mem(vq);
+               ret = 0;
        }
 
-       vhost_free_async_mem(vq);
-out:
        rte_spinlock_unlock(&vq->access_lock);
 
        return ret;
@@ -1891,9 +1887,6 @@ rte_vhost_async_get_inflight(int vid, uint16_t queue_id)
        if (vq == NULL)
                return ret;
 
-       if (!vq->async)
-               return ret;
-
        if (!rte_spinlock_trylock(&vq->access_lock)) {
                VHOST_LOG_CONFIG(DEBUG,
                        "(%s) failed to check in-flight packets. virtqueue busy.\n",
@@ -1901,7 +1894,9 @@ rte_vhost_async_get_inflight(int vid, uint16_t queue_id)
                return ret;
        }
 
-       ret = vq->async->pkts_inflight_n;
+       if (vq->async)
+               ret = vq->async->pkts_inflight_n;
+
        rte_spinlock_unlock(&vq->access_lock);
 
        return ret;