X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_vhost%2Fsocket.c;h=a0a95f9506038e91bd2daee96f0af277d148cc82;hb=406a2bc0c6cf318f1172e0ee0ae2ed2f8e83837c;hp=70181502132a7b32a54a7c5daa61390528cea6f7;hpb=efba12a78ddf6ea2f365d75ed78be2c51cc6c561;p=dpdk.git diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c index 7018150213..a0a95f9506 100644 --- a/lib/librte_vhost/socket.c +++ b/lib/librte_vhost/socket.c @@ -1,39 +1,9 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2016 Intel Corporation */ #include #include -#include #include #include #include @@ -68,6 +38,8 @@ struct vhost_user_socket { bool is_server; bool reconnect; bool dequeue_zero_copy; + bool iommu_support; + bool use_builtin_virtio_net; /* * The "supported_features" indicates the feature bits the @@ -124,6 +96,7 @@ read_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num) size_t fdsize = fd_num * sizeof(int); char control[CMSG_SPACE(fdsize)]; struct cmsghdr *cmsg; + int got_fds = 0; int ret; memset(&msgh, 0, sizeof(msgh)); @@ -150,11 +123,16 @@ read_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num) cmsg = CMSG_NXTHDR(&msgh, cmsg)) { if ((cmsg->cmsg_level == SOL_SOCKET) && (cmsg->cmsg_type == SCM_RIGHTS)) { - memcpy(fds, CMSG_DATA(cmsg), fdsize); + got_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int); + memcpy(fds, CMSG_DATA(cmsg), got_fds * sizeof(int)); break; } } + /* Clear out unused file descriptors */ + while (got_fds < fd_num) + fds[got_fds++] = -1; + return ret; } @@ -180,6 +158,11 @@ send_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num) msgh.msg_control = control; msgh.msg_controllen = sizeof(control); cmsg = CMSG_FIRSTHDR(&msgh); + if (cmsg == NULL) { + RTE_LOG(ERR, VHOST_CONFIG, "cmsg == NULL\n"); + errno = EINVAL; + return -1; + } cmsg->cmsg_len = CMSG_LEN(fdsize); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; @@ -190,7 +173,7 @@ send_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num) } do { - ret = sendmsg(sockfd, &msgh, 0); + ret = sendmsg(sockfd, &msgh, MSG_NOSIGNAL); } while (ret < 0 && errno == EINTR); if (ret < 0) { @@ -223,6 +206,8 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket) size = strnlen(vsocket->path, PATH_MAX); vhost_set_ifname(vid, vsocket->path, size); + vhost_set_builtin_virtio_net(vid, vsocket->use_builtin_virtio_net); + if (vsocket->dequeue_zero_copy) vhost_enable_dequeue_zero_copy(vid); @@ -257,6 +242,8 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket) pthread_mutex_lock(&vsocket->conn_mutex); TAILQ_INSERT_TAIL(&vsocket->conn_list, conn, next); pthread_mutex_unlock(&vsocket->conn_mutex); + + fdset_pipe_notify(&vhost_user.fdset); return; err: @@ -343,6 +330,16 @@ vhost_user_start_server(struct vhost_user_socket *vsocket) int fd = vsocket->socket_fd; const char *path = vsocket->path; + /* + * bind () may fail if the socket file with the same name already + * exists. But the library obviously should not delete the file + * provided by the user, since we can not be sure that it is not + * being used by other applications. Moreover, many applications form + * socket names based on user input, which is prone to errors. + * + * The user must ensure that the socket does not exist before + * registering the vhost driver in server mode. + */ ret = bind(fd, (struct sockaddr *)&vsocket->un, sizeof(vsocket->un)); if (ret < 0) { RTE_LOG(ERR, VHOST_CONFIG, @@ -461,6 +458,7 @@ static int vhost_user_reconnect_init(void) { int ret; + char thread_name[RTE_MAX_THREAD_NAME_LEN]; ret = pthread_mutex_init(&reconn_list.mutex, NULL); if (ret < 0) { @@ -471,12 +469,20 @@ vhost_user_reconnect_init(void) ret = pthread_create(&reconn_tid, NULL, vhost_user_client_reconnect, NULL); - if (ret < 0) { + if (ret != 0) { RTE_LOG(ERR, VHOST_CONFIG, "failed to create reconnect thread"); if (pthread_mutex_destroy(&reconn_list.mutex)) { RTE_LOG(ERR, VHOST_CONFIG, "failed to destroy reconnect mutex"); } + } else { + snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, + "vhost-reconn"); + + if (rte_thread_setname(reconn_tid, thread_name)) { + RTE_LOG(DEBUG, VHOST_CONFIG, + "failed to set reconnect thread name"); + } } return ret; @@ -546,6 +552,12 @@ rte_vhost_driver_disable_features(const char *path, uint64_t features) pthread_mutex_lock(&vhost_user.mutex); vsocket = find_vhost_user_socket(path); + + /* Note that use_builtin_virtio_net is not affected by this function + * since callers may want to selectively disable features of the + * built-in vhost net device backend. + */ + if (vsocket) vsocket->features &= ~features; pthread_mutex_unlock(&vhost_user.mutex); @@ -586,6 +598,11 @@ rte_vhost_driver_set_features(const char *path, uint64_t features) if (vsocket) { vsocket->supported_features = features; vsocket->features = features; + + /* Anyone setting feature bits is implementing their own vhost + * device backend. + */ + vsocket->use_builtin_virtio_net = false; } pthread_mutex_unlock(&vhost_user.mutex); @@ -666,15 +683,20 @@ rte_vhost_driver_register(const char *path, uint64_t flags) * rte_vhost_driver_set_features(), which will overwrite following * two values. */ + vsocket->use_builtin_virtio_net = true; vsocket->supported_features = VIRTIO_NET_SUPPORTED_FEATURES; vsocket->features = VIRTIO_NET_SUPPORTED_FEATURES; + if (!(flags & RTE_VHOST_USER_IOMMU_SUPPORT)) { + vsocket->supported_features &= ~(1ULL << VIRTIO_F_IOMMU_PLATFORM); + vsocket->features &= ~(1ULL << VIRTIO_F_IOMMU_PLATFORM); + } + if ((flags & RTE_VHOST_USER_CLIENT) != 0) { vsocket->reconnect = !(flags & RTE_VHOST_USER_NO_RECONNECT); if (vsocket->reconnect && reconn_tid == 0) { - if (vhost_user_reconnect_init() < 0) { + if (vhost_user_reconnect_init() != 0) goto out_mutex; - } } } else { vsocket->is_server = true; @@ -820,6 +842,7 @@ rte_vhost_driver_start(const char *path) { struct vhost_user_socket *vsocket; static pthread_t fdset_tid; + char thread_name[RTE_MAX_THREAD_NAME_LEN]; pthread_mutex_lock(&vhost_user.mutex); vsocket = find_vhost_user_socket(path); @@ -829,11 +852,33 @@ rte_vhost_driver_start(const char *path) return -1; if (fdset_tid == 0) { + /** + * create a pipe which will be waited by poll and notified to + * rebuild the wait list of poll. + */ + if (fdset_pipe_init(&vhost_user.fdset) < 0) { + RTE_LOG(ERR, VHOST_CONFIG, + "failed to create pipe for vhost fdset\n"); + return -1; + } + int ret = pthread_create(&fdset_tid, NULL, fdset_event_dispatch, &vhost_user.fdset); - if (ret < 0) + if (ret != 0) { RTE_LOG(ERR, VHOST_CONFIG, "failed to create fdset handling thread"); + + fdset_pipe_uninit(&vhost_user.fdset); + return -1; + } else { + snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, + "vhost-events"); + + if (rte_thread_setname(fdset_tid, thread_name)) { + RTE_LOG(DEBUG, VHOST_CONFIG, + "failed to set vhost-event thread name"); + } + } } if (vsocket->is_server)