get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 44989,
    "url": "https://patches.dpdk.org/api/patches/44989/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20180920045626.106109-1-qi.z.zhang@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": "<20180920045626.106109-1-qi.z.zhang@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20180920045626.106109-1-qi.z.zhang@intel.com",
    "date": "2018-09-20T04:56:26",
    "name": "[RFC,v3] ethdev: claim device reset as async",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "6eabf68d47554bba50288f3c557c7f245ba14e6f",
    "submitter": {
        "id": 504,
        "url": "https://patches.dpdk.org/api/people/504/?format=api",
        "name": "Qi Zhang",
        "email": "qi.z.zhang@intel.com"
    },
    "delegate": {
        "id": 319,
        "url": "https://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20180920045626.106109-1-qi.z.zhang@intel.com/mbox/",
    "series": [
        {
            "id": 1405,
            "url": "https://patches.dpdk.org/api/series/1405/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=1405",
            "date": "2018-09-20T04:56:26",
            "name": "[RFC,v3] ethdev: claim device reset as async",
            "version": 3,
            "mbox": "https://patches.dpdk.org/series/1405/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/44989/comments/",
    "check": "fail",
    "checks": "https://patches.dpdk.org/api/patches/44989/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 BCD5556A3;\n\tThu, 20 Sep 2018 06:55:31 +0200 (CEST)",
            "from mga06.intel.com (mga06.intel.com [134.134.136.31])\n\tby dpdk.org (Postfix) with ESMTP id EBDC0568A\n\tfor <dev@dpdk.org>; Thu, 20 Sep 2018 06:55:29 +0200 (CEST)",
            "from fmsmga007.fm.intel.com ([10.253.24.52])\n\tby orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t19 Sep 2018 21:55:28 -0700",
            "from dpdk51.sh.intel.com ([10.67.110.190])\n\tby fmsmga007.fm.intel.com with ESMTP; 19 Sep 2018 21:55:26 -0700"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.53,397,1531810800\"; d=\"scan'208\";a=\"71429522\"",
        "From": "Qi Zhang <qi.z.zhang@intel.com>",
        "To": "thomas@monjalon.net,\n\tdeclan.doherty@intel.com,\n\tferruh.yigit@intel.com",
        "Cc": "ktraynor@redhat.com, dev@dpdk.org, benjamin.h.shelton@intel.com,\n\tnarender.vangati@intel.com, Qi Zhang <qi.z.zhang@intel.com>",
        "Date": "Thu, 20 Sep 2018 12:56:26 +0800",
        "Message-Id": "<20180920045626.106109-1-qi.z.zhang@intel.com>",
        "X-Mailer": "git-send-email 2.13.6",
        "Subject": "[dpdk-dev] [RFC v3] ethdev: claim device reset as async",
        "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": "Device reset should be implemented in an async way since it is\npossible to be invoked in interrupt thread and sometimes to reset a\ndevice need to wait for some dependency, for example, a VF expects for\nPF ready or a NIC function as part of a SOC wait for the whole system\nreset complete, and all these time-consuming tasks will block the\ninterrupt thread.\nThe patch rename rte_eth_dev_reset to rte_eth_dev_reset_async and\nrework the implementation. It will spawn a new thread which will call\nops->dev_reset, and when finished it will raise the event\nRTE_ETH_EVENT_RESET_COMPLETE. The application should always wait for\nthis event before it continues to configure and restart the device.\n\nSigned-off-by: Qi Zhang <qi.z.zhang@intel.com>\n---\n app/test-pmd/testpmd.c         | 50 +++++++++++++++++++++++++++++++++++++++++-\n lib/librte_ethdev/rte_ethdev.c | 50 +++++++++++++++++++++++++++++++++++++++---\n lib/librte_ethdev/rte_ethdev.h | 48 ++++++++++++++++++++++++----------------\n 3 files changed, 125 insertions(+), 23 deletions(-)",
    "diff": "diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c\nindex ee48db2a3..ce3d9931b 100644\n--- a/app/test-pmd/testpmd.c\n+++ b/app/test-pmd/testpmd.c\n@@ -1918,6 +1918,54 @@ close_port(portid_t pid)\n \tprintf(\"Done\\n\");\n }\n \n+static int reset_ret;\n+static int reset_done;\n+\n+static int\n+on_reset_complete(__rte_unused uint16_t port_id,\n+\t\t__rte_unused enum rte_eth_event_type event,\n+\t\t__rte_unused void *cb_arg,\n+\t\tvoid *ret_param)\n+{\n+\tRTE_ASSERT(event == RTE_ETH_EVENT_RESET_COMPLETE);\n+\n+\treset_ret = *(int *)ret_param;\n+\treset_done = 1;\n+\treturn 0;\n+}\n+\n+static int\n+do_dev_reset_sync(portid_t pid)\n+{\n+\tint ret;\n+\n+\tret = rte_eth_dev_callback_register(pid,\n+\t\t\tRTE_ETH_EVENT_RESET_COMPLETE,\n+\t\t\ton_reset_complete, NULL);\n+\n+\tif (ret) {\n+\t\tprintf(\"Fail to reigster callback function\\n\");\n+\t\treturn ret;\n+\t}\n+\n+\treset_done = 0;\n+\tret = rte_eth_dev_reset_async(pid);\n+\tif (ret)\n+\t\tgoto finish;\n+\n+\twhile (!reset_done)\n+\t\trte_delay_ms(10);\n+\n+\tret = reset_ret;\n+\n+finish:\n+\trte_eth_dev_callback_unregister(pid,\n+\t\t\tRTE_ETH_EVENT_RESET_COMPLETE,\n+\t\t\ton_reset_complete, NULL);\n+\n+\treturn ret;\n+}\n+\n void\n reset_port(portid_t pid)\n {\n@@ -1946,7 +1994,7 @@ reset_port(portid_t pid)\n \t\t\tcontinue;\n \t\t}\n \n-\t\tdiag = rte_eth_dev_reset(pi);\n+\t\tdiag = do_dev_reset_sync(pi);\n \t\tif (diag == 0) {\n \t\t\tport = &ports[pi];\n \t\t\tport->need_reconfig = 1;\ndiff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c\nindex 4c3202505..69279577d 100644\n--- a/lib/librte_ethdev/rte_ethdev.c\n+++ b/lib/librte_ethdev/rte_ethdev.c\n@@ -1374,10 +1374,38 @@ rte_eth_dev_close(uint16_t port_id)\n \tdev->data->tx_queues = NULL;\n }\n \n+struct dev_reset_args {\n+\tstruct rte_eth_dev *dev;\n+\tenum rte_eth_dev_state pre_state;\n+};\n+\n+static void *\n+do_dev_reset(void *args)\n+{\n+\tstruct dev_reset_args *reset_args = args;\n+\tstruct rte_eth_dev *dev = reset_args->dev;\n+\tint ret;\n+\n+\tret = dev->dev_ops->dev_reset(dev);\n+\n+\t/*restore previous device state */\n+\tdev->state = reset_args->pre_state;\n+\n+\t/* notify users */\n+\t_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_RESET_COMPLETE,\n+\t\t\t\t\t&ret);\n+\n+\tfree(args);\n+\treturn NULL;\n+}\n+\n int\n-rte_eth_dev_reset(uint16_t port_id)\n+rte_eth_dev_reset_async(uint16_t port_id)\n {\n \tstruct rte_eth_dev *dev;\n+\tstruct dev_reset_args *args;\n+\tchar pthread_name[20];\n+\tpthread_t tid;\n \tint ret;\n \n \tRTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);\n@@ -1385,10 +1413,26 @@ rte_eth_dev_reset(uint16_t port_id)\n \n \tRTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_reset, -ENOTSUP);\n \n+\t/* already on resetting */\n+\tif (dev->state == RTE_ETH_DEV_RESETTING)\n+\t\treturn 0;\n+\n+\targs = calloc(1, sizeof(struct dev_reset_args));\n+\tif (!args)\n+\t\treturn -ENOMEM;\n+\n \trte_eth_dev_stop(port_id);\n-\tret = dev->dev_ops->dev_reset(dev);\n \n-\treturn eth_err(port_id, ret);\n+\t/* store previous device state temporary */\n+\targs->pre_state = dev->state;\n+\n+\tdev->state = RTE_ETH_DEV_RESETTING;\n+\tsnprintf(pthread_name, sizeof(pthread_name),\n+\t\t\t\"do_dev_reset_%d\", port_id);\n+\tret = rte_ctrl_thread_create(&tid, pthread_name, NULL,\n+\t\t\t\t\tdo_dev_reset, args);\n+\n+\treturn ret;\n }\n \n int __rte_experimental\ndiff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h\nindex 7070e9ab4..95fcb2931 100644\n--- a/lib/librte_ethdev/rte_ethdev.h\n+++ b/lib/librte_ethdev/rte_ethdev.h\n@@ -1239,6 +1239,8 @@ enum rte_eth_dev_state {\n \tRTE_ETH_DEV_DEFERRED,\n \t/** Device is in removed state when plug-out is detected. */\n \tRTE_ETH_DEV_REMOVED,\n+\t/** Device is on resetting when rte_eth_dev_reset_async is called. */\n+\tRTE_ETH_DEV_RESETTING,\n };\n \n struct rte_eth_dev_sriov {\n@@ -1814,21 +1816,29 @@ void rte_eth_dev_close(uint16_t port_id);\n  * RTE_ETH_EVENT_INTR_RESET event is detected, but can also use it to start\n  * a port reset in other circumstances.\n  *\n- * When this function is called, it first stops the port and then calls the\n- * PMD specific dev_uninit( ) and dev_init( ) to return the port to initial\n- * state, in which no Tx and Rx queues are setup, as if the port has been\n- * reset and not started. The port keeps the port id it had before the\n- * function call.\n- *\n- * After calling rte_eth_dev_reset( ), the application should use\n- * rte_eth_dev_configure( ), rte_eth_rx_queue_setup( ),\n- * rte_eth_tx_queue_setup( ), and rte_eth_dev_start( )\n- * to reconfigure the device as appropriate.\n- *\n- * Note: To avoid unexpected behavior, the application should stop calling\n- * Tx and Rx functions before calling rte_eth_dev_reset( ). For thread\n- * safety, all these controlling functions should be called from the same\n- * thread.\n+ * @note\n+ * Device reset may have the dependency, for example, a VF reset expects\n+ * PF ready, or a NIC function as a part of a SOC need to wait for other\n+ * parts of the system be ready, these are time-consuming tasks and will\n+ * block current thread.\n+ *\n+ * As the name, rte_eth_dev_reset_async is an async API, it will spwan a\n+ * new thread to call ops->dev_reset, once it is finished, it will raise\n+ * the RTE_ETH_EVENT_RESET_COMPLETE event to notify application.  That makes\n+ * things easy for an application that what to reset the device from the\n+ * interrupt thread since typically a RTE_ETH_EVENT_INTR_RESET handler is\n+ * invoked in interrupt thread.\n+ *\n+ * Application should not assume device reset is finished after\n+ * rte_eth_dev_reset_async return, it should always wait for a\n+ * RTE_ETH_EVENT_RESET_COMPLETE event and check the reset result.\n+ * If reset success, application should call rte_eth_dev_configure( ),\n+ * rte_eth_rx_queue_setup( ), rte_eth_tx_queue_setup( ),\n+ * and rte_eth_dev_start( ) to reconfigure the device as appropriate.\n+ *\n+ * @Note\n+ * To avoid unexpected behavior, the application should stop calling\n+ * Tx and Rx functions before calling rte_eth_dev_reset_async( ).\n  *\n  * @param port_id\n  *   The port identifier of the Ethernet device.\n@@ -1837,12 +1847,10 @@ void rte_eth_dev_close(uint16_t port_id);\n  *   - (0) if successful.\n  *   - (-EINVAL) if port identifier is invalid.\n  *   - (-ENOTSUP) if hardware doesn't support this function.\n- *   - (-EPERM) if not ran from the primary process.\n- *   - (-EIO) if re-initialisation failed or device is removed.\n  *   - (-ENOMEM) if the reset failed due to OOM.\n- *   - (-EAGAIN) if the reset temporarily failed and should be retried later.\n+ *   - (<0) other errors from low level driver.\n  */\n-int rte_eth_dev_reset(uint16_t port_id);\n+int rte_eth_dev_reset_async(uint16_t port_id);\n \n /**\n  * Enable receipt in promiscuous mode for an Ethernet device.\n@@ -2574,6 +2582,8 @@ enum rte_eth_event_type {\n \t\t\t\t/**< queue state event (enabled/disabled) */\n \tRTE_ETH_EVENT_INTR_RESET,\n \t\t\t/**< reset interrupt event, sent to VF on PF reset */\n+\tRTE_ETH_EVENT_RESET_COMPLETE,\n+\t\t\t/**< inform application that reset is completed */\n \tRTE_ETH_EVENT_VF_MBOX,  /**< message from the VF received by PF */\n \tRTE_ETH_EVENT_MACSEC,   /**< MACsec offload related event */\n \tRTE_ETH_EVENT_INTR_RMV, /**< device removal event */\n",
    "prefixes": [
        "RFC",
        "v3"
    ]
}