get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 51346,
    "url": "http://patches.dpdk.org/api/patches/51346/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20190319105417.16890-3-maxime.coquelin@redhat.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": "<20190319105417.16890-3-maxime.coquelin@redhat.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20190319105417.16890-3-maxime.coquelin@redhat.com",
    "date": "2019-03-19T10:54:17",
    "name": "[v3,2/2] vhost: support requests only handled by external backend",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "fdef4f1bfc9c95788f5dbc3b8a8bbdc4c72f7f8a",
    "submitter": {
        "id": 512,
        "url": "http://patches.dpdk.org/api/people/512/?format=api",
        "name": "Maxime Coquelin",
        "email": "maxime.coquelin@redhat.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/20190319105417.16890-3-maxime.coquelin@redhat.com/mbox/",
    "series": [
        {
            "id": 3800,
            "url": "http://patches.dpdk.org/api/series/3800/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=3800",
            "date": "2019-03-19T10:54:15",
            "name": "vhost: Support external backend only vhost-user requests",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/3800/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/51346/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/51346/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 89BDC4C96;\n\tTue, 19 Mar 2019 11:54:30 +0100 (CET)",
            "from mx1.redhat.com (mx1.redhat.com [209.132.183.28])\n\tby dpdk.org (Postfix) with ESMTP id C0B4E4C93\n\tfor <dev@dpdk.org>; Tue, 19 Mar 2019 11:54:28 +0100 (CET)",
            "from smtp.corp.redhat.com\n\t(int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby mx1.redhat.com (Postfix) with ESMTPS id 29B2087638;\n\tTue, 19 Mar 2019 10:54:28 +0000 (UTC)",
            "from localhost.localdomain (ovpn-112-48.ams2.redhat.com\n\t[10.36.112.48])\n\tby smtp.corp.redhat.com (Postfix) with ESMTP id 7287B6090C;\n\tTue, 19 Mar 2019 10:54:26 +0000 (UTC)"
        ],
        "From": "Maxime Coquelin <maxime.coquelin@redhat.com>",
        "To": "dev@dpdk.org, i.maximets@samsung.com, changpeng.liu@intel.com,\n\ttiwei.bie@intel.com, dariusz.stojaczyk@intel.com",
        "Cc": "Maxime Coquelin <maxime.coquelin@redhat.com>",
        "Date": "Tue, 19 Mar 2019 11:54:17 +0100",
        "Message-Id": "<20190319105417.16890-3-maxime.coquelin@redhat.com>",
        "In-Reply-To": "<20190319105417.16890-1-maxime.coquelin@redhat.com>",
        "References": "<20190319105417.16890-1-maxime.coquelin@redhat.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-Scanned-By": "MIMEDefang 2.79 on 10.5.11.13",
        "X-Greylist": "Sender IP whitelisted, not delayed by milter-greylist-4.5.16\n\t(mx1.redhat.com [10.5.110.26]); Tue, 19 Mar 2019 10:54:28 +0000 (UTC)",
        "Subject": "[dpdk-dev] [PATCH v3 2/2] vhost: support requests only handled by\n\texternal backend",
        "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": "External backends may have specific requests to handle, and so\nwe don't want the vhost-user lib to handle these requests as\nerrors.\n\nThis patch also changes the experimental API by introducing\nRTE_VHOST_MSG_RESULT_NOT_HANDLED so that vhost-user lib\ncan report an error if a message is handled neither by\nthe vhost-user library nor by the external backend.\n\nThe logic changes a bit so that if the callback returns\nwith ERR, OK or REPLY, it is considered the message\nis handled by the external backend so it won't be\nhandled by the vhost-user library.\nIt is still possible for an external backend to listen\nto requests that have to be handled by the vhost-user\nlibrary like SET_MEM_TABLE, but the callback have to\nreturn NOT_HANDLED in that case.\n\nVhost-crypto backend is ialso adapted to this API change.\n\nSuggested-by: Ilya Maximets <i.maximets@samsung.com>\nSigned-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>\nTested-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>\n---\n lib/librte_vhost/rte_vhost.h    | 39 ++++++----------\n lib/librte_vhost/vhost_crypto.c | 10 +++-\n lib/librte_vhost/vhost_user.c   | 82 +++++++++++++++++++++------------\n 3 files changed, 73 insertions(+), 58 deletions(-)",
    "diff": "diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h\nindex c9c392975..d2c0c93f4 100644\n--- a/lib/librte_vhost/rte_vhost.h\n+++ b/lib/librte_vhost/rte_vhost.h\n@@ -121,47 +121,34 @@ enum rte_vhost_msg_result {\n \tRTE_VHOST_MSG_RESULT_OK =  0,\n \t/* Message handling successful and reply prepared */\n \tRTE_VHOST_MSG_RESULT_REPLY =  1,\n+\t/* Message not handled */\n+\tRTE_VHOST_MSG_RESULT_NOT_HANDLED,\n };\n \n /**\n- * Function prototype for the vhost backend to handler specific vhost user\n- * messages prior to the master message handling\n+ * Function prototype for the vhost backend to handle specific vhost user\n+ * messages.\n  *\n  * @param vid\n  *  vhost device id\n  * @param msg\n  *  Message pointer.\n- * @param skip_master\n- *  If the handler requires skipping the master message handling, this variable\n- *  shall be written 1, otherwise 0.\n  * @return\n- *  VH_RESULT_OK on success, VH_RESULT_REPLY on success with reply,\n- *  VH_RESULT_ERR on failure\n+ *  RTE_VHOST_MSG_RESULT_OK on success,\n+ *  RTE_VHOST_MSG_RESULT_REPLY on success with reply,\n+ *  RTE_VHOST_MSG_RESULT_ERR on failure,\n+ *  RTE_VHOST_MSG_RESULT_NOT_HANDLED if message was not handled.\n  */\n-typedef enum rte_vhost_msg_result (*rte_vhost_msg_pre_handle)(int vid,\n-\t\tvoid *msg, uint32_t *skip_master);\n-\n-/**\n- * Function prototype for the vhost backend to handler specific vhost user\n- * messages after the master message handling is done\n- *\n- * @param vid\n- *  vhost device id\n- * @param msg\n- *  Message pointer.\n- * @return\n- *  VH_RESULT_OK on success, VH_RESULT_REPLY on success with reply,\n- *  VH_RESULT_ERR on failure\n- */\n-typedef enum rte_vhost_msg_result (*rte_vhost_msg_post_handle)(int vid,\n-\t\tvoid *msg);\n+typedef enum rte_vhost_msg_result (*rte_vhost_msg_handle)(int vid, void *msg);\n \n /**\n  * Optional vhost user message handlers.\n  */\n struct rte_vhost_user_extern_ops {\n-\trte_vhost_msg_pre_handle pre_msg_handle;\n-\trte_vhost_msg_post_handle post_msg_handle;\n+\t/* Called prior to the master message handling. */\n+\trte_vhost_msg_handle pre_msg_handle;\n+\t/* Called after the master message handling. */\n+\trte_vhost_msg_handle post_msg_handle;\n };\n \n /**\ndiff --git a/lib/librte_vhost/vhost_crypto.c b/lib/librte_vhost/vhost_crypto.c\nindex 0f437c4a1..9b4b850e8 100644\n--- a/lib/librte_vhost/vhost_crypto.c\n+++ b/lib/librte_vhost/vhost_crypto.c\n@@ -453,14 +453,20 @@ vhost_crypto_msg_post_handler(int vid, void *msg)\n \t\treturn RTE_VHOST_MSG_RESULT_ERR;\n \t}\n \n-\tif (vmsg->request.master == VHOST_USER_CRYPTO_CREATE_SESS) {\n+\tswitch (vmsg->request.master) {\n+\tcase VHOST_USER_CRYPTO_CREATE_SESS:\n \t\tvhost_crypto_create_sess(vcrypto,\n \t\t\t\t&vmsg->payload.crypto_session);\n \t\tvmsg->fd_num = 0;\n \t\tret = RTE_VHOST_MSG_RESULT_REPLY;\n-\t} else if (vmsg->request.master == VHOST_USER_CRYPTO_CLOSE_SESS) {\n+\t\tbreak;\n+\tcase VHOST_USER_CRYPTO_CLOSE_SESS:\n \t\tif (vhost_crypto_close_sess(vcrypto, vmsg->payload.u64))\n \t\t\tret = RTE_VHOST_MSG_RESULT_ERR;\n+\t\tbreak;\n+\tdefault:\n+\t\tret = RTE_VHOST_MSG_RESULT_NOT_HANDLED;\n+\t\tbreak;\n \t}\n \n \treturn ret;\ndiff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c\nindex 555d09ad9..39756fce7 100644\n--- a/lib/librte_vhost/vhost_user.c\n+++ b/lib/librte_vhost/vhost_user.c\n@@ -1910,7 +1910,7 @@ vhost_user_msg_handler(int vid, int fd)\n \tint did = -1;\n \tint ret;\n \tint unlock_required = 0;\n-\tuint32_t skip_master = 0;\n+\tbool handled;\n \tint request;\n \n \tdev = get_device(vid);\n@@ -1928,27 +1928,30 @@ vhost_user_msg_handler(int vid, int fd)\n \t}\n \n \tret = read_vhost_message(fd, &msg);\n-\tif (ret <= 0 || msg.request.master >= VHOST_USER_MAX) {\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\telse\n \t\t\tRTE_LOG(INFO, VHOST_CONFIG,\n \t\t\t\t\"vhost peer closed\\n\");\n-\t\telse\n-\t\t\tRTE_LOG(ERR, VHOST_CONFIG,\n-\t\t\t\t\"vhost read incorrect message\\n\");\n \n \t\treturn -1;\n \t}\n \n \tret = 0;\n-\tif (msg.request.master != VHOST_USER_IOTLB_MSG)\n-\t\tRTE_LOG(INFO, VHOST_CONFIG, \"read message %s\\n\",\n-\t\t\tvhost_message_str[msg.request.master]);\n-\telse\n-\t\tRTE_LOG(DEBUG, VHOST_CONFIG, \"read message %s\\n\",\n-\t\t\tvhost_message_str[msg.request.master]);\n+\trequest = msg.request.master;\n+\tif (request > VHOST_USER_NONE && request < VHOST_USER_MAX &&\n+\t\t\tvhost_message_str[request]) {\n+\t\tif (request != VHOST_USER_IOTLB_MSG)\n+\t\t\tRTE_LOG(INFO, VHOST_CONFIG, \"read message %s\\n\",\n+\t\t\t\tvhost_message_str[request]);\n+\t\telse\n+\t\t\tRTE_LOG(DEBUG, VHOST_CONFIG, \"read message %s\\n\",\n+\t\t\t\tvhost_message_str[request]);\n+\t} else {\n+\t\tRTE_LOG(DEBUG, VHOST_CONFIG, \"External request %d\\n\", request);\n+\t}\n \n \tret = vhost_user_check_and_alloc_queue_pair(dev, &msg);\n \tif (ret < 0) {\n@@ -1964,7 +1967,7 @@ vhost_user_msg_handler(int vid, int fd)\n \t * inactive, so it is safe. Otherwise taking the access_lock\n \t * would cause a dead lock.\n \t */\n-\tswitch (msg.request.master) {\n+\tswitch (request) {\n \tcase VHOST_USER_SET_FEATURES:\n \tcase VHOST_USER_SET_PROTOCOL_FEATURES:\n \tcase VHOST_USER_SET_OWNER:\n@@ -1989,19 +1992,24 @@ vhost_user_msg_handler(int vid, int fd)\n \n \t}\n \n+\thandled = false;\n \tif (dev->extern_ops.pre_msg_handle) {\n \t\tret = (*dev->extern_ops.pre_msg_handle)(dev->vid,\n-\t\t\t\t(void *)&msg, &skip_master);\n-\t\tif (ret == RTE_VHOST_MSG_RESULT_ERR)\n-\t\t\tgoto skip_to_reply;\n-\t\telse if (ret == RTE_VHOST_MSG_RESULT_REPLY)\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-\n-\t\tif (skip_master)\n+\t\t\t/* Fall-through */\n+\t\tcase RTE_VHOST_MSG_RESULT_ERR:\n+\t\tcase RTE_VHOST_MSG_RESULT_OK:\n+\t\t\thandled = true;\n \t\t\tgoto skip_to_post_handle;\n+\t\tcase RTE_VHOST_MSG_RESULT_NOT_HANDLED:\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n \t}\n \n-\trequest = msg.request.master;\n \tif (request > VHOST_USER_NONE && request < VHOST_USER_MAX) {\n \t\tif (!vhost_message_handlers[request])\n \t\t\tgoto skip_to_post_handle;\n@@ -2012,40 +2020,54 @@ vhost_user_msg_handler(int vid, int fd)\n \t\t\tRTE_LOG(ERR, VHOST_CONFIG,\n \t\t\t\t\"Processing %s failed.\\n\",\n \t\t\t\tvhost_message_str[request]);\n+\t\t\thandled = true;\n \t\t\tbreak;\n \t\tcase RTE_VHOST_MSG_RESULT_OK:\n \t\t\tRTE_LOG(DEBUG, VHOST_CONFIG,\n \t\t\t\t\"Processing %s succeeded.\\n\",\n \t\t\t\tvhost_message_str[request]);\n+\t\t\thandled = true;\n \t\t\tbreak;\n \t\tcase RTE_VHOST_MSG_RESULT_REPLY:\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\thandled = true;\n+\t\t\tbreak;\n+\t\tdefault:\n \t\t\tbreak;\n \t\t}\n-\t} else {\n-\t\tRTE_LOG(ERR, VHOST_CONFIG,\n-\t\t\t\"Requested invalid message type %d.\\n\", request);\n-\t\tret = RTE_VHOST_MSG_RESULT_ERR;\n \t}\n \n skip_to_post_handle:\n \tif (ret != RTE_VHOST_MSG_RESULT_ERR &&\n \t\t\tdev->extern_ops.post_msg_handle) {\n-\t\tret = (*dev->extern_ops.post_msg_handle)(\n-\t\t\t\tdev->vid, (void *)&msg);\n-\t\tif (ret == RTE_VHOST_MSG_RESULT_ERR)\n-\t\t\tgoto skip_to_reply;\n-\t\telse if (ret == RTE_VHOST_MSG_RESULT_REPLY)\n+\t\tret = (*dev->extern_ops.post_msg_handle)(dev->vid,\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\t/* Fall-through */\n+\t\tcase RTE_VHOST_MSG_RESULT_ERR:\n+\t\tcase RTE_VHOST_MSG_RESULT_OK:\n+\t\t\thandled = true;\n+\t\tcase RTE_VHOST_MSG_RESULT_NOT_HANDLED:\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n \t}\n \n-skip_to_reply:\n \tif (unlock_required)\n \t\tvhost_user_unlock_all_queue_pairs(dev);\n \n+\t/* If message was not handled at this stage, treat it as an error */\n+\tif (!handled) {\n+\t\tRTE_LOG(ERR, VHOST_CONFIG,\n+\t\t\t\"vhost message (req: %d) was not handled.\\n\", request);\n+\t\tret = RTE_VHOST_MSG_RESULT_ERR;\n+\t}\n+\n \t/*\n \t * If the request required a reply that was already sent,\n \t * this optional reply-ack won't be sent as the\n",
    "prefixes": [
        "v3",
        "2/2"
    ]
}