From patchwork Sat Dec 23 03:36:42 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhihong Wang X-Patchwork-Id: 32643 X-Patchwork-Delegate: maxime.coquelin@redhat.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id EF6061B40B; Fri, 22 Dec 2017 16:41:25 +0100 (CET) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by dpdk.org (Postfix) with ESMTP id 264761B3E5 for ; Fri, 22 Dec 2017 16:41:23 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 Dec 2017 07:41:22 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.45,441,1508828400"; d="scan'208";a="4814574" Received: from unknown (HELO dpdk98.sh.intel.com) ([10.67.111.140]) by orsmga007.jf.intel.com with ESMTP; 22 Dec 2017 07:41:20 -0800 From: Zhihong Wang To: dev@dpdk.org Cc: jianfeng.tan@intel.com, tiwei.bie@intel.com, maxime.coquelin@redhat.com, yliu@fridaylinux.org, cunming.liang@intel.com, xiao.w.wang@intel.com, dan.daly@intel.com, Zhihong Wang Date: Fri, 22 Dec 2017 22:36:42 -0500 Message-Id: <1514000203-69699-2-git-send-email-zhihong.wang@intel.com> X-Mailer: git-send-email 2.7.5 In-Reply-To: <1514000203-69699-1-git-send-email-zhihong.wang@intel.com> References: <1514000203-69699-1-git-send-email-zhihong.wang@intel.com> Subject: [dpdk-dev] [PATCH RFC 1/2] vhost: make capabilities configurable X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch makes vhost device capabilities configurable to adopt various engines. Such capabilities include supported features, protocol features, queue number. APIs are introduced to let app configure these capabilities. Signed-off-by: Zhihong Wang --- lib/librte_vhost/rte_vhost.h | 50 ++++++++++++++++++++++++++++ lib/librte_vhost/socket.c | 77 +++++++++++++++++++++++++++++++++++++++++++ lib/librte_vhost/vhost_user.c | 48 ++++++++++++++++++++------- 3 files changed, 164 insertions(+), 11 deletions(-) diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h index f653644..17b4c6d 100644 --- a/lib/librte_vhost/rte_vhost.h +++ b/lib/librte_vhost/rte_vhost.h @@ -209,6 +209,56 @@ int rte_vhost_driver_unregister(const char *path); int rte_vhost_driver_set_features(const char *path, uint64_t features); /** + * Get the protocol feature bits before feature negotiation. + * + * @param path + * The vhost-user socket file path + * @param protocol_features + * A pointer to store the queried protocol feature bits + * @return + * 0 on success, -1 on failure + */ +int rte_vhost_driver_get_protocol_features(const char *path, + uint64_t *protocol_features); + +/** + * Set the protocol feature bits the vhost-user driver supports. + * + * @param path + * The vhost-user socket file path + * @param protocol_features + * Supported protocol features + * @return + * 0 on success, -1 on failure + */ +int rte_vhost_driver_set_protocol_features(const char *path, + uint64_t protocol_features); + +/** + * Get the queue number before feature negotiation. + * + * @param path + * The vhost-user socket file path + * @param queue_num + * A pointer to store the queried queue number + * @return + * 0 on success, -1 on failure + */ +int rte_vhost_driver_get_queue_num(const char *path, uint16_t *queue_num); + +/** + * Set the queue number the vhost-user driver supports. + * + * @param path + * The vhost-user socket file path + * @param queue_num + * Supported queue number + * @return + * 0 on success, -1 on failure + */ +int rte_vhost_driver_set_queue_num(const char *path, uint16_t queue_num); + +/** * Enable vhost-user driver features. * * Note that diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c index 422da00..742f772 100644 --- a/lib/librte_vhost/socket.c +++ b/lib/librte_vhost/socket.c @@ -78,7 +78,10 @@ struct vhost_user_socket { * features negotiation. */ uint64_t supported_features; + uint64_t supported_protocol_features; uint64_t features; + uint64_t protocol_features; + uint16_t queue_num; struct vhost_device_ops const *notify_ops; }; @@ -613,6 +616,75 @@ rte_vhost_driver_get_features(const char *path, uint64_t *features) } } +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->supported_protocol_features = protocol_features; + 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) +{ + struct vhost_user_socket *vsocket; + + pthread_mutex_lock(&vhost_user.mutex); + vsocket = find_vhost_user_socket(path); + if (vsocket) + *protocol_features = vsocket->protocol_features; + pthread_mutex_unlock(&vhost_user.mutex); + + if (!vsocket) { + RTE_LOG(ERR, VHOST_CONFIG, + "socket file %s is not registered yet.\n", path); + return -1; + } else { + return 0; + } +} + +int rte_vhost_driver_set_queue_num(const char *path, uint16_t queue_num) +{ + struct vhost_user_socket *vsocket; + + pthread_mutex_lock(&vhost_user.mutex); + vsocket = find_vhost_user_socket(path); + if (vsocket) + vsocket->queue_num = queue_num; + pthread_mutex_unlock(&vhost_user.mutex); + + return vsocket ? 0 : -1; +} + +int rte_vhost_driver_get_queue_num(const char *path, uint16_t *queue_num) +{ + struct vhost_user_socket *vsocket; + + pthread_mutex_lock(&vhost_user.mutex); + vsocket = find_vhost_user_socket(path); + if (vsocket) + *queue_num = vsocket->queue_num; + pthread_mutex_unlock(&vhost_user.mutex); + + if (!vsocket) { + RTE_LOG(ERR, VHOST_CONFIG, + "socket file %s is not registered yet.\n", path); + return -1; + } else { + return 0; + } +} + /* * Register a new vhost-user socket; here we could act as server * (the default case), or client (when RTE_VHOST_USER_CLIENT) flag @@ -675,6 +747,11 @@ rte_vhost_driver_register(const char *path, uint64_t flags) vsocket->features &= ~(1ULL << VIRTIO_F_IOMMU_PLATFORM); } + vsocket->supported_protocol_features = VHOST_USER_PROTOCOL_FEATURES; + vsocket->protocol_features = VHOST_USER_PROTOCOL_FEATURES; + + vsocket->queue_num = VHOST_MAX_QUEUE_PAIRS; + if ((flags & RTE_VHOST_USER_CLIENT) != 0) { vsocket->reconnect = !(flags & RTE_VHOST_USER_NO_RECONNECT); if (vsocket->reconnect && reconn_tid == 0) { diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c index f4c7ce4..0a4d128 100644 --- a/lib/librte_vhost/vhost_user.c +++ b/lib/librte_vhost/vhost_user.c @@ -156,6 +156,18 @@ vhost_user_reset_owner(struct virtio_net *dev) } /* + * The max queue num. + */ +static uint16_t +vhost_user_get_queue_num(struct virtio_net *dev) +{ + uint16_t queue_num = 0; + + rte_vhost_driver_get_queue_num(dev->ifname, &queue_num); + return queue_num; +} + +/* * The features that we support are requested. */ static uint64_t @@ -860,13 +872,17 @@ vhost_user_set_vring_enable(struct virtio_net *dev, return 0; } -static void -vhost_user_get_protocol_features(struct virtio_net *dev, - struct VhostUserMsg *msg) +/* + * The protocol features that we support are requested. + */ + +static uint64_t +vhost_user_get_protocol_features(struct virtio_net *dev) { - uint64_t features, protocol_features = VHOST_USER_PROTOCOL_FEATURES; + uint64_t features, protocol_features; rte_vhost_driver_get_features(dev->ifname, &features); + rte_vhost_driver_get_protocol_features(dev->ifname, &protocol_features); /* * REPLY_ACK protocol feature is only mandatory for now @@ -877,18 +893,27 @@ vhost_user_get_protocol_features(struct virtio_net *dev, if (!(features & (1ULL << VIRTIO_F_IOMMU_PLATFORM))) protocol_features &= ~(1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK); - msg->payload.u64 = protocol_features; - msg->size = sizeof(msg->payload.u64); + return protocol_features; } -static void +static int vhost_user_set_protocol_features(struct virtio_net *dev, uint64_t protocol_features) { - if (protocol_features & ~VHOST_USER_PROTOCOL_FEATURES) - return; + uint64_t vhost_protocol_features = 0; + + rte_vhost_driver_get_protocol_features(dev->ifname, + &vhost_protocol_features); + if (protocol_features & ~vhost_protocol_features) { + RTE_LOG(ERR, VHOST_CONFIG, + "(%d) received invalid negotiated protocol_features.\n", + dev->vid); + return -1; + } dev->protocol_features = protocol_features; + + return 0; } static int @@ -1252,7 +1277,8 @@ vhost_user_msg_handler(int vid, int fd) break; case VHOST_USER_GET_PROTOCOL_FEATURES: - vhost_user_get_protocol_features(dev, &msg); + msg.payload.u64 = vhost_user_get_protocol_features(dev); + msg.size = sizeof(msg.payload.u64); send_vhost_reply(fd, &msg); break; case VHOST_USER_SET_PROTOCOL_FEATURES: @@ -1312,7 +1338,7 @@ vhost_user_msg_handler(int vid, int fd) break; case VHOST_USER_GET_QUEUE_NUM: - msg.payload.u64 = VHOST_MAX_QUEUE_PAIRS; + msg.payload.u64 = vhost_user_get_queue_num(dev); msg.size = sizeof(msg.payload.u64); send_vhost_reply(fd, &msg); break;