vhost: replace vDPA device ID in Vhost
[dpdk.git] / lib / librte_vhost / socket.c
index 8bc1e3a..49267ce 100644 (file)
@@ -55,12 +55,7 @@ struct vhost_user_socket {
 
        uint64_t protocol_features;
 
-       /*
-        * Device id to identify a specific backend device.
-        * It's set to -1 for the default software implementation.
-        * If valid, one socket can have 1 connection only.
-        */
-       int vdpa_dev_id;
+       struct rte_vdpa_device *vdpa_dev;
 
        struct vhost_device_ops const *notify_ops;
 };
@@ -127,7 +122,8 @@ read_fd_message(int sockfd, char *buf, int buflen, int *fds, int max_fds,
 
        ret = recvmsg(sockfd, &msgh, 0);
        if (ret <= 0) {
-               VHOST_LOG_CONFIG(ERR, "recvmsg failed\n");
+               if (ret)
+                       VHOST_LOG_CONFIG(ERR, "recvmsg failed\n");
                return ret;
        }
 
@@ -229,7 +225,7 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket)
 
        vhost_set_builtin_virtio_net(vid, vsocket->use_builtin_virtio_net);
 
-       vhost_attach_vdpa_device(vid, vsocket->vdpa_dev_id);
+       vhost_attach_vdpa_device(vid, vsocket->vdpa_dev);
 
        if (vsocket->dequeue_zero_copy)
                vhost_enable_dequeue_zero_copy(vid);
@@ -318,16 +314,16 @@ vhost_user_read_cb(int connfd, void *dat, int *remove)
 
                vhost_destroy_device(conn->vid);
 
+               if (vsocket->reconnect) {
+                       create_unix_socket(vsocket);
+                       vhost_user_start_client(vsocket);
+               }
+
                pthread_mutex_lock(&vsocket->conn_mutex);
                TAILQ_REMOVE(&vsocket->conn_list, conn, next);
                pthread_mutex_unlock(&vsocket->conn_mutex);
 
                free(conn);
-
-               if (vsocket->reconnect) {
-                       create_unix_socket(vsocket);
-                       vhost_user_start_client(vsocket);
-               }
        }
 }
 
@@ -577,17 +573,18 @@ find_vhost_user_socket(const char *path)
 }
 
 int
-rte_vhost_driver_attach_vdpa_device(const char *path, int did)
+rte_vhost_driver_attach_vdpa_device(const char *path,
+               struct rte_vdpa_device *dev)
 {
        struct vhost_user_socket *vsocket;
 
-       if (rte_vdpa_get_device(did) == NULL || path == NULL)
+       if (dev == NULL || path == NULL)
                return -1;
 
        pthread_mutex_lock(&vhost_user.mutex);
        vsocket = find_vhost_user_socket(path);
        if (vsocket)
-               vsocket->vdpa_dev_id = did;
+               vsocket->vdpa_dev = dev;
        pthread_mutex_unlock(&vhost_user.mutex);
 
        return vsocket ? 0 : -1;
@@ -601,25 +598,25 @@ rte_vhost_driver_detach_vdpa_device(const char *path)
        pthread_mutex_lock(&vhost_user.mutex);
        vsocket = find_vhost_user_socket(path);
        if (vsocket)
-               vsocket->vdpa_dev_id = -1;
+               vsocket->vdpa_dev = NULL;
        pthread_mutex_unlock(&vhost_user.mutex);
 
        return vsocket ? 0 : -1;
 }
 
-int
-rte_vhost_driver_get_vdpa_device_id(const char *path)
+struct rte_vdpa_device *
+rte_vhost_driver_get_vdpa_device(const char *path)
 {
        struct vhost_user_socket *vsocket;
-       int did = -1;
+       struct rte_vdpa_device *dev = NULL;
 
        pthread_mutex_lock(&vhost_user.mutex);
        vsocket = find_vhost_user_socket(path);
        if (vsocket)
-               did = vsocket->vdpa_dev_id;
+               dev = vsocket->vdpa_dev;
        pthread_mutex_unlock(&vhost_user.mutex);
 
-       return did;
+       return dev;
 }
 
 int
@@ -692,7 +689,6 @@ rte_vhost_driver_get_features(const char *path, uint64_t *features)
        struct vhost_user_socket *vsocket;
        uint64_t vdpa_features;
        struct rte_vdpa_device *vdpa_dev;
-       int did = -1;
        int ret = 0;
 
        pthread_mutex_lock(&vhost_user.mutex);
@@ -704,14 +700,13 @@ rte_vhost_driver_get_features(const char *path, uint64_t *features)
                goto unlock_exit;
        }
 
-       did = vsocket->vdpa_dev_id;
-       vdpa_dev = rte_vdpa_get_device(did);
+       vdpa_dev = vsocket->vdpa_dev;
        if (!vdpa_dev || !vdpa_dev->ops->get_features) {
                *features = vsocket->features;
                goto unlock_exit;
        }
 
-       if (vdpa_dev->ops->get_features(did, &vdpa_features) < 0) {
+       if (vdpa_dev->ops->get_features(vdpa_dev, &vdpa_features) < 0) {
                VHOST_LOG_CONFIG(ERR,
                                "failed to get vdpa features "
                                "for socket file %s.\n", path);
@@ -747,7 +742,6 @@ rte_vhost_driver_get_protocol_features(const char *path,
        struct vhost_user_socket *vsocket;
        uint64_t vdpa_protocol_features;
        struct rte_vdpa_device *vdpa_dev;
-       int did = -1;
        int ret = 0;
 
        pthread_mutex_lock(&vhost_user.mutex);
@@ -759,14 +753,13 @@ rte_vhost_driver_get_protocol_features(const char *path,
                goto unlock_exit;
        }
 
-       did = vsocket->vdpa_dev_id;
-       vdpa_dev = rte_vdpa_get_device(did);
+       vdpa_dev = vsocket->vdpa_dev;
        if (!vdpa_dev || !vdpa_dev->ops->get_protocol_features) {
                *protocol_features = vsocket->protocol_features;
                goto unlock_exit;
        }
 
-       if (vdpa_dev->ops->get_protocol_features(did,
+       if (vdpa_dev->ops->get_protocol_features(vdpa_dev,
                                &vdpa_protocol_features) < 0) {
                VHOST_LOG_CONFIG(ERR,
                                "failed to get vdpa protocol features "
@@ -789,7 +782,6 @@ rte_vhost_driver_get_queue_num(const char *path, uint32_t *queue_num)
        struct vhost_user_socket *vsocket;
        uint32_t vdpa_queue_num;
        struct rte_vdpa_device *vdpa_dev;
-       int did = -1;
        int ret = 0;
 
        pthread_mutex_lock(&vhost_user.mutex);
@@ -801,14 +793,13 @@ rte_vhost_driver_get_queue_num(const char *path, uint32_t *queue_num)
                goto unlock_exit;
        }
 
-       did = vsocket->vdpa_dev_id;
-       vdpa_dev = rte_vdpa_get_device(did);
+       vdpa_dev = vsocket->vdpa_dev;
        if (!vdpa_dev || !vdpa_dev->ops->get_queue_num) {
                *queue_num = VHOST_MAX_QUEUE_PAIRS;
                goto unlock_exit;
        }
 
-       if (vdpa_dev->ops->get_queue_num(did, &vdpa_queue_num) < 0) {
+       if (vdpa_dev->ops->get_queue_num(vdpa_dev, &vdpa_queue_num) < 0) {
                VHOST_LOG_CONFIG(ERR,
                                "failed to get vdpa queue number "
                                "for socket file %s.\n", path);
@@ -877,7 +868,7 @@ rte_vhost_driver_register(const char *path, uint64_t flags)
                        "error: failed to init connection mutex\n");
                goto out_free;
        }
-       vsocket->vdpa_dev_id = -1;
+       vsocket->vdpa_dev = NULL;
        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;
@@ -925,6 +916,12 @@ rte_vhost_driver_register(const char *path, uint64_t flags)
                        ret = -1;
                        goto out_mutex;
                }
+               if ((flags & RTE_VHOST_USER_CLIENT) != 0) {
+                       VHOST_LOG_CONFIG(ERR,
+                       "error: zero copy is incompatible with vhost client mode\n");
+                       ret = -1;
+                       goto out_mutex;
+               }
                vsocket->supported_features &= ~(1ULL << VIRTIO_F_IN_ORDER);
                vsocket->features &= ~(1ULL << VIRTIO_F_IN_ORDER);
 
@@ -1052,9 +1049,10 @@ again:
                                next = TAILQ_NEXT(conn, next);
 
                                /*
-                                * If r/wcb is executing, release the
-                                * conn_mutex lock, and try again since
-                                * the r/wcb may use the conn_mutex lock.
+                                * If r/wcb is executing, release vsocket's
+                                * conn_mutex and vhost_user's mutex locks, and
+                                * try again since the r/wcb may use the
+                                * conn_mutex and mutex locks.
                                 */
                                if (fdset_try_del(&vhost_user.fdset,
                                                  conn->connfd) == -1) {
@@ -1075,8 +1073,17 @@ again:
                        pthread_mutex_unlock(&vsocket->conn_mutex);
 
                        if (vsocket->is_server) {
-                               fdset_del(&vhost_user.fdset,
-                                               vsocket->socket_fd);
+                               /*
+                                * If r/wcb is executing, release vhost_user's
+                                * mutex lock, and try again since the r/wcb
+                                * may use the mutex lock.
+                                */
+                               if (fdset_try_del(&vhost_user.fdset,
+                                               vsocket->socket_fd) == -1) {
+                                       pthread_mutex_unlock(&vhost_user.mutex);
+                                       goto again;
+                               }
+
                                close(vsocket->socket_fd);
                                unlink(path);
                        } else if (vsocket->reconnect) {