vhost: move the device ready check at proper place
authorYuanhan Liu <yuanhan.liu@linux.intel.com>
Sat, 1 Apr 2017 07:22:49 +0000 (15:22 +0800)
committerYuanhan Liu <yuanhan.liu@linux.intel.com>
Sat, 1 Apr 2017 08:42:44 +0000 (10:42 +0200)
Currently, we check vq->desc, vq->kickfd and vq->callfd to know whether
a virtio device is ready or not. However, we only do it when handling
SET_VRING_KICK message, which could be wrong if a vhost-user frontend
send SET_VRING_KICK first and SET_VRING_CALL later.

To work for all possible vhost-user frontend implementations, we could
move the ready check at the end of vhost-user message handler.

Meanwhile, since we do the check more often than before, the "virtio
not ready" message is dropped, to not flood the screen.

Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
lib/librte_vhost/vhost_user.c

index 4337ce7..9140f60 100644 (file)
@@ -615,14 +615,14 @@ virtio_is_ready(struct virtio_net *dev)
        struct vhost_virtqueue *vq;
        uint32_t i;
 
+       if (dev->nr_vring == 0)
+               return 0;
+
        for (i = 0; i < dev->nr_vring; i++) {
                vq = dev->virtqueue[i];
 
-               if (!vq_is_ready(vq)) {
-                       RTE_LOG(INFO, VHOST_CONFIG,
-                               "virtio is not ready for processing.\n");
+               if (!vq_is_ready(vq))
                        return 0;
-               }
        }
 
        RTE_LOG(INFO, VHOST_CONFIG,
@@ -651,10 +651,6 @@ vhost_user_set_vring_call(struct virtio_net *dev, struct VhostUserMsg *pmsg)
        vq->callfd = file.fd;
 }
 
-/*
- *  In vhost-user, when we receive kick message, will test whether virtio
- *  device is ready for packet processing.
- */
 static void
 vhost_user_set_vring_kick(struct virtio_net *dev, struct VhostUserMsg *pmsg)
 {
@@ -673,20 +669,6 @@ vhost_user_set_vring_kick(struct virtio_net *dev, struct VhostUserMsg *pmsg)
        if (vq->kickfd >= 0)
                close(vq->kickfd);
        vq->kickfd = file.fd;
-
-       if (virtio_is_ready(dev)) {
-               dev->flags |= VIRTIO_DEV_READY;
-
-               if (!(dev->flags & VIRTIO_DEV_RUNNING)) {
-                       if (dev->dequeue_zero_copy) {
-                               RTE_LOG(INFO, VHOST_CONFIG,
-                                               "dequeue zero copy is enabled\n");
-                       }
-
-                       if (dev->notify_ops->new_device(dev->vid) == 0)
-                               dev->flags |= VIRTIO_DEV_RUNNING;
-               }
-       }
 }
 
 static void
@@ -1108,5 +1090,19 @@ vhost_user_msg_handler(int vid, int fd)
                send_vhost_message(fd, &msg);
        }
 
+       if (!(dev->flags & VIRTIO_DEV_RUNNING) && virtio_is_ready(dev)) {
+               dev->flags |= VIRTIO_DEV_READY;
+
+               if (!(dev->flags & VIRTIO_DEV_RUNNING)) {
+                       if (dev->dequeue_zero_copy) {
+                               RTE_LOG(INFO, VHOST_CONFIG,
+                                               "dequeue zero copy is enabled\n");
+                       }
+
+                       if (dev->notify_ops->new_device(dev->vid) == 0)
+                               dev->flags |= VIRTIO_DEV_RUNNING;
+               }
+       }
+
        return 0;
 }