get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 40803,
    "url": "https://patches.dpdk.org/api/patches/40803/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20180608032224.22049-2-tiwei.bie@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": "<20180608032224.22049-2-tiwei.bie@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20180608032224.22049-2-tiwei.bie@intel.com",
    "date": "2018-06-08T03:22:23",
    "name": "[dpdk-dev,v3,1/2] vhost: support host notifier",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "42dac3895ed229ec416774e080a7070b5c68c6b7",
    "submitter": {
        "id": 617,
        "url": "https://patches.dpdk.org/api/people/617/?format=api",
        "name": "Tiwei Bie",
        "email": "tiwei.bie@intel.com"
    },
    "delegate": {
        "id": 2642,
        "url": "https://patches.dpdk.org/api/users/2642/?format=api",
        "username": "mcoquelin",
        "first_name": "Maxime",
        "last_name": "Coquelin",
        "email": "maxime.coquelin@redhat.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20180608032224.22049-2-tiwei.bie@intel.com/mbox/",
    "series": [
        {
            "id": 40,
            "url": "https://patches.dpdk.org/api/series/40/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=40",
            "date": "2018-06-08T03:22:22",
            "name": "vhost: support host notifier",
            "version": 3,
            "mbox": "https://patches.dpdk.org/series/40/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/40803/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/40803/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 921EC1B28E;\n\tFri,  8 Jun 2018 05:22:22 +0200 (CEST)",
            "from mga17.intel.com (mga17.intel.com [192.55.52.151])\n\tby dpdk.org (Postfix) with ESMTP id 988D1D49E\n\tfor <dev@dpdk.org>; Fri,  8 Jun 2018 05:22:16 +0200 (CEST)",
            "from fmsmga008.fm.intel.com ([10.253.24.58])\n\tby fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t07 Jun 2018 20:22:14 -0700",
            "from debian.sh.intel.com ([10.67.104.203])\n\tby fmsmga008.fm.intel.com with ESMTP; 07 Jun 2018 20:22:14 -0700"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.49,489,1520924400\"; d=\"scan'208\";a=\"46168861\"",
        "From": "Tiwei Bie <tiwei.bie@intel.com>",
        "To": "maxime.coquelin@redhat.com,\n\tdev@dpdk.org",
        "Date": "Fri,  8 Jun 2018 11:22:23 +0800",
        "Message-Id": "<20180608032224.22049-2-tiwei.bie@intel.com>",
        "X-Mailer": "git-send-email 2.17.0",
        "In-Reply-To": "<20180608032224.22049-1-tiwei.bie@intel.com>",
        "References": "<20180608032224.22049-1-tiwei.bie@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v3 1/2] vhost: support host notifier",
        "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://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "When a vDPA device is attached, vhost user will try to\nregister host notifiers to QEMU to allow notifications\nto be delivered between the driver in the guest and the\nvDPA device in the host directly.\n\nSigned-off-by: Tiwei Bie <tiwei.bie@intel.com>\n---\n lib/librte_vhost/rte_vhost.h  |   8 ++\n lib/librte_vhost/vhost.c      |   3 +\n lib/librte_vhost/vhost.h      |   1 +\n lib/librte_vhost/vhost_user.c | 146 ++++++++++++++++++++++++++++++++++\n lib/librte_vhost/vhost_user.h |  13 ++-\n 5 files changed, 170 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h\nindex 7f0cb9bc8..b02673d4a 100644\n--- a/lib/librte_vhost/rte_vhost.h\n+++ b/lib/librte_vhost/rte_vhost.h\n@@ -58,6 +58,14 @@ extern \"C\" {\n #define VHOST_USER_PROTOCOL_F_CRYPTO_SESSION 7\n #endif\n \n+#ifndef VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD\n+#define VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD 10\n+#endif\n+\n+#ifndef VHOST_USER_PROTOCOL_F_HOST_NOTIFIER\n+#define VHOST_USER_PROTOCOL_F_HOST_NOTIFIER 11\n+#endif\n+\n /** Indicate whether protocol features negotiation is supported. */\n #ifndef VHOST_USER_F_PROTOCOL_FEATURES\n #define VHOST_USER_F_PROTOCOL_FEATURES\t30\ndiff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c\nindex afded4952..6ca5beb13 100644\n--- a/lib/librte_vhost/vhost.c\n+++ b/lib/librte_vhost/vhost.c\n@@ -291,6 +291,7 @@ vhost_new_device(void)\n \tdev->flags = VIRTIO_DEV_BUILTIN_VIRTIO_NET;\n \tdev->slave_req_fd = -1;\n \tdev->vdpa_dev_id = -1;\n+\trte_spinlock_init(&dev->slave_req_lock);\n \n \treturn i;\n }\n@@ -346,6 +347,8 @@ vhost_detach_vdpa_device(int vid)\n \tif (dev == NULL)\n \t\treturn;\n \n+\tvhost_user_host_notifier_ctrl(vid, false);\n+\n \tdev->vdpa_dev_id = -1;\n }\n \ndiff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h\nindex 58c425a5c..b10ac124b 100644\n--- a/lib/librte_vhost/vhost.h\n+++ b/lib/librte_vhost/vhost.h\n@@ -301,6 +301,7 @@ struct virtio_net {\n \tstruct guest_page       *guest_pages;\n \n \tint\t\t\tslave_req_fd;\n+\trte_spinlock_t\t\tslave_req_lock;\n \n \t/*\n \t * Device id to identify a specific backend device.\ndiff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c\nindex 947290fc3..a28fc3495 100644\n--- a/lib/librte_vhost/vhost_user.c\n+++ b/lib/librte_vhost/vhost_user.c\n@@ -1384,6 +1384,22 @@ send_vhost_reply(int sockfd, struct VhostUserMsg *msg)\n \treturn send_vhost_message(sockfd, msg, NULL, 0);\n }\n \n+static int\n+send_vhost_slave_message(struct virtio_net *dev, struct VhostUserMsg *msg,\n+\t\t\t int *fds, int fd_num)\n+{\n+\tint ret;\n+\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, fds, fd_num);\n+\tif (ret < 0 && (msg->flags & VHOST_USER_NEED_REPLY))\n+\t\trte_spinlock_unlock(&dev->slave_req_lock);\n+\n+\treturn ret;\n+}\n+\n /*\n  * Allocate a queue pair if it hasn't been allocated yet\n  */\n@@ -1705,11 +1721,45 @@ vhost_user_msg_handler(int vid, int fd)\n \t\tif (vdpa_dev->ops->dev_conf)\n \t\t\tvdpa_dev->ops->dev_conf(dev->vid);\n \t\tdev->flags |= VIRTIO_DEV_VDPA_CONFIGURED;\n+\t\tif (vhost_user_host_notifier_ctrl(dev->vid, true) != 0) {\n+\t\t\tRTE_LOG(INFO, VHOST_CONFIG,\n+\t\t\t\t\"(%d) software relay is used for vDPA, performance may be low.\\n\",\n+\t\t\t\tdev->vid);\n+\t\t}\n \t}\n \n \treturn 0;\n }\n \n+static int process_slave_message_reply(struct virtio_net *dev,\n+\t\t\t\t       const VhostUserMsg *msg)\n+{\n+\tVhostUserMsg msg_reply;\n+\tint ret;\n+\n+\tif ((msg->flags & VHOST_USER_NEED_REPLY) == 0)\n+\t\treturn 0;\n+\n+\tif (read_vhost_message(dev->slave_req_fd, &msg_reply) < 0) {\n+\t\tret = -1;\n+\t\tgoto out;\n+\t}\n+\n+\tif (msg_reply.request.slave != msg->request.slave) {\n+\t\tRTE_LOG(ERR, VHOST_CONFIG,\n+\t\t\t\"Received unexpected msg type (%u), expected %u\\n\",\n+\t\t\tmsg_reply.request.slave, msg->request.slave);\n+\t\tret = -1;\n+\t\tgoto out;\n+\t}\n+\n+\tret = msg_reply.payload.u64 ? -1 : 0;\n+\n+out:\n+\trte_spinlock_unlock(&dev->slave_req_lock);\n+\treturn ret;\n+}\n+\n int\n vhost_user_iotlb_miss(struct virtio_net *dev, uint64_t iova, uint8_t perm)\n {\n@@ -1735,3 +1785,99 @@ vhost_user_iotlb_miss(struct virtio_net *dev, uint64_t iova, uint8_t perm)\n \n \treturn 0;\n }\n+\n+static int vhost_user_slave_set_vring_host_notifier(struct virtio_net *dev,\n+\t\t\t\t\t\t    int index, int fd,\n+\t\t\t\t\t\t    uint64_t offset,\n+\t\t\t\t\t\t    uint64_t size)\n+{\n+\tint *fdp = NULL;\n+\tsize_t fd_num = 0;\n+\tint ret;\n+\tstruct VhostUserMsg msg = {\n+\t\t.request.slave = VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG,\n+\t\t.flags = VHOST_USER_VERSION | VHOST_USER_NEED_REPLY,\n+\t\t.size = sizeof(msg.payload.area),\n+\t\t.payload.area = {\n+\t\t\t.u64 = index & VHOST_USER_VRING_IDX_MASK,\n+\t\t\t.size = size,\n+\t\t\t.offset = offset,\n+\t\t},\n+\t};\n+\n+\tif (fd < 0)\n+\t\tmsg.payload.area.u64 |= VHOST_USER_VRING_NOFD_MASK;\n+\telse {\n+\t\tfdp = &fd;\n+\t\tfd_num = 1;\n+\t}\n+\n+\tret = send_vhost_slave_message(dev, &msg, fdp, fd_num);\n+\tif (ret < 0) {\n+\t\tRTE_LOG(ERR, VHOST_CONFIG,\n+\t\t\t\"Failed to set host notifier (%d)\\n\", ret);\n+\t\treturn ret;\n+\t}\n+\n+\treturn process_slave_message_reply(dev, &msg);\n+}\n+\n+int vhost_user_host_notifier_ctrl(int vid, bool enable)\n+{\n+\tstruct virtio_net *dev;\n+\tstruct rte_vdpa_device *vdpa_dev;\n+\tint vfio_device_fd, did, ret = 0;\n+\tuint64_t offset, size;\n+\tunsigned int i;\n+\n+\tdev = get_device(vid);\n+\tif (!dev)\n+\t\treturn -ENODEV;\n+\n+\tdid = dev->vdpa_dev_id;\n+\tif (did < 0)\n+\t\treturn -EINVAL;\n+\n+\tif (!(dev->features & (1ULL << VIRTIO_F_VERSION_1)) ||\n+\t    !(dev->features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)) ||\n+\t    !(dev->protocol_features &\n+\t\t\t(1ULL << VHOST_USER_PROTOCOL_F_SLAVE_REQ)) ||\n+\t    !(dev->protocol_features &\n+\t\t\t(1ULL << VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD)) ||\n+\t    !(dev->protocol_features &\n+\t\t\t(1ULL << VHOST_USER_PROTOCOL_F_HOST_NOTIFIER)))\n+\t\treturn -ENOTSUP;\n+\n+\tvdpa_dev = rte_vdpa_get_device(did);\n+\n+\tRTE_FUNC_PTR_OR_ERR_RET(vdpa_dev->ops->get_vfio_device_fd, -ENOTSUP);\n+\tRTE_FUNC_PTR_OR_ERR_RET(vdpa_dev->ops->get_notify_area, -ENOTSUP);\n+\n+\tvfio_device_fd = vdpa_dev->ops->get_vfio_device_fd(vid);\n+\tif (vfio_device_fd < 0)\n+\t\treturn -ENOTSUP;\n+\n+\tif (enable) {\n+\t\tfor (i = 0; i < dev->nr_vring; i++) {\n+\t\t\tif (vdpa_dev->ops->get_notify_area(vid, i, &offset,\n+\t\t\t\t\t&size) < 0) {\n+\t\t\t\tret = -ENOTSUP;\n+\t\t\t\tgoto disable;\n+\t\t\t}\n+\n+\t\t\tif (vhost_user_slave_set_vring_host_notifier(dev, i,\n+\t\t\t\t\tvfio_device_fd, offset, size) < 0) {\n+\t\t\t\tret = -EFAULT;\n+\t\t\t\tgoto disable;\n+\t\t\t}\n+\t\t}\n+\t} else {\n+disable:\n+\t\tfor (i = 0; i < dev->nr_vring; i++) {\n+\t\t\tvhost_user_slave_set_vring_host_notifier(dev, i, -1,\n+\t\t\t\t\t0, 0);\n+\t\t}\n+\t}\n+\n+\treturn ret;\n+}\ndiff --git a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h\nindex 1ad5cf467..42166adf2 100644\n--- a/lib/librte_vhost/vhost_user.h\n+++ b/lib/librte_vhost/vhost_user.h\n@@ -20,7 +20,9 @@\n \t\t\t\t\t (1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK) | \\\n \t\t\t\t\t (1ULL << VHOST_USER_PROTOCOL_F_NET_MTU) | \\\n \t\t\t\t\t (1ULL << VHOST_USER_PROTOCOL_F_SLAVE_REQ) | \\\n-\t\t\t\t\t (1ULL << VHOST_USER_PROTOCOL_F_CRYPTO_SESSION))\n+\t\t\t\t\t (1ULL << VHOST_USER_PROTOCOL_F_CRYPTO_SESSION) | \\\n+\t\t\t\t\t (1ULL << VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD) | \\\n+\t\t\t\t\t (1ULL << VHOST_USER_PROTOCOL_F_HOST_NOTIFIER))\n \n typedef enum VhostUserRequest {\n \tVHOST_USER_NONE = 0,\n@@ -54,6 +56,7 @@ typedef enum VhostUserRequest {\n typedef enum VhostUserSlaveRequest {\n \tVHOST_USER_SLAVE_NONE = 0,\n \tVHOST_USER_SLAVE_IOTLB_MSG = 1,\n+\tVHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG = 3,\n \tVHOST_USER_SLAVE_MAX\n } VhostUserSlaveRequest;\n \n@@ -99,6 +102,12 @@ typedef struct VhostUserCryptoSessionParam {\n \tuint8_t auth_key_buf[VHOST_USER_CRYPTO_MAX_HMAC_KEY_LENGTH];\n } VhostUserCryptoSessionParam;\n \n+typedef struct VhostUserVringArea {\n+\tuint64_t u64;\n+\tuint64_t size;\n+\tuint64_t offset;\n+} VhostUserVringArea;\n+\n typedef struct VhostUserMsg {\n \tunion {\n \t\tuint32_t master; /* a VhostUserRequest value */\n@@ -120,6 +129,7 @@ typedef struct VhostUserMsg {\n \t\tVhostUserLog    log;\n \t\tstruct vhost_iotlb_msg iotlb;\n \t\tVhostUserCryptoSessionParam crypto_session;\n+\t\tVhostUserVringArea area;\n \t} payload;\n \tint fds[VHOST_MEMORY_MAX_NREGIONS];\n } __attribute((packed)) VhostUserMsg;\n@@ -133,6 +143,7 @@ typedef struct VhostUserMsg {\n /* vhost_user.c */\n int vhost_user_msg_handler(int vid, int fd);\n int vhost_user_iotlb_miss(struct virtio_net *dev, uint64_t iova, uint8_t perm);\n+int vhost_user_host_notifier_ctrl(int vid, bool enable);\n \n /* socket.c */\n int read_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num);\n",
    "prefixes": [
        "dpdk-dev",
        "v3",
        "1/2"
    ]
}