get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/54965/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 54965,
    "url": "http://patches.dpdk.org/api/patches/54965/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1560957293-17294-12-git-send-email-ndragazis@arrikto.com/",
    "project": {
        "id": 1,
        "url": "http://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": "<1560957293-17294-12-git-send-email-ndragazis@arrikto.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1560957293-17294-12-git-send-email-ndragazis@arrikto.com",
    "date": "2019-06-19T15:14:36",
    "name": "[11/28] vhost: extract socket I/O into transport",
    "commit_ref": null,
    "pull_url": null,
    "state": "rfc",
    "archived": true,
    "hash": "1bba4f30c16fbe24459fe88af9e79e7e7adf48f3",
    "submitter": {
        "id": 1339,
        "url": "http://patches.dpdk.org/api/people/1339/?format=api",
        "name": "Nikos Dragazis",
        "email": "ndragazis@arrikto.com"
    },
    "delegate": {
        "id": 2642,
        "url": "http://patches.dpdk.org/api/users/2642/?format=api",
        "username": "mcoquelin",
        "first_name": "Maxime",
        "last_name": "Coquelin",
        "email": "maxime.coquelin@redhat.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1560957293-17294-12-git-send-email-ndragazis@arrikto.com/mbox/",
    "series": [
        {
            "id": 5082,
            "url": "http://patches.dpdk.org/api/series/5082/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=5082",
            "date": "2019-06-19T15:14:25",
            "name": "vhost: add virtio-vhost-user transport",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/5082/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/54965/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/54965/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 233671C3E8;\n\tWed, 19 Jun 2019 17:16:10 +0200 (CEST)",
            "from mx0.arrikto.com (mx0.arrikto.com [212.71.252.59])\n\tby dpdk.org (Postfix) with ESMTP id A5DA91C389\n\tfor <dev@dpdk.org>; Wed, 19 Jun 2019 17:15:40 +0200 (CEST)",
            "from troi.prod.arr (mail.arr [10.99.0.5])\n\tby mx0.arrikto.com (Postfix) with ESMTP id 65685182010;\n\tWed, 19 Jun 2019 18:15:40 +0300 (EEST)",
            "from localhost.localdomain (unknown [10.89.50.133])\n\tby troi.prod.arr (Postfix) with ESMTPSA id A57D632C;\n\tWed, 19 Jun 2019 18:15:39 +0300 (EEST)"
        ],
        "From": "Nikos Dragazis <ndragazis@arrikto.com>",
        "To": "dev@dpdk.org",
        "Cc": "Maxime Coquelin <maxime.coquelin@redhat.com>,\n\tTiwei Bie <tiwei.bie@intel.com>, Zhihong Wang <zhihong.wang@intel.com>,\n\tStefan Hajnoczi <stefanha@redhat.com>, Wei Wang <wei.w.wang@intel.com>,\n\tStojaczyk Dariusz <dariusz.stojaczyk@intel.com>,\n\tVangelis Koukis <vkoukis@arrikto.com>",
        "Date": "Wed, 19 Jun 2019 18:14:36 +0300",
        "Message-Id": "<1560957293-17294-12-git-send-email-ndragazis@arrikto.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "<1560957293-17294-1-git-send-email-ndragazis@arrikto.com>",
        "References": "<1560957293-17294-1-git-send-email-ndragazis@arrikto.com>",
        "Subject": "[dpdk-dev] [PATCH 11/28] vhost: extract socket I/O into transport",
        "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\t<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\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "The core vhost-user protocol code should not do socket I/O, because the\ndetails are transport-specific.  Move code to send and receive\nvhost-user messages into trans_af_unix.c.\n\nThe connection fd is a transport-specific feature. Therefore, it should\nand eventually will be removed from the core vhost-user code. That is,\nit will be removed from the vhost_user_msg_handler() and the message\nhandlers. We keep it for now, because vhost_user_set_mem_table() needs\nit. In a later commit, we will refactor the map/unmap functionality and\nafter that we will be able to remove the connection fds from the core\nvhost-user code.\n\nSigned-off-by: Nikos Dragazis <ndragazis@arrikto.com>\nSigned-off-by: Stefan Hajnoczi <stefanha@redhat.com>\n---\n lib/librte_vhost/trans_af_unix.c | 70 +++++++++++++++++++++++++++++++++---\n lib/librte_vhost/vhost.h         | 26 ++++++++++++++\n lib/librte_vhost/vhost_user.c    | 78 ++++++++--------------------------------\n lib/librte_vhost/vhost_user.h    |  7 +---\n 4 files changed, 108 insertions(+), 73 deletions(-)",
    "diff": "diff --git a/lib/librte_vhost/trans_af_unix.c b/lib/librte_vhost/trans_af_unix.c\nindex 7e119b4..c0ba8df 100644\n--- a/lib/librte_vhost/trans_af_unix.c\n+++ b/lib/librte_vhost/trans_af_unix.c\n@@ -50,7 +50,7 @@ static void vhost_user_read_cb(int connfd, void *dat, int *remove);\n  * return bytes# of read on success or negative val on failure. Update fdnum\n  * with number of fds read.\n  */\n-int\n+static int\n read_fd_message(int sockfd, char *buf, int buflen, int *fds, int max_fds,\n \t\tint *fd_num)\n {\n@@ -101,8 +101,8 @@ read_fd_message(int sockfd, char *buf, int buflen, int *fds, int max_fds,\n \treturn ret;\n }\n \n-int\n-send_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num)\n+static int\n+send_fd_message(int sockfd, void *buf, int buflen, int *fds, int fd_num)\n {\n \tstruct iovec iov;\n \tstruct msghdr msgh;\n@@ -148,6 +148,23 @@ send_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num)\n \treturn ret;\n }\n \n+static int\n+af_unix_send_reply(struct virtio_net *dev, struct VhostUserMsg *msg)\n+{\n+\tstruct vhost_user_connection *conn =\n+\t\tcontainer_of(dev, struct vhost_user_connection, device);\n+\n+\treturn send_fd_message(conn->connfd, msg,\n+\t\t\t       VHOST_USER_HDR_SIZE + msg->size, msg->fds, msg->fd_num);\n+}\n+\n+static int\n+af_unix_send_slave_req(struct virtio_net *dev, struct VhostUserMsg *msg)\n+{\n+\treturn send_fd_message(dev->slave_req_fd, msg,\n+\t\t\t       VHOST_USER_HDR_SIZE + msg->size, msg->fds, msg->fd_num);\n+}\n+\n static void\n vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket)\n {\n@@ -231,6 +248,36 @@ vhost_user_server_new_connection(int fd, void *dat, int *remove __rte_unused)\n \tvhost_user_add_connection(fd, vsocket);\n }\n \n+/* return bytes# of read on success or negative val on failure. */\n+int\n+read_vhost_message(int sockfd, struct VhostUserMsg *msg)\n+{\n+\tint ret;\n+\n+\tret = read_fd_message(sockfd, (char *)msg, VHOST_USER_HDR_SIZE,\n+\t\tmsg->fds, VHOST_MEMORY_MAX_NREGIONS, &msg->fd_num);\n+\tif (ret <= 0)\n+\t\treturn ret;\n+\n+\tif (msg->size) {\n+\t\tif (msg->size > sizeof(msg->payload)) {\n+\t\t\tRTE_LOG(ERR, VHOST_CONFIG,\n+\t\t\t\t\"invalid msg size: %d\\n\", msg->size);\n+\t\t\treturn -1;\n+\t\t}\n+\t\tret = read(sockfd, &msg->payload, msg->size);\n+\t\tif (ret <= 0)\n+\t\t\treturn ret;\n+\t\tif (ret != (int)msg->size) {\n+\t\t\tRTE_LOG(ERR, VHOST_CONFIG,\n+\t\t\t\t\"read control message failed\\n\");\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\treturn ret;\n+}\n+\n static void\n vhost_user_read_cb(int connfd, void *dat, int *remove)\n {\n@@ -238,10 +285,23 @@ vhost_user_read_cb(int connfd, void *dat, int *remove)\n \tstruct vhost_user_socket *vsocket = conn->vsocket;\n \tstruct af_unix_socket *af_vsocket =\n \t\tcontainer_of(vsocket, struct af_unix_socket, socket);\n+\tstruct VhostUserMsg msg;\n \tint ret;\n \n-\tret = vhost_user_msg_handler(conn->device.vid, connfd);\n+\tret = read_vhost_message(connfd, &msg);\n+\tif (ret <= 0) {\n+\t\tif (ret < 0)\n+\t\t\tRTE_LOG(ERR, VHOST_CONFIG,\n+\t\t\t\t\"vhost read message failed\\n\");\n+\t\telse if (ret == 0)\n+\t\t\tRTE_LOG(INFO, VHOST_CONFIG,\n+\t\t\t\t\"vhost peer closed\\n\");\n+\t\tgoto err;\n+\t}\n+\n+\tret = vhost_user_msg_handler(conn->device.vid, connfd, &msg);\n \tif (ret < 0) {\n+err:\n \t\tclose(connfd);\n \t\t*remove = 1;\n \n@@ -638,4 +698,6 @@ const struct vhost_transport_ops af_unix_trans_ops = {\n \t.socket_cleanup = af_unix_socket_cleanup,\n \t.socket_start = af_unix_socket_start,\n \t.vring_call = af_unix_vring_call,\n+\t.send_reply = af_unix_send_reply,\n+\t.send_slave_req = af_unix_send_slave_req,\n };\ndiff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h\nindex b9e4df1..b20773c 100644\n--- a/lib/librte_vhost/vhost.h\n+++ b/lib/librte_vhost/vhost.h\n@@ -290,6 +290,7 @@ struct guest_page {\n \n struct virtio_net;\n struct vhost_user_socket;\n+struct VhostUserMsg;\n \n /**\n  * A structure containing function pointers for transport-specific operations.\n@@ -351,6 +352,31 @@ struct vhost_transport_ops {\n \t *  0 on success, -1 on failure\n \t */\n \tint (*vring_call)(struct virtio_net *dev, struct vhost_virtqueue *vq);\n+\n+\t/**\n+\t * Send a reply to the master.\n+\t *\n+\t * @param dev\n+\t *  vhost device\n+\t * @param reply\n+\t *  reply message\n+\t * @return\n+\t *  0 on success, -1 on failure\n+\t */\n+\tint (*send_reply)(struct virtio_net *dev, struct VhostUserMsg *reply);\n+\n+\t/**\n+\t * Send a slave request to the master.\n+\t *\n+\t * @param dev\n+\t *  vhost device\n+\t * @param req\n+\t *  request message\n+\t * @return\n+\t *  0 on success, -1 on failure\n+\t */\n+\tint (*send_slave_req)(struct virtio_net *dev,\n+\t\t\t      struct VhostUserMsg *req);\n };\n \n /** The traditional AF_UNIX vhost-user protocol transport. */\ndiff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c\nindex c9e29ec..5c12435 100644\n--- a/lib/librte_vhost/vhost_user.c\n+++ b/lib/librte_vhost/vhost_user.c\n@@ -80,8 +80,8 @@ static const char *vhost_message_str[VHOST_USER_MAX] = {\n \t[VHOST_USER_POSTCOPY_END]  = \"VHOST_USER_POSTCOPY_END\",\n };\n \n-static int send_vhost_reply(int sockfd, struct VhostUserMsg *msg);\n-static int read_vhost_message(int sockfd, struct VhostUserMsg *msg);\n+static int send_vhost_reply(struct virtio_net *dev, struct VhostUserMsg *msg);\n+int read_vhost_message(int sockfd, struct VhostUserMsg *msg);\n \n static uint64_t\n get_blk_size(int fd)\n@@ -1042,7 +1042,7 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg,\n \tif (dev->postcopy_listening) {\n \t\t/* Send the addresses back to qemu */\n \t\tmsg->fd_num = 0;\n-\t\tsend_vhost_reply(main_fd, msg);\n+\t\tsend_vhost_reply(dev, msg);\n \n \t\t/* Wait for qemu to acknolwedge it's got the addresses\n \t\t * we've got to wait before we're allowed to generate faults.\n@@ -1764,49 +1764,8 @@ static vhost_message_handler_t vhost_message_handlers[VHOST_USER_MAX] = {\n \t[VHOST_USER_POSTCOPY_END] = vhost_user_postcopy_end,\n };\n \n-\n-/* return bytes# of read on success or negative val on failure. */\n static int\n-read_vhost_message(int sockfd, struct VhostUserMsg *msg)\n-{\n-\tint ret;\n-\n-\tret = read_fd_message(sockfd, (char *)msg, VHOST_USER_HDR_SIZE,\n-\t\tmsg->fds, VHOST_MEMORY_MAX_NREGIONS, &msg->fd_num);\n-\tif (ret <= 0)\n-\t\treturn ret;\n-\n-\tif (msg->size) {\n-\t\tif (msg->size > sizeof(msg->payload)) {\n-\t\t\tRTE_LOG(ERR, VHOST_CONFIG,\n-\t\t\t\t\"invalid msg size: %d\\n\", msg->size);\n-\t\t\treturn -1;\n-\t\t}\n-\t\tret = read(sockfd, &msg->payload, msg->size);\n-\t\tif (ret <= 0)\n-\t\t\treturn ret;\n-\t\tif (ret != (int)msg->size) {\n-\t\t\tRTE_LOG(ERR, VHOST_CONFIG,\n-\t\t\t\t\"read control message failed\\n\");\n-\t\t\treturn -1;\n-\t\t}\n-\t}\n-\n-\treturn ret;\n-}\n-\n-static int\n-send_vhost_message(int sockfd, struct VhostUserMsg *msg)\n-{\n-\tif (!msg)\n-\t\treturn 0;\n-\n-\treturn send_fd_message(sockfd, (char *)msg,\n-\t\tVHOST_USER_HDR_SIZE + msg->size, msg->fds, msg->fd_num);\n-}\n-\n-static int\n-send_vhost_reply(int sockfd, struct VhostUserMsg *msg)\n+send_vhost_reply(struct virtio_net *dev, struct VhostUserMsg *msg)\n {\n \tif (!msg)\n \t\treturn 0;\n@@ -1816,7 +1775,7 @@ send_vhost_reply(int sockfd, struct VhostUserMsg *msg)\n \tmsg->flags |= VHOST_USER_VERSION;\n \tmsg->flags |= VHOST_USER_REPLY_MASK;\n \n-\treturn send_vhost_message(sockfd, msg);\n+\treturn dev->trans_ops->send_reply(dev, msg);\n }\n \n static int\n@@ -1827,7 +1786,7 @@ send_vhost_slave_message(struct virtio_net *dev, struct VhostUserMsg *msg)\n \tif (msg->flags & VHOST_USER_NEED_REPLY)\n \t\trte_spinlock_lock(&dev->slave_req_lock);\n \n-\tret = send_vhost_message(dev->slave_req_fd, msg);\n+\tret = dev->trans_ops->send_slave_req(dev, msg);\n \tif (ret < 0 && (msg->flags & VHOST_USER_NEED_REPLY))\n \t\trte_spinlock_unlock(&dev->slave_req_lock);\n \n@@ -1908,10 +1867,10 @@ vhost_user_unlock_all_queue_pairs(struct virtio_net *dev)\n }\n \n int\n-vhost_user_msg_handler(int vid, int fd)\n+vhost_user_msg_handler(int vid, int fd, const struct VhostUserMsg *msg_)\n {\n+\tstruct VhostUserMsg msg = *msg_; /* copy so we can build the reply */\n \tstruct virtio_net *dev;\n-\tstruct VhostUserMsg msg;\n \tstruct rte_vdpa_device *vdpa_dev;\n \tint did = -1;\n \tint ret;\n@@ -1933,15 +1892,8 @@ vhost_user_msg_handler(int vid, int fd)\n \t\t}\n \t}\n \n-\tret = read_vhost_message(fd, &msg);\n-\tif (ret <= 0) {\n-\t\tif (ret < 0)\n-\t\t\tRTE_LOG(ERR, VHOST_CONFIG,\n-\t\t\t\t\"vhost read message failed\\n\");\n-\t\telse\n-\t\t\tRTE_LOG(INFO, VHOST_CONFIG,\n-\t\t\t\t\"vhost peer closed\\n\");\n-\n+\tif (msg.request.master >= VHOST_USER_MAX) {\n+\t\tRTE_LOG(ERR, VHOST_CONFIG, \"vhost read incorrect message\\n\");\n \t\treturn -1;\n \t}\n \n@@ -2004,7 +1956,7 @@ vhost_user_msg_handler(int vid, int fd)\n \t\t\t\t(void *)&msg);\n \t\tswitch (ret) {\n \t\tcase RTE_VHOST_MSG_RESULT_REPLY:\n-\t\t\tsend_vhost_reply(fd, &msg);\n+\t\t\tsend_vhost_reply(dev, &msg);\n \t\t\t/* Fall-through */\n \t\tcase RTE_VHOST_MSG_RESULT_ERR:\n \t\tcase RTE_VHOST_MSG_RESULT_OK:\n@@ -2038,7 +1990,7 @@ vhost_user_msg_handler(int vid, int fd)\n \t\t\tRTE_LOG(DEBUG, VHOST_CONFIG,\n \t\t\t\t\"Processing %s succeeded and needs reply.\\n\",\n \t\t\t\tvhost_message_str[request]);\n-\t\t\tsend_vhost_reply(fd, &msg);\n+\t\t\tsend_vhost_reply(dev, &msg);\n \t\t\thandled = true;\n \t\t\tbreak;\n \t\tdefault:\n@@ -2053,7 +2005,7 @@ vhost_user_msg_handler(int vid, int fd)\n \t\t\t\t(void *)&msg);\n \t\tswitch (ret) {\n \t\tcase RTE_VHOST_MSG_RESULT_REPLY:\n-\t\t\tsend_vhost_reply(fd, &msg);\n+\t\t\tsend_vhost_reply(dev, &msg);\n \t\t\t/* Fall-through */\n \t\tcase RTE_VHOST_MSG_RESULT_ERR:\n \t\tcase RTE_VHOST_MSG_RESULT_OK:\n@@ -2083,7 +2035,7 @@ vhost_user_msg_handler(int vid, int fd)\n \t\tmsg.payload.u64 = ret == RTE_VHOST_MSG_RESULT_ERR;\n \t\tmsg.size = sizeof(msg.payload.u64);\n \t\tmsg.fd_num = 0;\n-\t\tsend_vhost_reply(fd, &msg);\n+\t\tsend_vhost_reply(dev, &msg);\n \t} else if (ret == RTE_VHOST_MSG_RESULT_ERR) {\n \t\tRTE_LOG(ERR, VHOST_CONFIG,\n \t\t\t\"vhost message handling failed.\\n\");\n@@ -2161,7 +2113,7 @@ vhost_user_iotlb_miss(struct virtio_net *dev, uint64_t iova, uint8_t perm)\n \t\t},\n \t};\n \n-\tret = send_vhost_message(dev->slave_req_fd, &msg);\n+\tret = send_vhost_slave_req(dev, &msg);\n \tif (ret < 0) {\n \t\tRTE_LOG(ERR, VHOST_CONFIG,\n \t\t\t\t\"Failed to send IOTLB miss message (%d)\\n\",\ndiff --git a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h\nindex 2a650fe..0169bd2 100644\n--- a/lib/librte_vhost/vhost_user.h\n+++ b/lib/librte_vhost/vhost_user.h\n@@ -146,12 +146,7 @@ typedef struct VhostUserMsg {\n \n \n /* vhost_user.c */\n-int vhost_user_msg_handler(int vid, int fd);\n+int vhost_user_msg_handler(int vid, int fd, const struct VhostUserMsg *msg);\n int vhost_user_iotlb_miss(struct virtio_net *dev, uint64_t iova, uint8_t perm);\n \n-/* socket.c */\n-int read_fd_message(int sockfd, char *buf, int buflen, int *fds, int max_fds,\n-\t\tint *fd_num);\n-int send_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num);\n-\n #endif\n",
    "prefixes": [
        "11/28"
    ]
}