} else {
if (vq->shadow_used_split)
rte_free(vq->shadow_used_split);
+
vq->shadow_used_split = rte_malloc(NULL,
vq->size * sizeof(struct vring_used_elem),
RTE_CACHE_LINE_SIZE);
+
if (!vq->shadow_used_split) {
VHOST_LOG_CONFIG(ERR,
- "failed to allocate memory for shadow used ring.\n");
+ "failed to allocate memory for vq internal data.\n");
return RTE_VHOST_MSG_RESULT_ERR;
}
}
goto err_mmap;
}
- populate = (dev->dequeue_zero_copy) ? MAP_POPULATE : 0;
+ populate = (dev->dequeue_zero_copy || dev->async_copy) ?
+ MAP_POPULATE : 0;
mmap_addr = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE,
MAP_SHARED | populate, fd, 0);
reg->host_user_addr = (uint64_t)(uintptr_t)mmap_addr +
mmap_offset;
- if (dev->dequeue_zero_copy)
+ if (dev->dequeue_zero_copy || dev->async_copy)
if (add_guest_pages(dev, reg, alignment) < 0) {
VHOST_LOG_CONFIG(ERR,
"adding guest pages to region %u failed.\n",
struct vhost_virtqueue *vq;
uint32_t i;
+ if (dev->flags & VIRTIO_DEV_READY)
+ return 1;
+
if (dev->nr_vring < VIRTIO_DEV_NUM_VQS_TO_BE_READY)
return 0;
return 0;
}
+ dev->flags |= VIRTIO_DEV_READY;
+
if (!(dev->flags & VIRTIO_DEV_RUNNING))
VHOST_LOG_CONFIG(INFO,
"virtio is now ready for processing.\n");
} else {
rte_free(vq->shadow_used_split);
vq->shadow_used_split = NULL;
+ if (vq->async_pkts_pending)
+ rte_free(vq->async_pkts_pending);
+ if (vq->async_pending_info)
+ rte_free(vq->async_pending_info);
+ vq->async_pkts_pending = NULL;
+ vq->async_pending_info = NULL;
}
rte_free(vq->batch_copy_elems);
"set queue enable: %d to qp idx: %d\n",
enable, index);
+ if (!enable && dev->virtqueue[index]->async_registered) {
+ if (dev->virtqueue[index]->async_pkts_inflight_n) {
+ VHOST_LOG_CONFIG(ERR, "failed to disable vring. "
+ "async inflight packets must be completed first\n");
+ return RTE_VHOST_MSG_RESULT_ERR;
+ }
+ }
+
/* On disable, rings have to be stopped being processed. */
if (!enable && dev->dequeue_zero_copy)
drain_zmbuf_list(dev->virtqueue[index]);
}
- if (!(dev->flags & VIRTIO_DEV_RUNNING) && virtio_is_ready(dev)) {
- dev->flags |= VIRTIO_DEV_READY;
+ if (!virtio_is_ready(dev))
+ goto out;
- if (!(dev->flags & VIRTIO_DEV_RUNNING)) {
- if (dev->dequeue_zero_copy) {
- VHOST_LOG_CONFIG(INFO,
- "dequeue zero copy is enabled\n");
- }
+ /*
+ * Virtio is now ready. If not done already, it is time
+ * to notify the application it can process the rings and
+ * configure the vDPA device if present.
+ */
- if (dev->notify_ops->new_device(dev->vid) == 0)
- dev->flags |= VIRTIO_DEV_RUNNING;
- }
+ if (!(dev->flags & VIRTIO_DEV_RUNNING)) {
+ if (dev->notify_ops->new_device(dev->vid) == 0)
+ dev->flags |= VIRTIO_DEV_RUNNING;
}
vdpa_dev = dev->vdpa_dev;
- if (vdpa_dev && virtio_is_ready(dev) &&
- !(dev->flags & VIRTIO_DEV_VDPA_CONFIGURED)) {
+ if (!vdpa_dev)
+ goto out;
+
+ if (!(dev->flags & VIRTIO_DEV_VDPA_CONFIGURED)) {
if (vdpa_dev->ops->dev_conf)
vdpa_dev->ops->dev_conf(dev->vid);
+
dev->flags |= VIRTIO_DEV_VDPA_CONFIGURED;
}
+out:
return 0;
}