Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/64134/?format=api
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": [] }{ "id": 64134, "url": "