Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/568506/?format=api
{ "id": 568506, "url": "http://patchwork.ozlabs.org/api/patches/568506/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/1452897202-15204-6-git-send-email-joshua.a.hay@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": "<1452897202-15204-6-git-send-email-joshua.a.hay@intel.com>", "list_archive_url": null, "date": "2016-01-15T22:33:12", "name": "[next,S28,05/15] i40e: Add a SW workaround for lost Interrupts", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "e84adf3dab301467bca8dc472049f69d023de63c", "submitter": { "id": 19461, "url": "http://patchwork.ozlabs.org/api/people/19461/?format=api", "name": "Joshua Hay", "email": "joshua.a.hay@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/1452897202-15204-6-git-send-email-joshua.a.hay@intel.com/mbox/", "series": [], "comments": "http://patchwork.ozlabs.org/api/patches/568506/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/568506/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 whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138])\n\tby ozlabs.org (Postfix) with ESMTP id 802D9140BA4\n\tfor <incoming@patchwork.ozlabs.org>;\n\tSat, 16 Jan 2016 09:33:31 +1100 (AEDT)", "from localhost (localhost [127.0.0.1])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id EA338919F7;\n\tFri, 15 Jan 2016 22:33:29 +0000 (UTC)", "from whitealder.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id FaCSwaJvZCIw; Fri, 15 Jan 2016 22:33:26 +0000 (UTC)", "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id 58E2391A21;\n\tFri, 15 Jan 2016 22:33:25 +0000 (UTC)", "from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133])\n\tby ash.osuosl.org (Postfix) with ESMTP id BE9EF1C2189\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tFri, 15 Jan 2016 22:33:24 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n\tby hemlock.osuosl.org (Postfix) with ESMTP id BACD693679\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tFri, 15 Jan 2016 22:33:24 +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 K3tWqH6lWP1k for <intel-wired-lan@lists.osuosl.org>;\n\tFri, 15 Jan 2016 22:33:23 +0000 (UTC)", "from mga14.intel.com (mga14.intel.com [192.55.52.115])\n\tby hemlock.osuosl.org (Postfix) with ESMTP id B9E3093643\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tFri, 15 Jan 2016 22:33:23 +0000 (UTC)", "from fmsmga002.fm.intel.com ([10.253.24.26])\n\tby fmsmga103.fm.intel.com with ESMTP; 15 Jan 2016 14:33:23 -0800", "from jahay1-mobl2.amr.corp.intel.com (HELO\n\tlocalhost.localdomain.localdomain) ([134.134.176.81])\n\tby fmsmga002.fm.intel.com with ESMTP; 15 Jan 2016 14:33:22 -0800" ], "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.22,302,1449561600\"; d=\"scan'208\";a=\"894132180\"", "From": "Joshua Hay <joshua.a.hay@intel.com>", "To": "intel-wired-lan@lists.osuosl.org", "Date": "Fri, 15 Jan 2016 14:33:12 -0800", "Message-Id": "<1452897202-15204-6-git-send-email-joshua.a.hay@intel.com>", "X-Mailer": "git-send-email 2.1.0", "In-Reply-To": "<1452897202-15204-1-git-send-email-joshua.a.hay@intel.com>", "References": "<1452897202-15204-1-git-send-email-joshua.a.hay@intel.com>", "Subject": "[Intel-wired-lan] [next PATCH S28 05/15] i40e: Add a SW workaround\n\tfor lost Interrupts", "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": "From: Anjali Singhai Jain <anjali.singhai@intel.com>\n\nThis patch adds a workaround for cases where we might have\ninterrupts that got lost but WB happened.\nIf that happens without this patch we will see a tx_timeout.\nTo work around it, this patch goes ahead and reschedules napi\nin that situation, if napi is not already scheduled.\nWe also add a counter in ethtool to keep track of when\nwe detect a case of tx_lost_interrupt.\n\nNote: napi_reschedule() can be safely called from process/service_task\ncontext and is done in other drivers as well without an issue.\n\nSigned-off-by: Anjali Singhai Jain <anjali.singhai@intel.com>\nChange-ID: I00f98f1ce3774524d9421227652bef20fcbd0d20\n---\nTesting Hints: See if some more cases of tx_timeout go away from X722\nand even fortville. Particulary the case where HWB=TAIL as seen in\nthe dmesg logs when the tx_timeout happens.\n\n drivers/net/ethernet/intel/i40e/i40e.h | 1 +\n drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 1 +\n drivers/net/ethernet/intel/i40e/i40e_main.c | 32 ++++++++++++++++----------\n drivers/net/ethernet/intel/i40e/i40e_txrx.c | 10 +++++---\n drivers/net/ethernet/intel/i40e/i40e_txrx.h | 3 ++-\n drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 10 +++++---\n drivers/net/ethernet/intel/i40evf/i40e_txrx.h | 3 ++-\n 7 files changed, 40 insertions(+), 20 deletions(-)", "diff": "diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h\nindex 141c5c0..e37af29 100644\n--- a/drivers/net/ethernet/intel/i40e/i40e.h\n+++ b/drivers/net/ethernet/intel/i40e/i40e.h\n@@ -512,6 +512,7 @@ struct i40e_vsi {\n \tu32 tx_busy;\n \tu64 tx_linearize;\n \tu64 tx_force_wb;\n+\tu64 tx_lost_interrupt;\n \tu32 rx_buf_failed;\n \tu32 rx_page_failed;\n \ndiff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c\nindex 40a52b8..d2010290 100644\n--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c\n+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c\n@@ -89,6 +89,7 @@ static const struct i40e_stats i40e_gstrings_misc_stats[] = {\n \tI40E_VSI_STAT(\"rx_unknown_protocol\", eth_stats.rx_unknown_protocol),\n \tI40E_VSI_STAT(\"tx_linearize\", tx_linearize),\n \tI40E_VSI_STAT(\"tx_force_wb\", tx_force_wb),\n+\tI40E_VSI_STAT(\"tx_lost_interrupt\", tx_lost_interrupt),\n \tI40E_VSI_STAT(\"rx_alloc_fail\", rx_buf_failed),\n \tI40E_VSI_STAT(\"rx_pg_alloc_fail\", rx_page_failed),\n };\ndiff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c\nindex 8b04769..ac71ba2 100644\n--- a/drivers/net/ethernet/intel/i40e/i40e_main.c\n+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c\n@@ -819,6 +819,7 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi)\n \tstruct i40e_eth_stats *oes;\n \tstruct i40e_eth_stats *es; /* device's eth stats */\n \tu32 tx_restart, tx_busy;\n+\tu64 tx_lost_interrupt;\n \tstruct i40e_ring *p;\n \tu32 rx_page, rx_buf;\n \tu64 bytes, packets;\n@@ -844,6 +845,7 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi)\n \trx_b = rx_p = 0;\n \ttx_b = tx_p = 0;\n \ttx_restart = tx_busy = tx_linearize = tx_force_wb = 0;\n+\ttx_lost_interrupt = 0;\n \trx_page = 0;\n \trx_buf = 0;\n \trcu_read_lock();\n@@ -862,6 +864,7 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi)\n \t\ttx_busy += p->tx_stats.tx_busy;\n \t\ttx_linearize += p->tx_stats.tx_linearize;\n \t\ttx_force_wb += p->tx_stats.tx_force_wb;\n+\t\ttx_lost_interrupt += p->tx_stats.tx_lost_interrupt;\n \n \t\t/* Rx queue is part of the same block as Tx queue */\n \t\tp = &p[1];\n@@ -880,6 +883,7 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi)\n \tvsi->tx_busy = tx_busy;\n \tvsi->tx_linearize = tx_linearize;\n \tvsi->tx_force_wb = tx_force_wb;\n+\tvsi->tx_lost_interrupt = tx_lost_interrupt;\n \tvsi->rx_page_failed = rx_page;\n \tvsi->rx_buf_failed = rx_buf;\n \n@@ -4349,7 +4353,7 @@ static void i40e_detect_recover_hung_queue(int q_idx, struct i40e_vsi *vsi)\n {\n \tstruct i40e_ring *tx_ring = NULL;\n \tstruct i40e_pf\t*pf;\n-\tu32 head, val, tx_pending;\n+\tu32 head, val, tx_pending_hw;\n \tint i;\n \n \tpf = vsi->back;\n@@ -4375,16 +4379,9 @@ static void i40e_detect_recover_hung_queue(int q_idx, struct i40e_vsi *vsi)\n \telse\n \t\tval = rd32(&pf->hw, I40E_PFINT_DYN_CTL0);\n \n-\t/* Bail out if interrupts are disabled because napi_poll\n-\t * execution in-progress or will get scheduled soon.\n-\t * napi_poll cleans TX and RX queues and updates 'next_to_clean'.\n-\t */\n-\tif (!(val & I40E_PFINT_DYN_CTLN_INTENA_MASK))\n-\t\treturn;\n-\n \thead = i40e_get_head(tx_ring);\n \n-\ttx_pending = i40e_get_tx_pending(tx_ring);\n+\ttx_pending_hw = i40e_get_tx_pending(tx_ring, false);\n \n \t/* HW is done executing descriptors, updated HEAD write back,\n \t * but SW hasn't processed those descriptors. If interrupt is\n@@ -4392,12 +4389,12 @@ static void i40e_detect_recover_hung_queue(int q_idx, struct i40e_vsi *vsi)\n \t * dev_watchdog detecting timeout on those netdev_queue,\n \t * hence proactively trigger SW interrupt.\n \t */\n-\tif (tx_pending) {\n+\tif (tx_pending_hw && (!(val & I40E_PFINT_DYN_CTLN_INTENA_MASK))) {\n \t\t/* NAPI Poll didn't run and clear since it was set */\n \t\tif (test_and_clear_bit(I40E_Q_VECTOR_HUNG_DETECT,\n \t\t\t\t &tx_ring->q_vector->hung_detected)) {\n-\t\t\tnetdev_info(vsi->netdev, \"VSI_seid %d, Hung TX queue %d, tx_pending: %d, NTC:0x%x, HWB: 0x%x, NTU: 0x%x, TAIL: 0x%x\\n\",\n-\t\t\t\t vsi->seid, q_idx, tx_pending,\n+\t\t\tnetdev_info(vsi->netdev, \"VSI_seid %d, Hung TX queue %d, tx_pending_hw: %d, NTC:0x%x, HWB: 0x%x, NTU: 0x%x, TAIL: 0x%x\\n\",\n+\t\t\t\t vsi->seid, q_idx, tx_pending_hw,\n \t\t\t\t tx_ring->next_to_clean, head,\n \t\t\t\t tx_ring->next_to_use,\n \t\t\t\t readl(tx_ring->tail));\n@@ -4410,6 +4407,17 @@ static void i40e_detect_recover_hung_queue(int q_idx, struct i40e_vsi *vsi)\n \t\t\t\t&tx_ring->q_vector->hung_detected);\n \t\t}\n \t}\n+\n+\t/* This is the case where we have interrupts missing,\n+\t * so the tx_pending in HW will most likely be 0, but we\n+\t * will have tx_pending in sw since the WB happened but the\n+\t * interrupt got lost.\n+\t */\n+\tif ((!tx_pending_hw) && i40e_get_tx_pending(tx_ring, true) &&\n+\t (!(val & I40E_PFINT_DYN_CTLN_INTENA_MASK))) {\n+\t\tif (napi_reschedule(&tx_ring->q_vector->napi))\n+\t\t\ttx_ring->tx_stats.tx_lost_interrupt++;\n+\t}\n }\n \n /**\ndiff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c\nindex 37104bf..60e993e 100644\n--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c\n+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c\n@@ -610,15 +610,19 @@ void i40e_free_tx_resources(struct i40e_ring *tx_ring)\n /**\n * i40e_get_tx_pending - how many tx descriptors not processed\n * @tx_ring: the ring of descriptors\n+ * @in_sw: is tx_pending being checked in SW or HW\n *\n * Since there is no access to the ring head register\n * in XL710, we need to use our local copies\n **/\n-u32 i40e_get_tx_pending(struct i40e_ring *ring)\n+u32 i40e_get_tx_pending(struct i40e_ring *ring, bool in_sw)\n {\n \tu32 head, tail;\n \n-\thead = i40e_get_head(ring);\n+\tif (!in_sw)\n+\t\thead = i40e_get_head(ring);\n+\telse\n+\t\thead = ring->next_to_clean;\n \ttail = readl(ring->tail);\n \n \tif (head != tail)\n@@ -741,7 +745,7 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget)\n \t\t * them to be written back in case we stay in NAPI.\n \t\t * In this mode on X722 we do not enable Interrupt.\n \t\t */\n-\t\tj = i40e_get_tx_pending(tx_ring);\n+\t\tj = i40e_get_tx_pending(tx_ring, false);\n \n \t\tif (budget &&\n \t\t ((j / (WB_STRIDE + 1)) == 0) && (j != 0) &&\ndiff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h\nindex fd72182..45496df 100644\n--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h\n+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h\n@@ -203,6 +203,7 @@ struct i40e_tx_queue_stats {\n \tu64 tx_done_old;\n \tu64 tx_linearize;\n \tu64 tx_force_wb;\n+\tu64 tx_lost_interrupt;\n };\n \n struct i40e_rx_queue_stats {\n@@ -338,7 +339,7 @@ int i40e_tx_prepare_vlan_flags(struct sk_buff *skb,\n \t\t\t struct i40e_ring *tx_ring, u32 *flags);\n #endif\n void i40e_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector);\n-u32 i40e_get_tx_pending(struct i40e_ring *ring);\n+u32 i40e_get_tx_pending(struct i40e_ring *ring, bool in_sw);\n \n /**\n * i40e_get_head - Retrieve head from head writeback\ndiff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c\nindex 620cb97..c1ea819 100644\n--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c\n+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c\n@@ -129,15 +129,19 @@ void i40evf_free_tx_resources(struct i40e_ring *tx_ring)\n /**\n * i40evf_get_tx_pending - how many Tx descriptors not processed\n * @tx_ring: the ring of descriptors\n+ * @in_sw: is tx_pending being checked in SW or HW\n *\n * Since there is no access to the ring head register\n * in XL710, we need to use our local copies\n **/\n-u32 i40evf_get_tx_pending(struct i40e_ring *ring)\n+u32 i40evf_get_tx_pending(struct i40e_ring *ring, bool in_sw)\n {\n \tu32 head, tail;\n \n-\thead = i40e_get_head(ring);\n+\tif (!in_sw)\n+\t\thead = i40e_get_head(ring);\n+\telse\n+\t\thead = ring->next_to_clean;\n \ttail = readl(ring->tail);\n \n \tif (head != tail)\n@@ -259,7 +263,7 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget)\n \t\t * them to be written back in case we stay in NAPI.\n \t\t * In this mode on X722 we do not enable Interrupt.\n \t\t */\n-\t\tj = i40evf_get_tx_pending(tx_ring);\n+\t\tj = i40evf_get_tx_pending(tx_ring, false);\n \n \t\tif (budget &&\n \t\t ((j / (WB_STRIDE + 1)) == 0) && (j > 0) &&\ndiff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.h b/drivers/net/ethernet/intel/i40evf/i40e_txrx.h\nindex 062bd0c..bbd98b7 100644\n--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.h\n+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.h\n@@ -202,6 +202,7 @@ struct i40e_tx_queue_stats {\n \tu64 tx_done_old;\n \tu64 tx_linearize;\n \tu64 tx_force_wb;\n+\tu64 tx_lost_interrupt;\n };\n \n struct i40e_rx_queue_stats {\n@@ -326,7 +327,7 @@ void i40evf_free_tx_resources(struct i40e_ring *tx_ring);\n void i40evf_free_rx_resources(struct i40e_ring *rx_ring);\n int i40evf_napi_poll(struct napi_struct *napi, int budget);\n void i40evf_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector);\n-u32 i40evf_get_tx_pending(struct i40e_ring *ring);\n+u32 i40evf_get_tx_pending(struct i40e_ring *ring, bool in_sw);\n \n /**\n * i40e_get_head - Retrieve head from head writeback\n", "prefixes": [ "next", "S28", "05/15" ] }