vhost: fix name not null terminated
[dpdk.git] / lib / librte_vhost / virtio-net.c
index be91e5f..f4695af 100644 (file)
@@ -167,8 +167,8 @@ init_vring_queue(struct vhost_virtqueue *vq, int qp_idx)
 {
        memset(vq, 0, sizeof(struct vhost_virtqueue));
 
-       vq->kickfd = -1;
-       vq->callfd = -1;
+       vq->kickfd = VIRTIO_UNINITIALIZED_EVENTFD;
+       vq->callfd = VIRTIO_UNINITIALIZED_EVENTFD;
 
        /* Backends are set to -1 indicating an inactive device. */
        vq->backend = -1;
@@ -293,6 +293,9 @@ vhost_destroy_device(struct vhost_device_ctx ctx)
 {
        struct virtio_net *dev = get_device(ctx);
 
+       if (dev == NULL)
+               return;
+
        if (dev->flags & VIRTIO_DEV_RUNNING)
                notify_ops->destroy_device(dev);
 
@@ -317,6 +320,7 @@ vhost_set_ifname(struct vhost_device_ctx ctx,
                sizeof(dev->ifname) : if_len;
 
        strncpy(dev->ifname, if_name, len);
+       dev->ifname[sizeof(dev->ifname) - 1] = '\0';
 }
 
 
@@ -444,64 +448,71 @@ static struct virtio_net*
 numa_realloc(struct virtio_net *dev, int index)
 {
        int oldnode, newnode;
-       struct virtio_net *old_dev, *new_dev = NULL;
-       struct vhost_virtqueue *old_vq, *new_vq = NULL;
+       struct virtio_net *old_dev;
+       struct vhost_virtqueue *old_vq, *vq;
        int ret;
-       int realloc_dev = 0, realloc_vq = 0;
+
+       /*
+        * vq is allocated on pairs, we should try to do realloc
+        * on first queue of one queue pair only.
+        */
+       if (index % VIRTIO_QNUM != 0)
+               return dev;
 
        old_dev = dev;
-       old_vq  = dev->virtqueue[index];
+       vq = old_vq = dev->virtqueue[index];
+
+       ret = get_mempolicy(&newnode, NULL, 0, old_vq->desc,
+                           MPOL_F_NODE | MPOL_F_ADDR);
 
-       ret  = get_mempolicy(&newnode, NULL, 0, old_vq->desc,
-                       MPOL_F_NODE | MPOL_F_ADDR);
-       ret = ret | get_mempolicy(&oldnode, NULL, 0, old_dev,
-                       MPOL_F_NODE | MPOL_F_ADDR);
+       /* check if we need to reallocate vq */
+       ret |= get_mempolicy(&oldnode, NULL, 0, old_vq,
+                            MPOL_F_NODE | MPOL_F_ADDR);
        if (ret) {
                RTE_LOG(ERR, VHOST_CONFIG,
-                       "Unable to get vring desc or dev numa information.\n");
+                       "Unable to get vq numa information.\n");
                return dev;
        }
-       if (oldnode != newnode)
-               realloc_dev = 1;
+       if (oldnode != newnode) {
+               RTE_LOG(INFO, VHOST_CONFIG,
+                       "reallocate vq from %d to %d node\n", oldnode, newnode);
+               vq = rte_malloc_socket(NULL, sizeof(*vq) * VIRTIO_QNUM, 0,
+                                      newnode);
+               if (!vq)
+                       return dev;
+
+               memcpy(vq, old_vq, sizeof(*vq) * VIRTIO_QNUM);
+               rte_free(old_vq);
+       }
 
-       ret = get_mempolicy(&oldnode, NULL, 0, old_vq,
-                       MPOL_F_NODE | MPOL_F_ADDR);
+       /* check if we need to reallocate dev */
+       ret = get_mempolicy(&oldnode, NULL, 0, old_dev,
+                           MPOL_F_NODE | MPOL_F_ADDR);
        if (ret) {
                RTE_LOG(ERR, VHOST_CONFIG,
-                       "Unable to get vq numa information.\n");
-               return dev;
+                       "Unable to get dev numa information.\n");
+               goto out;
        }
-       if (oldnode != newnode)
-               realloc_vq = 1;
-
-       if (realloc_dev == 0 && realloc_vq == 0)
-               return dev;
-
-       if (realloc_dev)
-               new_dev = rte_malloc_socket(NULL,
-                       sizeof(struct virtio_net), 0, newnode);
-       if (realloc_vq)
-               new_vq = rte_malloc_socket(NULL,
-                       sizeof(struct vhost_virtqueue), 0, newnode);
-       if (!new_dev && !new_vq)
-               return dev;
-
-       if (realloc_vq)
-               memcpy(new_vq, old_vq, sizeof(*new_vq));
-       if (realloc_dev)
-               memcpy(new_dev, old_dev, sizeof(*new_dev));
+       if (oldnode != newnode) {
+               RTE_LOG(INFO, VHOST_CONFIG,
+                       "reallocate dev from %d to %d node\n",
+                       oldnode, newnode);
+               dev = rte_malloc_socket(NULL, sizeof(*dev), 0, newnode);
+               if (!dev) {
+                       dev = old_dev;
+                       goto out;
+               }
 
-       (new_dev ? new_dev : old_dev)->virtqueue[index] =
-               new_vq ? new_vq : old_vq;
-       if (realloc_vq)
-               rte_free(old_vq);
-       if (realloc_dev) {
+               memcpy(dev, old_dev, sizeof(*dev));
                rte_free(old_dev);
-
-               vhost_devices[new_dev->device_fh] = new_dev;
        }
 
-       return realloc_dev ? new_dev : dev;
+out:
+       dev->virtqueue[index] = vq;
+       dev->virtqueue[index + 1] = vq + 1;
+       vhost_devices[dev->device_fh] = dev;
+
+       return dev;
 }
 #else
 static struct virtio_net*