vhost: add IOTLB helper functions
[dpdk.git] / lib / librte_vhost / vhost.c
index d57d4b2..edcf1e0 100644 (file)
 #include <numaif.h>
 #endif
 
+#include <rte_errno.h>
 #include <rte_ethdev.h>
 #include <rte_log.h>
 #include <rte_string_fns.h>
 #include <rte_memory.h>
 #include <rte_malloc.h>
-#include <rte_virtio_net.h>
+#include <rte_vhost.h>
 
 #include "vhost.h"
 
@@ -101,7 +102,8 @@ free_device(struct virtio_net *dev)
                vq = dev->virtqueue[i];
 
                rte_free(vq->shadow_used_ring);
-
+               rte_free(vq->batch_copy_elems);
+               rte_mempool_free(vq->iotlb_pool);
                rte_free(vq);
        }
 
@@ -206,6 +208,7 @@ vhost_new_device(void)
 
        vhost_devices[i] = dev;
        dev->vid = i;
+       dev->slave_req_fd = -1;
 
        return i;
 }
@@ -272,7 +275,7 @@ rte_vhost_get_mtu(int vid, uint16_t *mtu)
        if (!(dev->flags & VIRTIO_DEV_READY))
                return -EAGAIN;
 
-       if (!(dev->features & VIRTIO_NET_F_MTU))
+       if (!(dev->features & (1ULL << VIRTIO_NET_F_MTU)))
                return -ENOTSUP;
 
        *mtu = dev->mtu;
@@ -295,7 +298,8 @@ rte_vhost_get_numa_node(int vid)
                            MPOL_F_NODE | MPOL_F_ADDR);
        if (ret < 0) {
                RTE_LOG(ERR, VHOST_CONFIG,
-                       "(%d) failed to query numa node: %d\n", vid, ret);
+                       "(%d) failed to query numa node: %s\n",
+                       vid, rte_strerror(errno));
                return -1;
        }
 
@@ -369,7 +373,7 @@ rte_vhost_get_mem_table(int vid, struct rte_vhost_memory **mem)
                return -1;
 
        size = dev->mem->nregions * sizeof(struct rte_vhost_mem_region);
-       m = malloc(size);
+       m = malloc(sizeof(struct rte_vhost_memory) + size);
        if (!m)
                return -1;
 
@@ -444,3 +448,60 @@ rte_vhost_enable_guest_notification(int vid, uint16_t queue_id, int enable)
        dev->virtqueue[queue_id]->used->flags = VRING_USED_F_NO_NOTIFY;
        return 0;
 }
+
+void
+rte_vhost_log_write(int vid, uint64_t addr, uint64_t len)
+{
+       struct virtio_net *dev = get_device(vid);
+
+       if (dev == NULL)
+               return;
+
+       vhost_log_write(dev, addr, len);
+}
+
+void
+rte_vhost_log_used_vring(int vid, uint16_t vring_idx,
+                        uint64_t offset, uint64_t len)
+{
+       struct virtio_net *dev;
+       struct vhost_virtqueue *vq;
+
+       dev = get_device(vid);
+       if (dev == NULL)
+               return;
+
+       if (vring_idx >= VHOST_MAX_VRING)
+               return;
+       vq = dev->virtqueue[vring_idx];
+       if (!vq)
+               return;
+
+       vhost_log_used_vring(dev, vq, offset, len);
+}
+
+uint32_t
+rte_vhost_rx_queue_count(int vid, uint16_t qid)
+{
+       struct virtio_net *dev;
+       struct vhost_virtqueue *vq;
+
+       dev = get_device(vid);
+       if (dev == NULL)
+               return 0;
+
+       if (unlikely(qid >= dev->nr_vring || (qid & 1) == 0)) {
+               RTE_LOG(ERR, VHOST_DATA, "(%d) %s: invalid virtqueue idx %d.\n",
+                       dev->vid, __func__, qid);
+               return 0;
+       }
+
+       vq = dev->virtqueue[qid];
+       if (vq == NULL)
+               return 0;
+
+       if (unlikely(vq->enabled == 0 || vq->avail == NULL))
+               return 0;
+
+       return *((volatile uint16_t *)&vq->avail->idx) - vq->last_avail_idx;
+}