get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 64134,
    "url": "https://patches.dpdk.org/api/patches/64134/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1577328342-216505-1-git-send-email-taox.zhu@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": "<1577328342-216505-1-git-send-email-taox.zhu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1577328342-216505-1-git-send-email-taox.zhu@intel.com",
    "date": "2019-12-26T02:45:42",
    "name": "net/ixgbe: fix blocking system events",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "79f162bf76658e0bfd6eca6d1946eb9bf56a9e55",
    "submitter": {
        "id": 1368,
        "url": "https://patches.dpdk.org/api/people/1368/?format=api",
        "name": "Zhu, TaoX",
        "email": "taox.zhu@intel.com"
    },
    "delegate": {
        "id": 31221,
        "url": "https://patches.dpdk.org/api/users/31221/?format=api",
        "username": "yexl",
        "first_name": "xiaolong",
        "last_name": "ye",
        "email": "xiaolong.ye@intel.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1577328342-216505-1-git-send-email-taox.zhu@intel.com/mbox/",
    "series": [
        {
            "id": 7949,
            "url": "https://patches.dpdk.org/api/series/7949/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=7949",
            "date": "2019-12-26T02:45:42",
            "name": "net/ixgbe: fix blocking system events",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/7949/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/64134/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/64134/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 80892A04FC;\n\tThu, 26 Dec 2019 03:47:38 +0100 (CET)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id A7AEC1BF84;\n\tThu, 26 Dec 2019 03:47:37 +0100 (CET)",
            "from mga06.intel.com (mga06.intel.com [134.134.136.31])\n by dpdk.org (Postfix) with ESMTP id 1A5BF1BF83;\n Thu, 26 Dec 2019 03:47:35 +0100 (CET)",
            "from fmsmga002.fm.intel.com ([10.253.24.26])\n by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n 25 Dec 2019 18:47:34 -0800",
            "from unknown (HELO dpdk-zhangalvin-dev.sh.intel.com)\n ([10.240.179.50])\n by fmsmga002.fm.intel.com with ESMTP; 25 Dec 2019 18:47:33 -0800"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.69,357,1571727600\"; d=\"scan'208\";a=\"250236139\"",
        "From": "taox.zhu@intel.com",
        "To": "konstantin.ananyev@intel.com wenzhuo.lu@intel.com",
        "Cc": "dev@dpdk.org,\n\tZhu Tao <taox.zhu@intel.com>,\n\tstable@dpdk.org",
        "Date": "Thu, 26 Dec 2019 10:45:42 +0800",
        "Message-Id": "<1577328342-216505-1-git-send-email-taox.zhu@intel.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "Subject": "[dpdk-dev] [PATCH] net/ixgbe: fix blocking system events",
        "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": "From: Zhu Tao <taox.zhu@intel.com>\n\nIXGBE link status task use rte alarm thread in old implementation.\nSometime ixgbe link status task takes up to 9 seconds. This will\nseverely affect the rte-alarm-thread-dependent a task in the system,\nlike  interrupt or hotplug event. So replace with a independent thread\nwhich has the same thread affinity settings as rte interrupt.\n\nFixes: 0408f47b (\"net/ixgbe: fix busy polling while fiber link update\")\nCc: stable@dpdk.org\n\nSigned-off-by: Zhu Tao <taox.zhu@intel.com>\n---\n drivers/net/ixgbe/ixgbe_ethdev.c | 184 +++++++++++++++++++++++++++++++++++++--\n drivers/net/ixgbe/ixgbe_ethdev.h |  32 +++++++\n 2 files changed, 210 insertions(+), 6 deletions(-)",
    "diff": "diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c\nindex 2c6fd0f..f0b387d 100644\n--- a/drivers/net/ixgbe/ixgbe_ethdev.c\n+++ b/drivers/net/ixgbe/ixgbe_ethdev.c\n@@ -15,6 +15,7 @@\n #include <rte_byteorder.h>\n #include <rte_common.h>\n #include <rte_cycles.h>\n+#include <rte_tailq.h>\n \n #include <rte_interrupts.h>\n #include <rte_log.h>\n@@ -378,6 +379,9 @@ static int ixgbe_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,\n \t\t\t\t\t struct rte_eth_udp_tunnel *udp_tunnel);\n static int ixgbe_filter_restore(struct rte_eth_dev *dev);\n static void ixgbe_l2_tunnel_conf(struct rte_eth_dev *dev);\n+static int ixgbe_task_thread_init(struct rte_eth_dev *dev);\n+static void ixgbe_task_thread_uninit(struct rte_eth_dev *dev);\n+\n \n /*\n  * Define VF Stats MACRO for Non \"cleared on read\" register\n@@ -1069,6 +1073,171 @@ struct rte_ixgbe_xstats_name_off {\n }\n \n /*\n+ * Add a task to task queue tail.\n+ */\n+int ixgbe_add_task(struct rte_eth_dev *dev, ixgbe_task_cb_fn task_cb)\n+{\n+\tstruct ixgbe_adapter *ad = dev->data->dev_private;\n+\tstruct ixgbe_task *task;\n+\n+\tif (ad->task_status == IXGBE_TASK_THREAD_RUNNING) {\n+\t\ttask = rte_zmalloc(\"ixgbe\", sizeof(struct ixgbe_task), 0);\n+\t\tif (task == NULL)\n+\t\t\treturn -ENOMEM;\n+\n+\t\ttask->arg = dev;\n+\t\ttask->task_cb = task_cb;\n+\t\ttask->status = IXGBE_TASK_READY;\n+\n+\t\tpthread_mutex_lock(&ad->task_lock);\n+\t\tTAILQ_INSERT_TAIL(&ad->task_head, task, next);\n+\t\tpthread_cond_signal(&ad->task_cond);\n+\t\tpthread_mutex_unlock(&ad->task_lock);\n+\t} else {\n+\t\treturn -EPERM;\t/* Operation not permitted */\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/*\n+ * Sync cancel a task with all @task_cb be exit.\n+ */\n+int ixgbe_cancel_task(struct rte_eth_dev *dev, ixgbe_task_cb_fn task_cb)\n+{\n+\tstruct ixgbe_adapter *ad = dev->data->dev_private;\n+\tstruct ixgbe_task *task, *ttask;\n+\tint i, executing;\n+#define DELAY_TIMEOUT_LOG   2000\t// 2s\n+#define DELAY_TIMEOUT_MAX   10000\t// 10s\n+\n+\tfor (i = 0; i < DELAY_TIMEOUT_MAX; i++) {\n+\t\texecuting = 0;\n+\t\tif (ad->task_status == IXGBE_TASK_THREAD_RUNNING) {\n+\t\t\tpthread_mutex_lock(&ad->task_lock);\n+\t\t\tTAILQ_FOREACH_SAFE(task, &ad->task_head, next, ttask) {\n+\t\t\t\tif (task->task_cb == task_cb) {\n+\t\t\t\t\tif (task->status == IXGBE_TASK_RUNNING) {\n+\t\t\t\t\t\texecuting++;\n+\t\t\t\t\t} else {\n+\t\t\t\t\t\tTAILQ_REMOVE(&ad->task_head, task, next);\n+\t\t\t\t\t\trte_free(task);\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tpthread_mutex_unlock(&ad->task_lock);\n+\n+\t\t\tif (executing) {\n+\t\t\t\tif (i > DELAY_TIMEOUT_LOG && (i % 1000 == 0)) {\n+\t\t\t\t\tPMD_DRV_LOG(WARNING,\n+\t\t\t\t\t\t    \"Cannel task time wait %ds!\", i / 1000);\n+\t\t\t\t}\n+\n+\t\t\t\trte_delay_us_sleep(1000);\t// 1ms\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\t\t}\n+\t\tbreak;\n+\t}\n+\n+\tif (i == DELAY_TIMEOUT_MAX)\n+\t\treturn -EBUSY;\n+\n+\treturn 0;\n+}\n+\n+/*\n+ * Task main thread. Loop until state is set to IXGBE_TASK_THREAD_EXIT.\n+ * For each task, set the status to IXGBE_TASK_RUNNING before execution,\n+ * execute and then be dequeue.\n+ */\n+static void *ixgbe_task_handler(void *args)\n+{\n+\tstruct ixgbe_adapter *ad =\n+\t    ((struct rte_eth_dev *)args)->data->dev_private;\n+\tstruct ixgbe_task *task;\n+\n+\tPMD_INIT_LOG(DEBUG, \"ixgbe task thread created\");\n+\twhile (ad->task_status) {\n+\t\tpthread_mutex_lock(&ad->task_lock);\n+\t\tif (TAILQ_EMPTY(&ad->task_head)) {\n+\t\t\tpthread_cond_wait(&ad->task_cond, &ad->task_lock);\n+\t\t\tpthread_mutex_unlock(&ad->task_lock);\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\t/* pop firt task and run it */\n+\t\ttask = TAILQ_FIRST(&ad->task_head);\n+\t\ttask->status = IXGBE_TASK_RUNNING;\n+\t\tpthread_mutex_unlock(&ad->task_lock);\n+\n+\t\tif (task && task->task_cb)\n+\t\t\ttask->task_cb(task->arg);\n+\n+\t\tpthread_mutex_lock(&ad->task_lock);\n+\t\tTAILQ_REMOVE(&ad->task_head, task, next);\n+\t\trte_free(task);\n+\t\tpthread_mutex_unlock(&ad->task_lock);\n+\t}\n+\n+\tpthread_mutex_lock(&ad->task_lock);\n+\twhile (!TAILQ_EMPTY(&ad->task_head)) {\n+\t\ttask = TAILQ_FIRST(&ad->task_head);\n+\t\tTAILQ_REMOVE(&ad->task_head, task, next);\n+\t\trte_free(task);\n+\t}\n+\tpthread_mutex_unlock(&ad->task_lock);\n+\tad->task_status = IXGBE_TASK_THREAD_EXIT_DONE;\n+\n+\treturn NULL;\n+}\n+\n+static int ixgbe_task_thread_init(struct rte_eth_dev *dev)\n+{\n+\tstruct ixgbe_adapter *ad = dev->data->dev_private;\n+\tstruct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);\n+\tchar name[IXGBE_TASK_THREAD_NAME_LEN];\n+\tint ret;\n+\n+\tTAILQ_INIT(&ad->task_head);\n+\tpthread_mutex_init(&ad->task_lock, NULL);\n+\tpthread_cond_init(&ad->task_cond, NULL);\n+\n+\tsnprintf(name, IXGBE_TASK_THREAD_NAME_LEN, \"ixgbe-delay:%s\",\n+\t\t pci_dev->name);\n+\n+\tret = rte_ctrl_thread_create(&ad->task_tid, name, NULL,\n+\t\t\t\t     ixgbe_task_handler, dev);\n+\tif (ret < 0) {\n+\t\tPMD_INIT_LOG(ERR, \"Create control thread %s fail!\", name);\n+\t\treturn ret;\n+\t}\n+\tad->task_status = IXGBE_TASK_THREAD_RUNNING;\n+\n+\treturn 0;\n+}\n+\n+static void ixgbe_task_thread_uninit(struct rte_eth_dev *dev)\n+{\n+\tstruct ixgbe_adapter *ad = dev->data->dev_private;\n+\tint i;\n+#define MAX_EXIT_TIMEOUT  3000\t/* 3s */\n+\n+\tif (ad->task_status == IXGBE_TASK_THREAD_RUNNING) {\n+\t\tad->task_status = IXGBE_TASK_THREAD_EXIT;\n+\t\tpthread_cond_signal(&ad->task_cond);\n+\t\tfor (i = 0; i < MAX_EXIT_TIMEOUT; i++) {\n+\t\t\tif (ad->task_status == IXGBE_TASK_THREAD_EXIT_DONE) {\n+\t\t\t\tpthread_cond_destroy(&ad->task_cond);\n+\t\t\t\tpthread_mutex_destroy(&ad->task_lock);\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\trte_delay_us_sleep(1000);\t// 1ms\n+\t\t}\n+\t}\n+}\n+\n+/*\n  * This function is based on code in ixgbe_attach() in base/ixgbe.c.\n  * It returns 0 on success.\n  */\n@@ -1301,6 +1470,7 @@ struct rte_ixgbe_xstats_name_off {\n \t/* enable support intr */\n \tixgbe_enable_intr(eth_dev);\n \n+\tixgbe_task_thread_init(eth_dev);\n \tixgbe_dev_set_link_down(eth_dev);\n \n \t/* initialize filter info */\n@@ -1337,6 +1507,7 @@ struct rte_ixgbe_xstats_name_off {\n \t\treturn 0;\n \n \tixgbe_dev_close(eth_dev);\n+\tixgbe_task_thread_uninit(eth_dev);\n \n \treturn 0;\n }\n@@ -1713,6 +1884,7 @@ static int ixgbe_l2_tn_filter_init(struct rte_eth_dev *eth_dev)\n \t\t\t\t   ixgbevf_dev_interrupt_handler, eth_dev);\n \trte_intr_enable(intr_handle);\n \tixgbevf_intr_enable(eth_dev);\n+\tixgbe_task_thread_init(eth_dev);\n \n \tPMD_INIT_LOG(DEBUG, \"port %d vendorID=0x%x deviceID=0x%x mac.type=%s\",\n \t\t     eth_dev->data->port_id, pci_dev->id.vendor_id,\n@@ -1732,6 +1904,7 @@ static int ixgbe_l2_tn_filter_init(struct rte_eth_dev *eth_dev)\n \t\treturn 0;\n \n \tixgbevf_dev_close(eth_dev);\n+\tixgbe_task_thread_uninit(eth_dev);\n \n \treturn 0;\n }\n@@ -2570,7 +2743,7 @@ static int eth_ixgbevf_pci_remove(struct rte_pci_device *pci_dev)\n \t}\n \n \t/* Stop the link setup handler before resetting the HW. */\n-\trte_eal_alarm_cancel(ixgbe_dev_setup_link_alarm_handler, dev);\n+\tixgbe_cancel_task(dev, ixgbe_dev_setup_link_alarm_handler);\n \n \t/* disable uio/vfio intr/eventfd mapping */\n \trte_intr_disable(intr_handle);\n@@ -2842,7 +3015,7 @@ static int eth_ixgbevf_pci_remove(struct rte_pci_device *pci_dev)\n \n \tPMD_INIT_FUNC_TRACE();\n \n-\trte_eal_alarm_cancel(ixgbe_dev_setup_link_alarm_handler, dev);\n+\tixgbe_cancel_task(dev, ixgbe_dev_setup_link_alarm_handler);\n \n \t/* disable interrupts */\n \tixgbe_disable_intr(hw);\n@@ -4162,8 +4335,7 @@ static int ixgbevf_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,\n \tif (link_up == 0) {\n \t\tif (ixgbe_get_media_type(hw) == ixgbe_media_type_fiber) {\n \t\t\tintr->flags |= IXGBE_FLAG_NEED_LINK_CONFIG;\n-\t\t\trte_eal_alarm_set(10,\n-\t\t\t\tixgbe_dev_setup_link_alarm_handler, dev);\n+\t\t\tixgbe_add_task(dev, ixgbe_dev_setup_link_alarm_handler);\n \t\t}\n \t\treturn rte_eth_linkstatus_set(dev, &link);\n \t}\n@@ -5207,7 +5379,7 @@ static int ixgbevf_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,\n \tPMD_INIT_FUNC_TRACE();\n \n \t/* Stop the link setup handler before resetting the HW. */\n-\trte_eal_alarm_cancel(ixgbe_dev_setup_link_alarm_handler, dev);\n+\tixgbe_cancel_task(dev, ixgbe_dev_setup_link_alarm_handler);\n \n \terr = hw->mac.ops.reset_hw(hw);\n \tif (err) {\n@@ -5305,7 +5477,7 @@ static int ixgbevf_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,\n \n \tPMD_INIT_FUNC_TRACE();\n \n-\trte_eal_alarm_cancel(ixgbe_dev_setup_link_alarm_handler, dev);\n+\tixgbe_cancel_task(dev, ixgbe_dev_setup_link_alarm_handler);\n \n \tixgbevf_intr_disable(dev);\n \ndiff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h\nindex 76a1b9d..4426349 100644\n--- a/drivers/net/ixgbe/ixgbe_ethdev.h\n+++ b/drivers/net/ixgbe/ixgbe_ethdev.h\n@@ -470,6 +470,28 @@ struct ixgbe_tm_conf {\n \tbool committed;\n };\n \n+#define IXGBE_TASK_THREAD_NAME_LEN  64\n+enum {\n+\tIXGBE_TASK_THREAD_EXIT = 0,\n+\tIXGBE_TASK_THREAD_RUNNING = 1,\n+\tIXGBE_TASK_THREAD_EXIT_DONE = 2\n+};\n+enum {\n+\tIXGBE_TASK_READY = 0,\n+\tIXGBE_TASK_RUNNING = 1,\n+\tIXGBE_TASK_FINISH = 2\n+};\n+\n+typedef void (*ixgbe_task_cb_fn) (void *arg);\n+struct ixgbe_task {\n+\tTAILQ_ENTRY(ixgbe_task) next;\n+\tvoid *arg;\n+\tint status;\n+\tixgbe_task_cb_fn task_cb;\n+};\n+TAILQ_HEAD(ixgbe_task_head, ixgbe_task);\n+\n+\n /*\n  * Structure to store private data for each driver instance (for each port).\n  */\n@@ -510,6 +532,13 @@ struct ixgbe_adapter {\n \t * mailbox status) link status.\n \t */\n \tuint8_t pflink_fullchk;\n+\n+\t/* Control thread per VF/PF, used for to do delay work */\n+\tpthread_t task_tid;\n+\tstruct ixgbe_task_head task_head;\n+\tint task_status;\n+\tpthread_mutex_t task_lock;\n+\tpthread_cond_t task_cond;\n };\n \n struct ixgbe_vf_representor {\n@@ -760,6 +789,9 @@ void ixgbe_dev_macsec_setting_save(struct rte_eth_dev *dev,\n \t\tstruct ixgbe_macsec_setting *macsec_setting);\n \n void ixgbe_dev_macsec_setting_reset(struct rte_eth_dev *dev);\n+int ixgbe_add_task(struct rte_eth_dev *dev, ixgbe_task_cb_fn task_cb);\n+int ixgbe_cancel_task(struct rte_eth_dev *dev, ixgbe_task_cb_fn task_cb);\n+\n \n static inline int\n ixgbe_ethertype_filter_lookup(struct ixgbe_filter_info *filter_info,\n",
    "prefixes": []
}