Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/85395/?format=api
https://patches.dpdk.org/api/patches/85395/?format=api", "web_url": "https://patches.dpdk.org/project/dpdk/patch/20201218073851.93609-7-chenbo.xia@intel.com/", "project": { "id": 1, "url": "https://patches.dpdk.org/api/projects/1/?format=api", "name": "DPDK", "link_name": "dpdk", "list_id": "dev.dpdk.org", "list_email": "dev@dpdk.org", "web_url": "http://core.dpdk.org", "scm_url": "git://dpdk.org/dpdk", "webscm_url": "http://git.dpdk.org/dpdk", "list_archive_url": "https://inbox.dpdk.org/dev", "list_archive_url_format": "https://inbox.dpdk.org/dev/{}", "commit_url_format": "" }, "msgid": "<20201218073851.93609-7-chenbo.xia@intel.com>", "list_archive_url": "https://inbox.dpdk.org/dev/20201218073851.93609-7-chenbo.xia@intel.com", "date": "2020-12-18T07:38:48", "name": "[6/9] vfio_user: add client APIs of device attach/detach", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": true, "hash": "a1a8ea7359337d64920105b7ec4528b2f2e16dd5", "submitter": { "id": 1276, "url": "https://patches.dpdk.org/api/people/1276/?format=api", "name": "Chenbo Xia", "email": "chenbo.xia@intel.com" }, "delegate": { "id": 1, "url": "https://patches.dpdk.org/api/users/1/?format=api", "username": "tmonjalo", "first_name": "Thomas", "last_name": "Monjalon", "email": "thomas@monjalon.net" }, "mbox": "https://patches.dpdk.org/project/dpdk/patch/20201218073851.93609-7-chenbo.xia@intel.com/mbox/", "series": [ { "id": 14361, "url": "https://patches.dpdk.org/api/series/14361/?format=api", "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=14361", "date": "2020-12-18T07:38:42", "name": "Introduce vfio-user library", "version": 1, "mbox": "https://patches.dpdk.org/series/14361/mbox/" } ], "comments": "https://patches.dpdk.org/api/patches/85395/comments/", "check": "success", "checks": "https://patches.dpdk.org/api/patches/85395/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<dev-bounces@dpdk.org>", "X-Original-To": "patchwork@inbox.dpdk.org", "Delivered-To": "patchwork@inbox.dpdk.org", "Received": [ "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 20FD1A09F6;\n\tFri, 18 Dec 2020 08:56:19 +0100 (CET)", "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 18A2CCA6E;\n\tFri, 18 Dec 2020 08:54:31 +0100 (CET)", "from mga05.intel.com (mga05.intel.com [192.55.52.43])\n by dpdk.org (Postfix) with ESMTP id F3C13CAB6\n for <dev@dpdk.org>; Fri, 18 Dec 2020 08:54:29 +0100 (CET)", "from fmsmga008.fm.intel.com ([10.253.24.58])\n by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 17 Dec 2020 23:54:29 -0800", "from npg-dpdk-virtio-xiachenbo-nw.sh.intel.com ([10.67.119.123])\n by fmsmga008.fm.intel.com with ESMTP; 17 Dec 2020 23:54:26 -0800" ], "IronPort-SDR": [ "\n kmZzsObGkg2g1GXqXsYptxO188F8VymJp7U9Bv2OS+Bsge6Qll5BhLtpMsxrXkgNvIssrd0+5f\n Ggic49pRBEeQ==", "\n YwUA+YdVrjVHWKFMStXHqhV915aAAVY3NOsjwHm0qriTTpSOaNxjVRxC+H+PlJoS31zrPwAN3r\n sCUSmEB1Gj1A==" ], "X-IronPort-AV": [ "E=McAfee;i=\"6000,8403,9838\"; a=\"260126178\"", "E=Sophos;i=\"5.78,429,1599548400\"; d=\"scan'208\";a=\"260126178\"", "E=Sophos;i=\"5.78,429,1599548400\"; d=\"scan'208\";a=\"340270408\"" ], "X-ExtLoop1": "1", "From": "Chenbo Xia <chenbo.xia@intel.com>", "To": "dev@dpdk.org,\n\tthomas@monjalon.net,\n\tdavid.marchand@redhat.com", "Cc": "stephen@networkplumber.org, cunming.liang@intel.com, xiuchun.lu@intel.com,\n miao.li@intel.com, jingjing.wu@intel.com", "Date": "Fri, 18 Dec 2020 15:38:48 +0800", "Message-Id": "<20201218073851.93609-7-chenbo.xia@intel.com>", "X-Mailer": "git-send-email 2.17.1", "In-Reply-To": "<20201218073851.93609-1-chenbo.xia@intel.com>", "References": "<20201218073851.93609-1-chenbo.xia@intel.com>", "Subject": "[dpdk-dev] [PATCH 6/9] vfio_user: add client APIs of device\n\tattach/detach", "X-BeenThere": "dev@dpdk.org", "X-Mailman-Version": "2.1.15", "Precedence": "list", "List-Id": "DPDK patches and discussions <dev.dpdk.org>", "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>", "List-Archive": "<http://mails.dpdk.org/archives/dev/>", "List-Post": "<mailto:dev@dpdk.org>", "List-Help": "<mailto:dev-request@dpdk.org?subject=help>", "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>", "Errors-To": "dev-bounces@dpdk.org", "Sender": "\"dev\" <dev-bounces@dpdk.org>" }, "content": "This patch implements two APIs, rte_vfio_user_attach_dev() and\nrte_vfio_user_detach_dev() for vfio-user client to connect to\nor disconnect from a vfio-user device on server side.\n\nSigned-off-by: Chenbo Xia <chenbo.xia@intel.com>\nSigned-off-by: Xiuchun Lu <xiuchun.lu@intel.com>\n---\n lib/librte_vfio_user/meson.build | 3 +-\n lib/librte_vfio_user/rte_vfio_user.h | 30 +++\n lib/librte_vfio_user/version.map | 2 +\n lib/librte_vfio_user/vfio_user_client.c | 279 ++++++++++++++++++++++++\n lib/librte_vfio_user/vfio_user_client.h | 25 +++\n 5 files changed, 338 insertions(+), 1 deletion(-)\n create mode 100644 lib/librte_vfio_user/vfio_user_client.c\n create mode 100644 lib/librte_vfio_user/vfio_user_client.h", "diff": "diff --git a/lib/librte_vfio_user/meson.build b/lib/librte_vfio_user/meson.build\nindex b7363f61c6..5761f0edd1 100644\n--- a/lib/librte_vfio_user/meson.build\n+++ b/lib/librte_vfio_user/meson.build\n@@ -6,5 +6,6 @@ if not is_linux\n \treason = 'only supported on Linux'\n endif\n \n-sources = files('vfio_user_base.c', 'vfio_user_server.c')\n+sources = files('vfio_user_base.c', 'vfio_user_server.c',\n+\t'vfio_user_client.c')\n headers = files('rte_vfio_user.h')\ndiff --git a/lib/librte_vfio_user/rte_vfio_user.h b/lib/librte_vfio_user/rte_vfio_user.h\nindex 6c12b0b6ed..b09d83e224 100644\n--- a/lib/librte_vfio_user/rte_vfio_user.h\n+++ b/lib/librte_vfio_user/rte_vfio_user.h\n@@ -225,4 +225,34 @@ __rte_experimental\n int rte_vfio_user_set_irq_info(const char *sock_addr,\n \tstruct rte_vfio_user_irq_info *irq);\n \n+/**\n+ * Below APIs are for vfio-user client (device consumer) to use:\n+ *\t*rte_vfio_user_attach_dev\n+ *\t*rte_vfio_user_detach_dev\n+ */\n+\n+/**\n+ * Attach to a vfio-user device.\n+ *\n+ * @param sock_addr\n+ * Unix domain socket address\n+ * @return\n+ * - >=0: Success, device attached. Returned value is the device ID.\n+ * - <0: Failure on device attach\n+ */\n+__rte_experimental\n+int rte_vfio_user_attach_dev(const char *sock_addr);\n+\n+/**\n+ * Detach from a vfio-user device.\n+ *\n+ * @param dev_id\n+ * Device ID of the vfio-user device\n+ * @return\n+ * - 0: Success, device detached\n+ * - <0: Failure on device detach\n+ */\n+__rte_experimental\n+int rte_vfio_user_detach_dev(int dev_id);\n+\n #endif\ndiff --git a/lib/librte_vfio_user/version.map b/lib/librte_vfio_user/version.map\nindex 621a51a9fc..a0cda2b49c 100644\n--- a/lib/librte_vfio_user/version.map\n+++ b/lib/librte_vfio_user/version.map\n@@ -10,6 +10,8 @@ EXPERIMENTAL {\n \trte_vfio_user_set_dev_info;\n \trte_vfio_user_set_reg_info;\n \trte_vfio_user_set_irq_info;\n+\trte_vfio_user_attach_dev;\n+\trte_vfio_user_detach_dev;\n \n \tlocal: *;\n };\ndiff --git a/lib/librte_vfio_user/vfio_user_client.c b/lib/librte_vfio_user/vfio_user_client.c\nnew file mode 100644\nindex 0000000000..85b2e8cb46\n--- /dev/null\n+++ b/lib/librte_vfio_user/vfio_user_client.c\n@@ -0,0 +1,279 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2020 Intel Corporation\n+ */\n+\n+#include <unistd.h>\n+#include <string.h>\n+#include <pthread.h>\n+#include <fcntl.h>\n+#include <sys/un.h>\n+#include <sys/socket.h>\n+\n+#include \"vfio_user_client.h\"\n+#include \"rte_vfio_user.h\"\n+\n+#define REPLY_USEC 1000\n+#define RECV_MAX_TRY 50\n+\n+static struct vfio_user_client_devs vfio_client_devs = {\n+\t.cl_num = 0,\n+\t.mutex = PTHREAD_MUTEX_INITIALIZER,\n+};\n+\n+/* Check if the sock_addr exists. If not, alloc and return index */\n+static int vfio_user_client_allocate(const char *sock_addr)\n+{\n+\tuint32_t i, count = 0;\n+\tint index = -1;\n+\n+\tif (sock_addr == NULL)\n+\t\treturn -1;\n+\n+\tif (vfio_client_devs.cl_num == 0)\n+\t\treturn 0;\n+\n+\tfor (i = 0; i < MAX_VFIO_USER_CLIENT; i++) {\n+\t\tstruct vfio_user_client *cl = vfio_client_devs.cl[i];\n+\n+\t\tif (!cl) {\n+\t\t\tif (index == -1)\n+\t\t\t\tindex = i;\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tif (!strcmp(cl->sock.sock_addr, sock_addr))\n+\t\t\treturn -1;\n+\n+\t\tcount++;\n+\t\tif (count == vfio_client_devs.cl_num)\n+\t\t\tbreak;\n+\t}\n+\n+\treturn index;\n+}\n+\n+static struct vfio_user_client *\n+vfio_user_client_create_dev(const char *sock_addr)\n+{\n+\tstruct vfio_user_client *cl;\n+\tstruct vfio_user_socket *sock;\n+\tint fd, idx;\n+\tstruct sockaddr_un un;\n+\n+\tpthread_mutex_lock(&vfio_client_devs.mutex);\n+\tif (vfio_client_devs.cl_num == MAX_VFIO_USER_CLIENT) {\n+\t\tVFIO_USER_LOG(ERR, \"Failed to create client:\"\n+\t\t\t\" client num reaches max\\n\");\n+\t\tgoto err;\n+\t}\n+\n+\tidx = vfio_user_client_allocate(sock_addr);\n+\tif (idx < 0) {\n+\t\tVFIO_USER_LOG(ERR, \"Failed to create client:\"\n+\t\t\t\"socket addr exists\\n\");\n+\t\tgoto err;\n+\t}\n+\n+\tcl = malloc(sizeof(*cl));\n+\tif (!cl) {\n+\t\tVFIO_USER_LOG(ERR, \"Failed to alloc client\\n\");\n+\t\tgoto err;\n+\t}\n+\n+\tsock = &cl->sock;\n+\tsock->sock_addr = strdup(sock_addr);\n+\tif (!sock->sock_addr) {\n+\t\tVFIO_USER_LOG(ERR, \"Failed to copy sock_addr\\n\");\n+\t\tgoto err_dup;\n+\t}\n+\n+\tfd = socket(AF_UNIX, SOCK_STREAM, 0);\n+\tif (fd < 0) {\n+\t\tVFIO_USER_LOG(ERR, \"Client failed to create socket: %s\\n\",\n+\t\t\tstrerror(errno));\n+\t\tgoto err_sock;\n+\t}\n+\n+\tif (fcntl(fd, F_SETFL, O_NONBLOCK)) {\n+\t\tVFIO_USER_LOG(ERR, \"Failed to set nonblocking mode for client \"\n+\t\t\t\"socket, fd: %d (%s)\\n\", fd, strerror(errno));\n+\t\tgoto err_ctl;\n+\t}\n+\n+\tmemset(&un, 0, sizeof(un));\n+\tun.sun_family = AF_UNIX;\n+\tstrncpy(un.sun_path, sock->sock_addr, sizeof(un.sun_path));\n+\tun.sun_path[sizeof(un.sun_path) - 1] = '\\0';\n+\n+\tif (connect(fd, &un, sizeof(un)) < 0) {\n+\t\tVFIO_USER_LOG(ERR, \"Client connect error, %s\\n\",\n+\t\t\tstrerror(errno));\n+\t\tgoto err_ctl;\n+\t}\n+\n+\tsock->sock_fd = fd;\n+\tsock->dev_id = idx;\n+\n+\tvfio_client_devs.cl[idx] = cl;\n+\tvfio_client_devs.cl_num++;\n+\n+\tpthread_mutex_unlock(&vfio_client_devs.mutex);\n+\n+\treturn cl;\n+\n+err_ctl:\n+\tclose(fd);\n+err_sock:\n+\tfree(sock->sock_addr);\n+err_dup:\n+\tfree(sock);\n+err:\n+\tpthread_mutex_unlock(&vfio_client_devs.mutex);\n+\treturn NULL;\n+}\n+\n+static int vfio_user_client_destroy_dev(int dev_id)\n+{\n+\tstruct vfio_user_client *cl;\n+\tstruct vfio_user_socket *sock;\n+\tint ret = 0;\n+\n+\tpthread_mutex_lock(&vfio_client_devs.mutex);\n+\tif (vfio_client_devs.cl_num == 0) {\n+\t\tVFIO_USER_LOG(ERR, \"Failed to destroy client:\"\n+\t\t\t\" no client exists\\n\");\n+\t\tret = -EINVAL;\n+\t\tgoto err;\n+\t}\n+\n+\tcl = vfio_client_devs.cl[dev_id];\n+\tif (!cl) {\n+\t\tVFIO_USER_LOG(ERR, \"Failed to destroy client:\"\n+\t\t\t\" wrong device ID(%d)\\n\", dev_id);\n+\t\tret = -EINVAL;\n+\t\tgoto err;\n+\t}\n+\n+\tsock = &cl->sock;\n+\tfree(sock->sock_addr);\n+\tclose(sock->sock_fd);\n+\n+\tfree(cl);\n+\tvfio_client_devs.cl[dev_id] = NULL;\n+\tvfio_client_devs.cl_num--;\n+\n+err:\n+\tpthread_mutex_unlock(&vfio_client_devs.mutex);\n+\treturn ret;\n+}\n+\n+static inline void vfio_user_client_fill_hdr(VFIO_USER_MSG *msg, uint16_t cmd,\n+\tuint32_t sz)\n+{\n+\tstatic uint16_t\tmsg_id;\n+\n+\tmsg->msg_id = msg_id++;\n+\tmsg->cmd = cmd;\n+\tmsg->size = sz;\n+\tmsg->flags = VFIO_USER_TYPE_CMD;\n+\tmsg->err = 0;\n+}\n+\n+static int vfio_user_client_send_recv(int sock_fd, VFIO_USER_MSG *msg)\n+{\n+\tuint16_t cmd = msg->cmd;\n+\tuint16_t id = msg->msg_id;\n+\tuint8_t try_recv = 0;\n+\tint ret;\n+\n+\tret = vfio_user_send_msg(sock_fd, msg);\n+\tif (ret < 0) {\n+\t\tVFIO_USER_LOG(ERR, \"Send error for %s\\n\",\n+\t\t\tvfio_user_msg_str[cmd]);\n+\t\treturn -1;\n+\t}\n+\n+\tVFIO_USER_LOG(INFO, \"Send request %s\\n\", vfio_user_msg_str[cmd]);\n+\n+\tmemset(msg, 0, sizeof(*msg));\n+\n+\twhile (try_recv < RECV_MAX_TRY) {\n+\t\tret = vfio_user_recv_msg(sock_fd, msg);\n+\t\tif (!ret) {\n+\t\t\tVFIO_USER_LOG(ERR, \"Peer closed\\n\");\n+\t\t\treturn -1;\n+\t\t} else if (ret > 0) {\n+\t\t\tif (id != msg->msg_id)\n+\t\t\t\tcontinue;\n+\t\t\telse\n+\t\t\t\tbreak;\n+\t\t}\n+\t\tusleep(REPLY_USEC);\n+\t\ttry_recv++;\n+\t}\n+\n+\tif (cmd != msg->cmd) {\n+\t\tVFIO_USER_LOG(ERR, \"Request and reply mismatch\\n\");\n+\t\tret = -1;\n+\t} else\n+\t\tret = 0;\n+\n+\tVFIO_USER_LOG(INFO, \"Recv reply %s\\n\", vfio_user_msg_str[cmd]);\n+\n+\treturn ret;\n+}\n+\n+int rte_vfio_user_attach_dev(const char *sock_addr)\n+{\n+\tstruct vfio_user_client *dev;\n+\tVFIO_USER_MSG msg;\n+\tuint32_t sz = VFIO_USER_MSG_HDR_SIZE + sizeof(struct vfio_user_version)\n+\t\t- VFIO_USER_MAX_VERSION_DATA;\n+\tstruct vfio_user_version *ver = &msg.payload.ver;\n+\tint ret;\n+\n+\tif (!sock_addr)\n+\t\treturn -EINVAL;\n+\n+\tdev = vfio_user_client_create_dev(sock_addr);\n+\tif (!dev) {\n+\t\tVFIO_USER_LOG(ERR, \"Failed to attach the device \"\n+\t\t\t\"with sock_addr %s\\n\", sock_addr);\n+\t\treturn -1;\n+\t}\n+\n+\tmemset(&msg, 0, sizeof(VFIO_USER_MSG));\n+\tvfio_user_client_fill_hdr(&msg, VFIO_USER_VERSION, sz);\n+\tver->major = VFIO_USER_VERSION_MAJOR;\n+\tver->minor = VFIO_USER_VERSION_MINOR;\n+\n+\tret = vfio_user_client_send_recv(dev->sock.sock_fd, &msg);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tif (msg.flags & VFIO_USER_ERROR) {\n+\t\tVFIO_USER_LOG(ERR, \"Failed to negotiate version: %s\\n\",\n+\t\t\t\tmsg.err ? strerror(msg.err) : \"Unknown error\");\n+\t\treturn msg.err ? -(int)msg.err : -1;\n+\t}\n+\n+\tif (vfio_user_check_msg_fdnum(&msg, 0) != 0)\n+\t\treturn -1;\n+\n+\treturn dev->sock.dev_id;\n+}\n+\n+int rte_vfio_user_detach_dev(int dev_id)\n+{\n+\tint ret;\n+\n+\tif (dev_id < 0)\n+\t\treturn -EINVAL;\n+\n+\tret = vfio_user_client_destroy_dev(dev_id);\n+\tif (ret)\n+\t\tVFIO_USER_LOG(ERR, \"Failed to detach the device (ID:%d)\\n\",\n+\t\t\tdev_id);\n+\n+\treturn ret;\n+}\ndiff --git a/lib/librte_vfio_user/vfio_user_client.h b/lib/librte_vfio_user/vfio_user_client.h\nnew file mode 100644\nindex 0000000000..d489e62037\n--- /dev/null\n+++ b/lib/librte_vfio_user/vfio_user_client.h\n@@ -0,0 +1,25 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2020 Intel Corporation\n+ */\n+\n+#ifndef _VFIO_USER_CLIENT_H\n+#define _VFIO_USER_CLIENT_H\n+\n+#include <stdint.h>\n+\n+#include \"vfio_user_base.h\"\n+\n+#define MAX_VFIO_USER_CLIENT 1024\n+\n+struct vfio_user_client {\n+\tstruct vfio_user_socket sock;\n+\tuint8_t rsvd[16];\t/* Reserved for future use */\n+};\n+\n+struct vfio_user_client_devs {\n+\tstruct vfio_user_client *cl[MAX_VFIO_USER_CLIENT];\n+\tuint32_t cl_num;\n+\tpthread_mutex_t mutex;\n+};\n+\n+#endif\n", "prefixes": [ "6/9" ] }{ "id": 85395, "url": "