From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jianfeng Tan Subject: [PATCH v2 4/7] net/virtio_user: abstract virtio user backend ops Date: Fri, 23 Dec 2016 07:14:23 +0000 Message-ID: <1482477266-39199-5-git-send-email-jianfeng.tan@intel.com> References: <1480689075-66977-1-git-send-email-jianfeng.tan@intel.com> <1482477266-39199-1-git-send-email-jianfeng.tan@intel.com> Cc: yuanhan.liu@linux.intel.com, ferruh.yigit@intel.com, cunming.liang@intel.com, Jianfeng Tan To: dev@dpdk.org Return-path: Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id 9C7DE10DEB for ; Fri, 23 Dec 2016 08:13:54 +0100 (CET) In-Reply-To: <1482477266-39199-1-git-send-email-jianfeng.tan@intel.com> List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add a struct virtio_user_backend_ops to abstract three kinds of backend operations: - setup, create the unix socket connection; - send_request, sync messages with backend; - enable_qp, enable some queue pair. Signed-off-by: Jianfeng Tan --- drivers/net/virtio/virtio_user/vhost.h | 19 +++++-- drivers/net/virtio/virtio_user/vhost_user.c | 54 ++++++++----------- drivers/net/virtio/virtio_user/virtio_user_dev.c | 66 +++++++++++++++++------- drivers/net/virtio/virtio_user/virtio_user_dev.h | 7 +++ 4 files changed, 93 insertions(+), 53 deletions(-) diff --git a/drivers/net/virtio/virtio_user/vhost.h b/drivers/net/virtio/virtio_user/vhost.h index e54ac35..bd67133 100644 --- a/drivers/net/virtio/virtio_user/vhost.h +++ b/drivers/net/virtio/virtio_user/vhost.h @@ -103,8 +103,21 @@ struct vhost_memory_region { uint64_t mmap_offset; }; -int vhost_user_sock(int vhostfd, enum vhost_user_request req, void *arg); -int vhost_user_setup(const char *path); -int vhost_user_enable_queue_pair(int vhostfd, uint16_t pair_idx, int enable); +struct virtio_user_dev; +typedef int (*vhost_setup_t)(struct virtio_user_dev *dev); +typedef int (*vhost_send_request_t)(struct virtio_user_dev *dev, + enum vhost_user_request req, + void *arg); +typedef int (*vhost_enable_qp_t)(struct virtio_user_dev *dev, + uint16_t pair_idx, + int enable); + +struct virtio_user_backend_ops { + vhost_setup_t setup; + vhost_send_request_t send_request; + vhost_enable_qp_t enable_qp; +}; + +struct virtio_user_backend_ops ops_user; #endif diff --git a/drivers/net/virtio/virtio_user/vhost_user.c b/drivers/net/virtio/virtio_user/vhost_user.c index 295ce16..faea1b6 100644 --- a/drivers/net/virtio/virtio_user/vhost_user.c +++ b/drivers/net/virtio/virtio_user/vhost_user.c @@ -41,6 +41,7 @@ #include #include "vhost.h" +#include "virtio_user_dev.h" /* The version of the protocol we support */ #define VHOST_USER_VERSION 0x1 @@ -255,24 +256,10 @@ prepare_vhost_memory_user(struct vhost_user_msg *msg, int fds[]) static struct vhost_user_msg m; -static const char * const vhost_msg_strings[] = { - [VHOST_USER_SET_OWNER] = "VHOST_USER_SET_OWNER", - [VHOST_USER_RESET_OWNER] = "VHOST_USER_RESET_OWNER", - [VHOST_USER_SET_FEATURES] = "VHOST_USER_SET_FEATURES", - [VHOST_USER_GET_FEATURES] = "VHOST_USER_GET_FEATURES", - [VHOST_USER_SET_VRING_CALL] = "VHOST_USER_SET_VRING_CALL", - [VHOST_USER_SET_VRING_NUM] = "VHOST_USER_SET_VRING_NUM", - [VHOST_USER_SET_VRING_BASE] = "VHOST_USER_SET_VRING_BASE", - [VHOST_USER_GET_VRING_BASE] = "VHOST_USER_GET_VRING_BASE", - [VHOST_USER_SET_VRING_ADDR] = "VHOST_USER_SET_VRING_ADDR", - [VHOST_USER_SET_VRING_KICK] = "VHOST_USER_SET_VRING_KICK", - [VHOST_USER_SET_MEM_TABLE] = "VHOST_USER_SET_MEM_TABLE", - [VHOST_USER_SET_VRING_ENABLE] = "VHOST_USER_SET_VRING_ENABLE", - NULL, -}; - -int -vhost_user_sock(int vhostfd, enum vhost_user_request req, void *arg) +static int +vhost_user_sock(struct virtio_user_dev *dev, + enum vhost_user_request req, + void *arg) { struct vhost_user_msg msg; struct vhost_vring_file *file = 0; @@ -280,11 +267,9 @@ vhost_user_sock(int vhostfd, enum vhost_user_request req, void *arg) int fds[VHOST_MEMORY_MAX_NREGIONS]; int fd_num = 0; int i, len; + int vhostfd = dev->vhostfd; RTE_SET_USED(m); - RTE_SET_USED(vhost_msg_strings); - - PMD_DRV_LOG(INFO, "%s", vhost_msg_strings[req]); msg.request = req; msg.flags = VHOST_USER_VERSION; @@ -355,8 +340,8 @@ vhost_user_sock(int vhostfd, enum vhost_user_request req, void *arg) len = VHOST_USER_HDR_SIZE + msg.size; if (vhost_user_write(vhostfd, &msg, len, fds, fd_num) < 0) { - PMD_DRV_LOG(ERR, "%s failed: %s", - vhost_msg_strings[req], strerror(errno)); + PMD_DRV_LOG(ERR, "fail to write vhost user msg: %s", + strerror(errno)); return -1; } @@ -403,15 +388,13 @@ vhost_user_sock(int vhostfd, enum vhost_user_request req, void *arg) /** * Set up environment to talk with a vhost user backend. - * @param path - * - The path to vhost user unix socket file. * * @return * - (-1) if fail to set up; * - (>=0) if successful, and it is the fd to vhostfd. */ -int -vhost_user_setup(const char *path) +static int +vhost_user_setup(struct virtio_user_dev *dev) { int fd; int flag; @@ -429,7 +412,7 @@ vhost_user_setup(const char *path) memset(&un, 0, sizeof(un)); un.sun_family = AF_UNIX; - snprintf(un.sun_path, sizeof(un.sun_path), "%s", path); + snprintf(un.sun_path, sizeof(un.sun_path), "%s", dev->path); if (connect(fd, (struct sockaddr *)&un, sizeof(un)) < 0) { PMD_DRV_LOG(ERR, "connect error, %s", strerror(errno)); close(fd); @@ -439,8 +422,10 @@ vhost_user_setup(const char *path) return fd; } -int -vhost_user_enable_queue_pair(int vhostfd, uint16_t pair_idx, int enable) +static int +vhost_user_enable_queue_pair(struct virtio_user_dev *dev, + uint16_t pair_idx, + int enable) { int i; @@ -450,10 +435,15 @@ vhost_user_enable_queue_pair(int vhostfd, uint16_t pair_idx, int enable) .num = enable, }; - if (vhost_user_sock(vhostfd, - VHOST_USER_SET_VRING_ENABLE, &state)) + if (vhost_user_sock(dev, VHOST_USER_SET_VRING_ENABLE, &state)) return -1; } return 0; } + +struct virtio_user_backend_ops ops_user = { + .setup = vhost_user_setup, + .send_request = vhost_user_sock, + .enable_qp = vhost_user_enable_queue_pair +}; diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c index 66a8ffe..a818c29 100644 --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c @@ -39,6 +39,9 @@ #include #include #include +#include +#include +#include #include "vhost.h" #include "virtio_user_dev.h" @@ -64,7 +67,7 @@ virtio_user_create_queue(struct virtio_user_dev *dev, uint32_t queue_sel) } file.index = queue_sel; file.fd = callfd; - vhost_user_sock(dev->vhostfd, VHOST_USER_SET_VRING_CALL, &file); + dev->ops->send_request(dev, VHOST_USER_SET_VRING_CALL, &file); dev->callfds[queue_sel] = callfd; return 0; @@ -88,12 +91,12 @@ virtio_user_kick_queue(struct virtio_user_dev *dev, uint32_t queue_sel) state.index = queue_sel; state.num = vring->num; - vhost_user_sock(dev->vhostfd, VHOST_USER_SET_VRING_NUM, &state); + dev->ops->send_request(dev, VHOST_USER_SET_VRING_NUM, &state); state.num = 0; /* no reservation */ - vhost_user_sock(dev->vhostfd, VHOST_USER_SET_VRING_BASE, &state); + dev->ops->send_request(dev, VHOST_USER_SET_VRING_BASE, &state); - vhost_user_sock(dev->vhostfd, VHOST_USER_SET_VRING_ADDR, &addr); + dev->ops->send_request(dev, VHOST_USER_SET_VRING_ADDR, &addr); /* Of all per virtqueue MSGs, make sure VHOST_USER_SET_VRING_KICK comes * lastly because vhost depends on this msg to judge if @@ -106,7 +109,7 @@ virtio_user_kick_queue(struct virtio_user_dev *dev, uint32_t queue_sel) } file.index = queue_sel; file.fd = kickfd; - vhost_user_sock(dev->vhostfd, VHOST_USER_SET_VRING_KICK, &file); + dev->ops->send_request(dev, VHOST_USER_SET_VRING_KICK, &file); dev->kickfds[queue_sel] = kickfd; return 0; @@ -147,18 +150,17 @@ virtio_user_start_device(struct virtio_user_dev *dev) goto error; /* Step 1: set features - * Make sure VHOST_USER_F_PROTOCOL_FEATURES is added if mq is enabled, - * and VIRTIO_NET_F_MAC is stripped. + * Strip VIRTIO_NET_F_MAC, as MAC address is handled in vdev init. */ features = dev->features; features &= ~(1ull << VIRTIO_NET_F_MAC); - ret = vhost_user_sock(dev->vhostfd, VHOST_USER_SET_FEATURES, &features); + ret = dev->ops->send_request(dev, VHOST_USER_SET_FEATURES, &features); if (ret < 0) goto error; PMD_DRV_LOG(INFO, "set features: %" PRIx64, features); /* Step 2: share memory regions */ - ret = vhost_user_sock(dev->vhostfd, VHOST_USER_SET_MEM_TABLE, NULL); + ret = dev->ops->send_request(dev, VHOST_USER_SET_MEM_TABLE, NULL); if (ret < 0) goto error; @@ -169,7 +171,7 @@ virtio_user_start_device(struct virtio_user_dev *dev) /* Step 4: enable queues * we enable the 1st queue pair by default. */ - vhost_user_enable_queue_pair(dev->vhostfd, 0, 1); + dev->ops->enable_qp(dev, 0, 1); return 0; error: @@ -179,7 +181,7 @@ virtio_user_start_device(struct virtio_user_dev *dev) int virtio_user_stop_device(struct virtio_user_dev *dev) { - return vhost_user_sock(dev->vhostfd, VHOST_USER_RESET_OWNER, NULL); + return dev->ops->send_request(dev, VHOST_USER_RESET_OWNER, NULL); } static inline void @@ -203,6 +205,36 @@ parse_mac(struct virtio_user_dev *dev, const char *mac) } } +static int +is_vhost_user_by_type(const char *path) +{ + struct stat sb; + + if (stat(path, &sb) == -1) + return 0; + + return S_ISSOCK(sb.st_mode); +} + +static int +virtio_user_dev_setup(struct virtio_user_dev *dev) +{ + uint32_t i; + + dev->vhostfd = -1; + for (i = 0; i < VIRTIO_MAX_VIRTQUEUES * 2 + 1; ++i) { + dev->kickfds[i] = -1; + dev->callfds[i] = -1; + } + + if (is_vhost_user_by_type(dev->path)) { + dev->ops = &ops_user; + return dev->ops->setup(dev); + } + + return -1; +} + int virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues, int cq, int queue_size, const char *mac) @@ -213,19 +245,17 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues, dev->queue_size = queue_size; dev->mac_specified = 0; parse_mac(dev, mac); - dev->vhostfd = -1; - dev->vhostfd = vhost_user_setup(dev->path); - if (dev->vhostfd < 0) { + if (virtio_user_dev_setup(dev) < 0) { PMD_INIT_LOG(ERR, "backend set up fails"); return -1; } - if (vhost_user_sock(dev->vhostfd, VHOST_USER_SET_OWNER, NULL) < 0) { + if (dev->ops->send_request(dev, VHOST_USER_SET_OWNER, NULL) < 0) { PMD_INIT_LOG(ERR, "set_owner fails: %s", strerror(errno)); return -1; } - if (vhost_user_sock(dev->vhostfd, VHOST_USER_GET_FEATURES, + if (dev->ops->send_request(dev, VHOST_USER_GET_FEATURES, &dev->device_features) < 0) { PMD_INIT_LOG(ERR, "get_features failed: %s", strerror(errno)); return -1; @@ -277,9 +307,9 @@ virtio_user_handle_mq(struct virtio_user_dev *dev, uint16_t q_pairs) } for (i = 0; i < q_pairs; ++i) - ret |= vhost_user_enable_queue_pair(dev->vhostfd, i, 1); + ret |= dev->ops->enable_qp(dev, i, 1); for (i = q_pairs; i < dev->max_queue_pairs; ++i) - ret |= vhost_user_enable_queue_pair(dev->vhostfd, i, 0); + ret |= dev->ops->enable_qp(dev, i, 0); dev->queue_pairs = q_pairs; diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h b/drivers/net/virtio/virtio_user/virtio_user_dev.h index 28fc788..503a496 100644 --- a/drivers/net/virtio/virtio_user/virtio_user_dev.h +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h @@ -37,9 +37,15 @@ #include #include "../virtio_pci.h" #include "../virtio_ring.h" +#include "vhost.h" struct virtio_user_dev { + /* for vhost_user backend */ int vhostfd; + + /* for vhost_kernel backend */ + + /* for both vhost_user and vhost_kernel */ int callfds[VIRTIO_MAX_VIRTQUEUES * 2 + 1]; int kickfds[VIRTIO_MAX_VIRTQUEUES * 2 + 1]; int mac_specified; @@ -54,6 +60,7 @@ struct virtio_user_dev { uint8_t mac_addr[ETHER_ADDR_LEN]; char path[PATH_MAX]; struct vring vrings[VIRTIO_MAX_VIRTQUEUES * 2 + 1]; + struct virtio_user_backend_ops *ops; }; int virtio_user_start_device(struct virtio_user_dev *dev); -- 2.7.4