]> git.droids-corp.org - dpdk.git/commitdiff
vhost: fix deadlock when message handling failed
authorWenwu Ma <wenwux.ma@intel.com>
Sat, 7 May 2022 13:27:53 +0000 (13:27 +0000)
committerMaxime Coquelin <maxime.coquelin@redhat.com>
Wed, 1 Jun 2022 09:50:09 +0000 (11:50 +0200)
In vhost_user_msg_handler(), if vhost message handling
failed, we should check whether the queue is locked and
release the lock before returning. Or, it will cause a
deadlock later.

Fixes: 7f31d4ea05ca ("vhost: fix lock on device readiness notification")
Cc: stable@dpdk.org
Signed-off-by: Wenwu Ma <wenwux.ma@intel.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
Tested-by: Wei Ling <weix.ling@intel.com>
Acked-by: David Marchand <david.marchand@redhat.com>
lib/vhost/vhost_user.c

index 850848c269c79c213ba45b3e939e63b5828f281f..91e69d1d970574d2e2215960a92c1f0c2850b3f6 100644 (file)
@@ -2887,7 +2887,6 @@ vhost_user_msg_handler(int vid, int fd)
                return -1;
        }
 
-       ret = 0;
        request = ctx.msg.request.master;
        if (request > VHOST_USER_NONE && request < RTE_DIM(vhost_message_handlers))
                msg_handler = &vhost_message_handlers[request];
@@ -3031,9 +3030,11 @@ skip_to_post_handle:
                send_vhost_reply(dev, fd, &ctx);
        } else if (ret == RTE_VHOST_MSG_RESULT_ERR) {
                VHOST_LOG_CONFIG(ERR, "(%s) vhost message handling failed.\n", dev->ifname);
-               return -1;
+               ret = -1;
+               goto unlock;
        }
 
+       ret = 0;
        for (i = 0; i < dev->nr_vring; i++) {
                struct vhost_virtqueue *vq = dev->virtqueue[i];
                bool cur_ready = vq_is_ready(dev, vq);
@@ -3044,10 +3045,11 @@ skip_to_post_handle:
                }
        }
 
+unlock:
        if (unlock_required)
                vhost_user_unlock_all_queue_pairs(dev);
 
-       if (!virtio_is_ready(dev))
+       if (ret != 0 || !virtio_is_ready(dev))
                goto out;
 
        /*
@@ -3074,7 +3076,7 @@ skip_to_post_handle:
        }
 
 out:
-       return 0;
+       return ret;
 }
 
 static int process_slave_message_reply(struct virtio_net *dev,