git.droids-corp.org
/
dpdk.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
eal/windows: add missing SPDX license tag
[dpdk.git]
/
lib
/
librte_vhost
/
vhost.c
diff --git
a/lib/librte_vhost/vhost.c
b/lib/librte_vhost/vhost.c
index
0c9ba3b
..
52ab93d
100644
(file)
--- a/
lib/librte_vhost/vhost.c
+++ b/
lib/librte_vhost/vhost.c
@@
-26,6
+26,7
@@
#include "vhost_user.h"
struct virtio_net *vhost_devices[MAX_VHOST_DEVICE];
#include "vhost_user.h"
struct virtio_net *vhost_devices[MAX_VHOST_DEVICE];
+pthread_mutex_t vhost_dev_lock = PTHREAD_MUTEX_INITIALIZER;
/* Called with iotlb_lock read-locked */
uint64_t
/* Called with iotlb_lock read-locked */
uint64_t
@@
-106,7
+107,7
@@
__vhost_log_write(struct virtio_net *dev, uint64_t addr, uint64_t len)
return;
/* To make sure guest memory updates are committed before logging */
return;
/* To make sure guest memory updates are committed before logging */
- rte_
smp_wmb(
);
+ rte_
atomic_thread_fence(__ATOMIC_RELEASE
);
page = addr / VHOST_LOG_PAGE;
while (page * VHOST_LOG_PAGE < addr + len) {
page = addr / VHOST_LOG_PAGE;
while (page * VHOST_LOG_PAGE < addr + len) {
@@
-144,7
+145,7
@@
__vhost_log_cache_sync(struct virtio_net *dev, struct vhost_virtqueue *vq)
if (unlikely(!dev->log_base))
return;
if (unlikely(!dev->log_base))
return;
- rte_
smp_wmb(
);
+ rte_
atomic_thread_fence(__ATOMIC_RELEASE
);
log_base = (unsigned long *)(uintptr_t)dev->log_base;
log_base = (unsigned long *)(uintptr_t)dev->log_base;
@@
-163,7
+164,7
@@
__vhost_log_cache_sync(struct virtio_net *dev, struct vhost_virtqueue *vq)
#endif
}
#endif
}
- rte_
smp_wmb(
);
+ rte_
atomic_thread_fence(__ATOMIC_RELEASE
);
vq->log_cache_nb_elem = 0;
}
vq->log_cache_nb_elem = 0;
}
@@
-190,7
+191,7
@@
vhost_log_cache_page(struct virtio_net *dev, struct vhost_virtqueue *vq,
* No more room for a new log cache entry,
* so write the dirty log map directly.
*/
* No more room for a new log cache entry,
* so write the dirty log map directly.
*/
- rte_
smp_wmb(
);
+ rte_
atomic_thread_fence(__ATOMIC_RELEASE
);
vhost_log_page((uint8_t *)(uintptr_t)dev->log_base, page);
return;
vhost_log_page((uint8_t *)(uintptr_t)dev->log_base, page);
return;
@@
-327,17
+328,17
@@
cleanup_device(struct virtio_net *dev, int destroy)
static void
vhost_free_async_mem(struct vhost_virtqueue *vq)
{
static void
vhost_free_async_mem(struct vhost_virtqueue *vq)
{
- if (vq->async_pkts_pending)
- rte_free(vq->async_pkts_pending);
if (vq->async_pkts_info)
rte_free(vq->async_pkts_info);
if (vq->async_pkts_info)
rte_free(vq->async_pkts_info);
+ if (vq->async_descs_split)
+ rte_free(vq->async_descs_split);
if (vq->it_pool)
rte_free(vq->it_pool);
if (vq->vec_pool)
rte_free(vq->vec_pool);
if (vq->it_pool)
rte_free(vq->it_pool);
if (vq->vec_pool)
rte_free(vq->vec_pool);
- vq->async_pkts_pending = NULL;
vq->async_pkts_info = NULL;
vq->async_pkts_info = NULL;
+ vq->async_descs_split = NULL;
vq->it_pool = NULL;
vq->vec_pool = NULL;
}
vq->it_pool = NULL;
vq->vec_pool = NULL;
}
@@
-544,6
+545,11
@@
init_vring_queue(struct virtio_net *dev, uint32_t vring_idx)
}
vq = dev->virtqueue[vring_idx];
}
vq = dev->virtqueue[vring_idx];
+ if (!vq) {
+ VHOST_LOG_CONFIG(ERR, "Virtqueue not allocated (%d)\n",
+ vring_idx);
+ return;
+ }
memset(vq, 0, sizeof(struct vhost_virtqueue));
memset(vq, 0, sizeof(struct vhost_virtqueue));
@@
-570,6
+576,12
@@
reset_vring_queue(struct virtio_net *dev, uint32_t vring_idx)
}
vq = dev->virtqueue[vring_idx];
}
vq = dev->virtqueue[vring_idx];
+ if (!vq) {
+ VHOST_LOG_CONFIG(ERR, "Virtqueue not allocated (%d)\n",
+ vring_idx);
+ return;
+ }
+
callfd = vq->callfd;
init_vring_queue(dev, vring_idx);
vq->callfd = callfd;
callfd = vq->callfd;
init_vring_queue(dev, vring_idx);
vq->callfd = callfd;
@@
-594,7
+606,7
@@
alloc_vring_queue(struct virtio_net *dev, uint32_t vring_idx)
}
dev->virtqueue[i] = vq;
}
dev->virtqueue[i] = vq;
- init_vring_queue(dev,
vring_idx
);
+ init_vring_queue(dev,
i
);
rte_spinlock_init(&vq->access_lock);
vq->avail_wrap_counter = 1;
vq->used_wrap_counter = 1;
rte_spinlock_init(&vq->access_lock);
vq->avail_wrap_counter = 1;
vq->used_wrap_counter = 1;
@@
-634,6
+646,7
@@
vhost_new_device(void)
struct virtio_net *dev;
int i;
struct virtio_net *dev;
int i;
+ pthread_mutex_lock(&vhost_dev_lock);
for (i = 0; i < MAX_VHOST_DEVICE; i++) {
if (vhost_devices[i] == NULL)
break;
for (i = 0; i < MAX_VHOST_DEVICE; i++) {
if (vhost_devices[i] == NULL)
break;
@@
-642,6
+655,7
@@
vhost_new_device(void)
if (i == MAX_VHOST_DEVICE) {
VHOST_LOG_CONFIG(ERR,
"Failed to find a free slot for new device.\n");
if (i == MAX_VHOST_DEVICE) {
VHOST_LOG_CONFIG(ERR,
"Failed to find a free slot for new device.\n");
+ pthread_mutex_unlock(&vhost_dev_lock);
return -1;
}
return -1;
}
@@
-649,10
+663,13
@@
vhost_new_device(void)
if (dev == NULL) {
VHOST_LOG_CONFIG(ERR,
"Failed to allocate memory for new dev.\n");
if (dev == NULL) {
VHOST_LOG_CONFIG(ERR,
"Failed to allocate memory for new dev.\n");
+ pthread_mutex_unlock(&vhost_dev_lock);
return -1;
}
vhost_devices[i] = dev;
return -1;
}
vhost_devices[i] = dev;
+ pthread_mutex_unlock(&vhost_dev_lock);
+
dev->vid = i;
dev->flags = VIRTIO_DEV_BUILTIN_VIRTIO_NET;
dev->slave_req_fd = -1;
dev->vid = i;
dev->flags = VIRTIO_DEV_BUILTIN_VIRTIO_NET;
dev->slave_req_fd = -1;
@@
-1086,11
+1103,11
@@
rte_vhost_clr_inflight_desc_split(int vid, uint16_t vring_idx,
if (unlikely(idx >= vq->size))
return -1;
if (unlikely(idx >= vq->size))
return -1;
- rte_
smp_mb(
);
+ rte_
atomic_thread_fence(__ATOMIC_SEQ_CST
);
vq->inflight_split->desc[idx].inflight = 0;
vq->inflight_split->desc[idx].inflight = 0;
- rte_
smp_mb(
);
+ rte_
atomic_thread_fence(__ATOMIC_SEQ_CST
);
vq->inflight_split->used_idx = last_used_idx;
return 0;
vq->inflight_split->used_idx = last_used_idx;
return 0;
@@
-1129,11
+1146,11
@@
rte_vhost_clr_inflight_desc_packed(int vid, uint16_t vring_idx,
if (unlikely(head >= vq->size))
return -1;
if (unlikely(head >= vq->size))
return -1;
- rte_
smp_mb(
);
+ rte_
atomic_thread_fence(__ATOMIC_SEQ_CST
);
inflight_info->desc[head].inflight = 0;
inflight_info->desc[head].inflight = 0;
- rte_
smp_mb(
);
+ rte_
atomic_thread_fence(__ATOMIC_SEQ_CST
);
inflight_info->old_free_head = inflight_info->free_head;
inflight_info->old_used_idx = inflight_info->used_idx;
inflight_info->old_free_head = inflight_info->free_head;
inflight_info->old_used_idx = inflight_info->used_idx;
@@
-1260,7
+1277,12
@@
rte_vhost_avail_entries(int vid, uint16_t queue_id)
if (!dev)
return 0;
if (!dev)
return 0;
+ if (queue_id >= VHOST_MAX_VRING)
+ return 0;
+
vq = dev->virtqueue[queue_id];
vq = dev->virtqueue[queue_id];
+ if (!vq)
+ return 0;
rte_spinlock_lock(&vq->access_lock);
rte_spinlock_lock(&vq->access_lock);
@@
-1314,7
+1336,7
@@
vhost_enable_notify_packed(struct virtio_net *dev,
vq->avail_wrap_counter << 15;
}
vq->avail_wrap_counter << 15;
}
- rte_
smp_wmb(
);
+ rte_
atomic_thread_fence(__ATOMIC_RELEASE
);
vq->device_event->flags = flags;
return 0;
vq->device_event->flags = flags;
return 0;
@@
-1347,7
+1369,12
@@
rte_vhost_enable_guest_notification(int vid, uint16_t queue_id, int enable)
if (!dev)
return -1;
if (!dev)
return -1;
+ if (queue_id >= VHOST_MAX_VRING)
+ return -1;
+
vq = dev->virtqueue[queue_id];
vq = dev->virtqueue[queue_id];
+ if (!vq)
+ return -1;
rte_spinlock_lock(&vq->access_lock);
rte_spinlock_lock(&vq->access_lock);
@@
-1457,6
+1484,9
@@
int rte_vhost_get_vring_base(int vid, uint16_t queue_id,
if (dev == NULL || last_avail_idx == NULL || last_used_idx == NULL)
return -1;
if (dev == NULL || last_avail_idx == NULL || last_used_idx == NULL)
return -1;
+ if (queue_id >= VHOST_MAX_VRING)
+ return -1;
+
vq = dev->virtqueue[queue_id];
if (!vq)
return -1;
vq = dev->virtqueue[queue_id];
if (!vq)
return -1;
@@
-1483,6
+1513,9
@@
int rte_vhost_set_vring_base(int vid, uint16_t queue_id,
if (!dev)
return -1;
if (!dev)
return -1;
+ if (queue_id >= VHOST_MAX_VRING)
+ return -1;
+
vq = dev->virtqueue[queue_id];
if (!vq)
return -1;
vq = dev->virtqueue[queue_id];
if (!vq)
return -1;
@@
-1507,15
+1540,23
@@
rte_vhost_get_vring_base_from_inflight(int vid,
uint16_t *last_used_idx)
{
struct rte_vhost_inflight_info_packed *inflight_info;
uint16_t *last_used_idx)
{
struct rte_vhost_inflight_info_packed *inflight_info;
+ struct vhost_virtqueue *vq;
struct virtio_net *dev = get_device(vid);
if (dev == NULL || last_avail_idx == NULL || last_used_idx == NULL)
return -1;
struct virtio_net *dev = get_device(vid);
if (dev == NULL || last_avail_idx == NULL || last_used_idx == NULL)
return -1;
+ if (queue_id >= VHOST_MAX_VRING)
+ return -1;
+
+ vq = dev->virtqueue[queue_id];
+ if (!vq)
+ return -1;
+
if (!vq_is_packed(dev))
return -1;
if (!vq_is_packed(dev))
return -1;
- inflight_info =
dev->virtqueue[queue_id]
->inflight_packed;
+ inflight_info =
vq
->inflight_packed;
if (!inflight_info)
return -1;
if (!inflight_info)
return -1;
@@
-1553,6
+1594,9
@@
int rte_vhost_async_channel_register(int vid, uint16_t queue_id,
f.intval = features;
f.intval = features;
+ if (queue_id >= VHOST_MAX_VRING)
+ return -1;
+
vq = dev->virtqueue[queue_id];
if (unlikely(vq == NULL || !dev->async_copy))
vq = dev->virtqueue[queue_id];
if (unlikely(vq == NULL || !dev->async_copy))
@@
-1590,9
+1634,6
@@
int rte_vhost_async_channel_register(int vid, uint16_t queue_id,
node = SOCKET_ID_ANY;
#endif
node = SOCKET_ID_ANY;
#endif
- vq->async_pkts_pending = rte_malloc_socket(NULL,
- vq->size * sizeof(uintptr_t),
- RTE_CACHE_LINE_SIZE, node);
vq->async_pkts_info = rte_malloc_socket(NULL,
vq->size * sizeof(struct async_inflight_info),
RTE_CACHE_LINE_SIZE, node);
vq->async_pkts_info = rte_malloc_socket(NULL,
vq->size * sizeof(struct async_inflight_info),
RTE_CACHE_LINE_SIZE, node);
@@
-1602,7
+1643,10
@@
int rte_vhost_async_channel_register(int vid, uint16_t queue_id,
vq->vec_pool = rte_malloc_socket(NULL,
VHOST_MAX_ASYNC_VEC * sizeof(struct iovec),
RTE_CACHE_LINE_SIZE, node);
vq->vec_pool = rte_malloc_socket(NULL,
VHOST_MAX_ASYNC_VEC * sizeof(struct iovec),
RTE_CACHE_LINE_SIZE, node);
- if (!vq->async_pkts_pending || !vq->async_pkts_info ||
+ vq->async_descs_split = rte_malloc_socket(NULL,
+ vq->size * sizeof(struct vring_used_elem),
+ RTE_CACHE_LINE_SIZE, node);
+ if (!vq->async_descs_split || !vq->async_pkts_info ||
!vq->it_pool || !vq->vec_pool) {
vhost_free_async_mem(vq);
VHOST_LOG_CONFIG(ERR,
!vq->it_pool || !vq->vec_pool) {
vhost_free_async_mem(vq);
VHOST_LOG_CONFIG(ERR,
@@
-1634,6
+1678,9
@@
int rte_vhost_async_channel_unregister(int vid, uint16_t queue_id)
if (dev == NULL)
return ret;
if (dev == NULL)
return ret;
+ if (queue_id >= VHOST_MAX_VRING)
+ return ret;
+
vq = dev->virtqueue[queue_id];
if (vq == NULL)
vq = dev->virtqueue[queue_id];
if (vq == NULL)