Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/756517/?format=api
{ "id": 756517, "url": "http://patchwork.ozlabs.org/api/patches/756517/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20170428184421.20216-6-jacob.e.keller@intel.com/", "project": { "id": 46, "url": "http://patchwork.ozlabs.org/api/projects/46/?format=api", "name": "Intel Wired Ethernet development", "link_name": "intel-wired-lan", "list_id": "intel-wired-lan.osuosl.org", "list_email": "intel-wired-lan@osuosl.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20170428184421.20216-6-jacob.e.keller@intel.com>", "list_archive_url": null, "date": "2017-04-28T18:44:21", "name": "[v3,5/5] net-intel: check for Tx timestamp timeouts during watchdog", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "8bab5f81a26e9c41a4142b2a4f217faa74a67f0a", "submitter": { "id": 9784, "url": "http://patchwork.ozlabs.org/api/people/9784/?format=api", "name": "Jacob Keller", "email": "jacob.e.keller@intel.com" }, "delegate": { "id": 68, "url": "http://patchwork.ozlabs.org/api/users/68/?format=api", "username": "jtkirshe", "first_name": "Jeff", "last_name": "Kirsher", "email": "jeffrey.t.kirsher@intel.com" }, "mbox": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20170428184421.20216-6-jacob.e.keller@intel.com/mbox/", "series": [], "comments": "http://patchwork.ozlabs.org/api/patches/756517/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/756517/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<intel-wired-lan-bounces@lists.osuosl.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Received": [ "from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3wF2mL3pPcz9s7y\n\tfor <incoming@patchwork.ozlabs.org>;\n\tSat, 29 Apr 2017 04:44:34 +1000 (AEST)", "from localhost (localhost [127.0.0.1])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id C73AF885E2;\n\tFri, 28 Apr 2017 18:44:32 +0000 (UTC)", "from fraxinus.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id V9-rczQD-q-m; Fri, 28 Apr 2017 18:44:29 +0000 (UTC)", "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id 1410488591;\n\tFri, 28 Apr 2017 18:44:29 +0000 (UTC)", "from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133])\n\tby ash.osuosl.org (Postfix) with ESMTP id CABF11C26F3\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tFri, 28 Apr 2017 18:44:26 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n\tby hemlock.osuosl.org (Postfix) with ESMTP id C2E868A265\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tFri, 28 Apr 2017 18:44:26 +0000 (UTC)", "from hemlock.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id HVV4VOHVSOAo for <intel-wired-lan@lists.osuosl.org>;\n\tFri, 28 Apr 2017 18:44:25 +0000 (UTC)", "from mga07.intel.com (mga07.intel.com [134.134.136.100])\n\tby hemlock.osuosl.org (Postfix) with ESMTPS id 742878A262\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tFri, 28 Apr 2017 18:44:25 +0000 (UTC)", "from fmsmga001.fm.intel.com ([10.253.24.23])\n\tby orsmga105.jf.intel.com with ESMTP; 28 Apr 2017 11:44:24 -0700", "from jekeller-desk.amr.corp.intel.com (HELO\n\tjekeller-desk.jekeller.internal) ([10.166.35.158])\n\tby fmsmga001.fm.intel.com with ESMTP; 28 Apr 2017 11:44:24 -0700" ], "X-Virus-Scanned": [ "amavisd-new at osuosl.org", "amavisd-new at osuosl.org" ], "X-Greylist": "domain auto-whitelisted by SQLgrey-1.7.6", "X-ExtLoop1": "1", "X-IronPort-AV": "E=Sophos; i=\"5.37,389,1488873600\"; d=\"scan'208\";\n\ta=\"1141484712\"", "From": "Jacob Keller <jacob.e.keller@intel.com>", "To": "Intel Wired LAN <intel-wired-lan@lists.osuosl.org>", "Date": "Fri, 28 Apr 2017 11:44:21 -0700", "Message-Id": "<20170428184421.20216-6-jacob.e.keller@intel.com>", "X-Mailer": "git-send-email 2.13.0.rc0.317.gcc792a6cad5a", "In-Reply-To": "<20170428184421.20216-1-jacob.e.keller@intel.com>", "References": "<20170428184421.20216-1-jacob.e.keller@intel.com>", "Cc": "Richard Cochran <richardcochran@gmail.com>", "Subject": "[Intel-wired-lan] [PATCH v3 5/5] net-intel: check for Tx timestamp\n\ttimeouts during watchdog", "X-BeenThere": "intel-wired-lan@lists.osuosl.org", "X-Mailman-Version": "2.1.18-1", "Precedence": "list", "List-Id": "Intel Wired Ethernet Linux Kernel Driver Development\n\t<intel-wired-lan.lists.osuosl.org>", "List-Unsubscribe": "<http://lists.osuosl.org/mailman/options/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@lists.osuosl.org?subject=unsubscribe>", "List-Archive": "<http://lists.osuosl.org/pipermail/intel-wired-lan/>", "List-Post": "<mailto:intel-wired-lan@lists.osuosl.org>", "List-Help": "<mailto:intel-wired-lan-request@lists.osuosl.org?subject=help>", "List-Subscribe": "<http://lists.osuosl.org/mailman/listinfo/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@lists.osuosl.org?subject=subscribe>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Errors-To": "intel-wired-lan-bounces@lists.osuosl.org", "Sender": "\"Intel-wired-lan\" <intel-wired-lan-bounces@lists.osuosl.org>" }, "content": "Several drivers share similar logic for handling the Tx timestamps.\nThese drivers have some parts which rely on the interrupt instead of\nonly a polling work task. Although unlikely it may be possible in some\ncircumstances for the PTP tx timestamp to never occur. If this happens,\nthe result is that all future Tx timestamp requests will be ignored\npermanently.\n\nFix this by adding a *ptp_tx_hang() function similar to the already\nexisting *ptp_rx_hang() routine which checks to make sure that the\ntimestamp hasn't taken too long. This ensures that we will eventually\nrecover from this case.\n\nSigned-off-by: Jacob Keller <jacob.e.keller@intel.com>\n---\n drivers/net/ethernet/intel/i40e/i40e.h | 2 ++\n drivers/net/ethernet/intel/i40e/i40e_main.c | 1 +\n drivers/net/ethernet/intel/i40e/i40e_ptp.c | 30 +++++++++++++++++++++++++++\n drivers/net/ethernet/intel/i40e/i40e_txrx.c | 1 +\n drivers/net/ethernet/intel/igb/igb.h | 1 +\n drivers/net/ethernet/intel/igb/igb_main.c | 1 +\n drivers/net/ethernet/intel/igb/igb_ptp.c | 29 ++++++++++++++++++++++++++\n drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 +\n drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 1 +\n drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 27 ++++++++++++++++++++++++\n 10 files changed, 94 insertions(+)", "diff": "diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h\nindex f4465afe1fe1..25bf336c5f38 100644\n--- a/drivers/net/ethernet/intel/i40e/i40e.h\n+++ b/drivers/net/ethernet/intel/i40e/i40e.h\n@@ -502,6 +502,7 @@ struct i40e_pf {\n \tstruct ptp_clock *ptp_clock;\n \tstruct ptp_clock_info ptp_caps;\n \tstruct sk_buff *ptp_tx_skb;\n+\tunsigned long ptp_tx_start;\n \tstruct hwtstamp_config tstamp_config;\n \tstruct mutex tmreg_lock; /* Used to protect the SYSTIME registers. */\n \tu64 ptp_base_adj;\n@@ -957,6 +958,7 @@ bool i40e_dcb_need_reconfig(struct i40e_pf *pf,\n \t\t\t struct i40e_dcbx_config *new_cfg);\n #endif /* CONFIG_I40E_DCB */\n void i40e_ptp_rx_hang(struct i40e_pf *pf);\n+void i40e_ptp_tx_hang(struct i40e_pf *pf);\n void i40e_ptp_tx_hwtstamp(struct i40e_pf *pf);\n void i40e_ptp_rx_hwtstamp(struct i40e_pf *pf, struct sk_buff *skb, u8 index);\n void i40e_ptp_set_increment(struct i40e_pf *pf);\ndiff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c\nindex c019dec988e3..e4eb97832413 100644\n--- a/drivers/net/ethernet/intel/i40e/i40e_main.c\n+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c\n@@ -6373,6 +6373,7 @@ static void i40e_watchdog_subtask(struct i40e_pf *pf)\n \t}\n \n \ti40e_ptp_rx_hang(pf);\n+\ti40e_ptp_tx_hang(pf);\n }\n \n /**\ndiff --git a/drivers/net/ethernet/intel/i40e/i40e_ptp.c b/drivers/net/ethernet/intel/i40e/i40e_ptp.c\nindex 876ea169816a..cd35c4b9a8b0 100644\n--- a/drivers/net/ethernet/intel/i40e/i40e_ptp.c\n+++ b/drivers/net/ethernet/intel/i40e/i40e_ptp.c\n@@ -327,6 +327,36 @@ void i40e_ptp_rx_hang(struct i40e_pf *pf)\n \tpf->rx_hwtstamp_cleared += cleared;\n }\n \n+/**\n+ * i40e_ptp_tx_hang - Detect error case when Tx timestamp register is hung\n+ * @pf: The PF private data structure\n+ *\n+ * This watchdog task is run periodically to make sure that we clear the Tx\n+ * timestamp logic if we don't obtain a timestamp in a reasonable amount of\n+ * time. It is unexpected in the normal case but if it occurs it results in\n+ * permanently prevent timestamps of future packets\n+ **/\n+void i40e_ptp_tx_hang(struct i40e_pf *pf)\n+{\n+\tif (!(pf->flags & I40E_FLAG_PTP) || !pf->ptp_tx)\n+\t\treturn;\n+\n+\t/* Nothing to do if we're not already waiting for a timestamp */\n+\tif (!test_bit(__I40E_PTP_TX_IN_PROGRESS, pf->state))\n+\t\treturn;\n+\n+\t/* We already have a handler routine which is run when we are notified\n+\t * of a Tx timestamp in the hardware. If we don't get an interrupt\n+\t * within a second it is reasonable to assume that we never will.\n+\t */\n+\tif (time_is_before_jiffies(pf->ptp_tx_start + HZ)) {\n+\t\tdev_kfree_skb_any(pf->ptp_tx_skb);\n+\t\tpf->ptp_tx_skb = NULL;\n+\t\tclear_bit_unlock(__I40E_PTP_TX_IN_PROGRESS, pf->state);\n+\t\tpf->tx_hwtstamp_timeouts++;\n+\t}\n+}\n+\n /**\n * i40e_ptp_tx_hwtstamp - Utility function which returns the Tx timestamp\n * @pf: Board private structure\ndiff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c\nindex c69ee4b0cfe2..c2e9013d05eb 100644\n--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c\n+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c\n@@ -2628,6 +2628,7 @@ static int i40e_tsyn(struct i40e_ring *tx_ring, struct sk_buff *skb,\n \tif (pf->ptp_tx &&\n \t !test_and_set_bit_lock(__I40E_PTP_TX_IN_PROGRESS, pf->state)) {\n \t\tskb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;\n+\t\tpf->ptp_tx_start = jiffies;\n \t\tpf->ptp_tx_skb = skb_get(skb);\n \t} else {\n \t\tpf->tx_hwtstamp_skipped++;\ndiff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h\nindex be35edcf6b08..ff4d9073781a 100644\n--- a/drivers/net/ethernet/intel/igb/igb.h\n+++ b/drivers/net/ethernet/intel/igb/igb.h\n@@ -677,6 +677,7 @@ void igb_ptp_stop(struct igb_adapter *adapter);\n void igb_ptp_reset(struct igb_adapter *adapter);\n void igb_ptp_suspend(struct igb_adapter *adapter);\n void igb_ptp_rx_hang(struct igb_adapter *adapter);\n+void igb_ptp_tx_hang(struct igb_adapter *adapter);\n void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb);\n void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va,\n \t\t\t struct sk_buff *skb);\ndiff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c\nindex 21b455bfb4ca..eec54d9df06b 100644\n--- a/drivers/net/ethernet/intel/igb/igb_main.c\n+++ b/drivers/net/ethernet/intel/igb/igb_main.c\n@@ -4726,6 +4726,7 @@ static void igb_watchdog_task(struct work_struct *work)\n \n \tigb_spoof_check(adapter);\n \tigb_ptp_rx_hang(adapter);\n+\tigb_ptp_tx_hang(adapter);\n \n \t/* Check LVMMC register on i350/i354 only */\n \tif ((adapter->hw.mac.type == e1000_i350) ||\ndiff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c\nindex a2da5738bfb5..b2f67c169bd2 100644\n--- a/drivers/net/ethernet/intel/igb/igb_ptp.c\n+++ b/drivers/net/ethernet/intel/igb/igb_ptp.c\n@@ -711,6 +711,35 @@ void igb_ptp_rx_hang(struct igb_adapter *adapter)\n \t}\n }\n \n+/**\n+ * igb_ptp_tx_hang - detect error case where Tx timestamp never finishes\n+ * @adapter: private network adapter structure\n+ */\n+void igb_ptp_tx_hang(struct igb_adapter *adapter)\n+{\n+\tbool timeout = time_is_before_jiffies(adapter->ptp_tx_start +\n+\t\t\t\t\t IGB_PTP_TX_TIMEOUT);\n+\n+\tif (!adapter->ptp_tx_skb)\n+\t\treturn;\n+\n+\tif (!test_bit(__IGB_PTP_TX_IN_PROGRESS, &adapter->state))\n+\t\treturn;\n+\n+\t/* If we haven't received a timestamp within the timeout, it is\n+\t * reasonable to assume that it will never occur, so we can unlock the\n+\t * timestamp bit when this occurs.\n+\t */\n+\tif (timeout) {\n+\t\tcancel_work_sync(&adapter->ptp_tx_work);\n+\t\tdev_kfree_skb_any(adapter->ptp_tx_skb);\n+\t\tadapter->ptp_tx_skb = NULL;\n+\t\tclear_bit_unlock(__IGB_PTP_TX_IN_PROGRESS, &adapter->state);\n+\t\tadapter->tx_hwtstamp_timeouts++;\n+\t\tdev_warn(&adapter->pdev->dev, \"clearing Tx timestamp hang\\n\");\n+\t}\n+}\n+\n /**\n * igb_ptp_tx_hwtstamp - utility function which checks for TX time stamp\n * @adapter: Board private structure.\ndiff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h\nindex eb36106218ad..dd5578756ae0 100644\n--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h\n+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h\n@@ -961,6 +961,7 @@ void ixgbe_ptp_suspend(struct ixgbe_adapter *adapter);\n void ixgbe_ptp_stop(struct ixgbe_adapter *adapter);\n void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter);\n void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter);\n+void ixgbe_ptp_tx_hang(struct ixgbe_adapter *adapter);\n void ixgbe_ptp_rx_pktstamp(struct ixgbe_q_vector *, struct sk_buff *);\n void ixgbe_ptp_rx_rgtstamp(struct ixgbe_q_vector *, struct sk_buff *skb);\n static inline void ixgbe_ptp_rx_hwtstamp(struct ixgbe_ring *rx_ring,\ndiff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c\nindex c61459fcc21e..f3199c73faed 100644\n--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c\n+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c\n@@ -7645,6 +7645,7 @@ static void ixgbe_service_task(struct work_struct *work)\n \tif (test_bit(__IXGBE_PTP_RUNNING, &adapter->state)) {\n \t\tixgbe_ptp_overflow_check(adapter);\n \t\tixgbe_ptp_rx_hang(adapter);\n+\t\tixgbe_ptp_tx_hang(adapter);\n \t}\n \n \tixgbe_service_event_complete(adapter);\ndiff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c\nindex 9270e6f4fcff..24f4eaf37727 100644\n--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c\n+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c\n@@ -662,6 +662,33 @@ static void ixgbe_ptp_clear_tx_timestamp(struct ixgbe_adapter *adapter)\n \tclear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, &adapter->state);\n }\n \n+/**\n+ * ixgbe_ptp_tx_hang - detect error case where Tx timestamp never finishes\n+ * @adapter: private network adapter structure\n+ */\n+void ixgbe_ptp_tx_hang(struct ixgbe_adapter *adapter)\n+{\n+\tbool timeout = time_is_before_jiffies(adapter->ptp_tx_start +\n+\t\t\t\t\t IXGBE_PTP_TX_TIMEOUT);\n+\n+\tif (!adapter->ptp_tx_skb)\n+\t\treturn;\n+\n+\tif (!test_bit(__IXGBE_PTP_TX_IN_PROGRESS, &adapter->state))\n+\t\treturn;\n+\n+\t/* If we haven't received a timestamp within the timeout, it is\n+\t * reasonable to assume that it will never occur, so we can unlock the\n+\t * timestamp bit when this occurs.\n+\t */\n+\tif (timeout) {\n+\t\tcancel_work_sync(&adapter->ptp_tx_work);\n+\t\tixgbe_ptp_clear_tx_timestamp(adapter);\n+\t\tadapter->tx_hwtstamp_timeouts++;\n+\t\te_warn(drv, \"clearing Tx timestamp hang\\n\");\n+\t}\n+}\n+\n /**\n * ixgbe_ptp_tx_hwtstamp - utility function which checks for TX time stamp\n * @adapter: the private adapter struct\n", "prefixes": [ "v3", "5/5" ] }