bool dequeue_zero_copy;
bool iommu_support;
bool use_builtin_virtio_net;
+ bool extbuf;
+ bool linearbuf;
/*
* The "supported_features" indicates the feature bits the
}
if (msgh.msg_flags & (MSG_TRUNC | MSG_CTRUNC)) {
- RTE_LOG(ERR, VHOST_CONFIG, "truncted msg\n");
+ RTE_LOG(ERR, VHOST_CONFIG, "truncated msg\n");
return -1;
}
if (vsocket->dequeue_zero_copy)
vhost_enable_dequeue_zero_copy(vid);
+ if (vsocket->extbuf)
+ vhost_enable_extbuf(vid);
+
+ if (vsocket->linearbuf)
+ vhost_enable_linearbuf(vid);
+
RTE_LOG(INFO, VHOST_CONFIG, "new device, handle is %d\n", vid);
if (vsocket->notify_ops->new_connection) {
RTE_LOG(ERR, VHOST_CONFIG,
"failed to add vhost user connection with fd %d\n",
fd);
- goto err;
+ goto err_cleanup;
}
}
if (vsocket->notify_ops->destroy_connection)
vsocket->notify_ops->destroy_connection(conn->vid);
- goto err;
+ goto err_cleanup;
}
pthread_mutex_lock(&vsocket->conn_mutex);
fdset_pipe_notify(&vhost_user.fdset);
return;
+err_cleanup:
+ vhost_destroy_device(vid);
err:
free(conn);
close(fd);
ret = vhost_user_msg_handler(conn->vid, connfd);
if (ret < 0) {
+ struct virtio_net *dev = get_device(conn->vid);
+
close(connfd);
*remove = 1;
- vhost_destroy_device(conn->vid);
+
+ if (dev)
+ vhost_destroy_device_notify(dev);
if (vsocket->notify_ops->destroy_connection)
vsocket->notify_ops->destroy_connection(conn->vid);
+ vhost_destroy_device(conn->vid);
+
pthread_mutex_lock(&vsocket->conn_mutex);
TAILQ_REMOVE(&vsocket->conn_list, conn, next);
pthread_mutex_unlock(&vsocket->conn_mutex);
{
int i;
+ if (path == NULL)
+ return NULL;
+
for (i = 0; i < vhost_user.vsocket_cnt; i++) {
struct vhost_user_socket *vsocket = vhost_user.vsockets[i];
{
struct vhost_user_socket *vsocket;
- if (rte_vdpa_get_device(did) == NULL)
+ if (rte_vdpa_get_device(did) == NULL || path == NULL)
return -1;
pthread_mutex_lock(&vhost_user.mutex);
return ret;
}
+int
+rte_vhost_driver_set_protocol_features(const char *path,
+ uint64_t protocol_features)
+{
+ struct vhost_user_socket *vsocket;
+
+ pthread_mutex_lock(&vhost_user.mutex);
+ vsocket = find_vhost_user_socket(path);
+ if (vsocket)
+ vsocket->protocol_features = protocol_features;
+ pthread_mutex_unlock(&vhost_user.mutex);
+ return vsocket ? 0 : -1;
+}
+
int
rte_vhost_driver_get_protocol_features(const char *path,
uint64_t *protocol_features)
goto out_free;
}
vsocket->dequeue_zero_copy = flags & RTE_VHOST_USER_DEQUEUE_ZERO_COPY;
+ vsocket->extbuf = flags & RTE_VHOST_USER_EXTBUF_SUPPORT;
+ vsocket->linearbuf = flags & RTE_VHOST_USER_LINEARBUF_SUPPORT;
+
+ if (vsocket->dequeue_zero_copy &&
+ (flags & RTE_VHOST_USER_IOMMU_SUPPORT)) {
+ RTE_LOG(ERR, VHOST_CONFIG,
+ "error: enabling dequeue zero copy and IOMMU features "
+ "simultaneously is not supported\n");
+ goto out_mutex;
+ }
/*
* Set the supported features correctly for the builtin vhost-user
* not compatible with postcopy.
*/
if (vsocket->dequeue_zero_copy) {
+ if (vsocket->extbuf) {
+ RTE_LOG(ERR, VHOST_CONFIG,
+ "error: zero copy is incompatible with external buffers\n");
+ ret = -1;
+ goto out_mutex;
+ }
+ if (vsocket->linearbuf) {
+ RTE_LOG(ERR, VHOST_CONFIG,
+ "error: zero copy is incompatible with linear buffers\n");
+ ret = -1;
+ goto out_mutex;
+ }
vsocket->supported_features &= ~(1ULL << VIRTIO_F_IN_ORDER);
vsocket->features &= ~(1ULL << VIRTIO_F_IN_ORDER);
~(1ULL << VHOST_USER_PROTOCOL_F_PAGEFAULT);
}
+ /*
+ * We'll not be able to receive a buffer from guest in linear mode
+ * without external buffer if it will not fit in a single mbuf, which is
+ * likely if segmentation offloading enabled.
+ */
+ if (vsocket->linearbuf && !vsocket->extbuf) {
+ uint64_t seg_offload_features =
+ (1ULL << VIRTIO_NET_F_HOST_TSO4) |
+ (1ULL << VIRTIO_NET_F_HOST_TSO6) |
+ (1ULL << VIRTIO_NET_F_HOST_UFO);
+
+ RTE_LOG(INFO, VHOST_CONFIG,
+ "Linear buffers requested without external buffers, "
+ "disabling host segmentation offloading support\n");
+ vsocket->supported_features &= ~seg_offload_features;
+ vsocket->features &= ~seg_offload_features;
+ }
+
if (!(flags & RTE_VHOST_USER_IOMMU_SUPPORT)) {
vsocket->supported_features &= ~(1ULL << VIRTIO_F_IOMMU_PLATFORM);
vsocket->features &= ~(1ULL << VIRTIO_F_IOMMU_PLATFORM);
int count;
struct vhost_user_connection *conn, *next;
+ if (path == NULL)
+ return -1;
+
+again:
pthread_mutex_lock(&vhost_user.mutex);
for (i = 0; i < vhost_user.vsocket_cnt; i++) {
struct vhost_user_socket *vsocket = vhost_user.vsockets[i];
if (!strcmp(vsocket->path, path)) {
-again:
pthread_mutex_lock(&vsocket->conn_mutex);
for (conn = TAILQ_FIRST(&vsocket->conn_list);
conn != NULL;
conn->connfd) == -1) {
pthread_mutex_unlock(
&vsocket->conn_mutex);
+ pthread_mutex_unlock(&vhost_user.mutex);
goto again;
}