Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/566207/?format=api
{ "id": 566207, "url": "http://patchwork.ozlabs.org/api/patches/566207/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/1452554307-20937-10-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": "<1452554307-20937-10-git-send-email-joshua.a.hay@intel.com>", "list_archive_url": null, "date": "2016-01-11T23:18:21", "name": "[next,S27,09/15] i40e/i40evf: try again after failure", "commit_ref": null, "pull_url": null, "state": "changes-requested", "archived": false, "hash": "b72fd78cdd78a36d59c06fba08699bf6b72574a0", "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/1452554307-20937-10-git-send-email-joshua.a.hay@intel.com/mbox/", "series": [], "comments": "http://patchwork.ozlabs.org/api/patches/566207/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/566207/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\tby ozlabs.org (Postfix) with ESMTP id 30E2F140291\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue, 12 Jan 2016 10:18:38 +1100 (AEDT)", "from localhost (localhost [127.0.0.1])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id 807C489FA3;\n\tMon, 11 Jan 2016 23:18:37 +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 JGf97d7O7qwF; Mon, 11 Jan 2016 23:18:36 +0000 (UTC)", "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id 46CA389FFE;\n\tMon, 11 Jan 2016 23:18:35 +0000 (UTC)", "from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138])\n\tby ash.osuosl.org (Postfix) with ESMTP id 5D9101C102A\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 11 Jan 2016 23:18:33 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id A63DF8AA15\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 11 Jan 2016 23:18:32 +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 Bh0Abayu2d0t for <intel-wired-lan@lists.osuosl.org>;\n\tMon, 11 Jan 2016 23:18:31 +0000 (UTC)", "from mga03.intel.com (mga03.intel.com [134.134.136.65])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id 9E6648AB02\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 11 Jan 2016 23:18:29 +0000 (UTC)", "from orsmga002.jf.intel.com ([10.7.209.21])\n\tby orsmga103.jf.intel.com with ESMTP; 11 Jan 2016 15:18:30 -0800", "from jahay1-mobl2.amr.corp.intel.com (HELO\n\tlocalhost.localdomain.localdomain) ([134.134.176.82])\n\tby orsmga002.jf.intel.com with ESMTP; 11 Jan 2016 15:18:30 -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.20,555,1444719600\"; d=\"scan'208\";a=\"888496218\"", "From": "Joshua Hay <joshua.a.hay@intel.com>", "To": "intel-wired-lan@lists.osuosl.org", "Date": "Mon, 11 Jan 2016 15:18:21 -0800", "Message-Id": "<1452554307-20937-10-git-send-email-joshua.a.hay@intel.com>", "X-Mailer": "git-send-email 2.1.0", "In-Reply-To": "<1452554307-20937-1-git-send-email-joshua.a.hay@intel.com>", "References": "<1452554307-20937-1-git-send-email-joshua.a.hay@intel.com>", "Subject": "[Intel-wired-lan] [next PATCH S27 09/15] i40e/i40evf: try again\n\tafter failure", "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: Jesse Brandeburg <jesse.brandeburg@intel.com>\n\nThis is the \"Don't Give Up\" patch. Previously the\ndriver could fail an allocation, and then possibly stall\na queue forever, by never coming back to continue receiving\nor allocating buffers.\n\nWith this patch, the driver will keep polling trying to allocate\nreceive buffers until it succeeds. This should keep all receive\nqueues running even in the face of memory pressure.\n\nAlso update copyright year in file header.\n\nSigned-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>\nChange-ID: I2b103d1ce95b9831288a7222c3343ffa1988b81b\n---\nTesting Hints: Load RHEL 7.1 -229 default kernel with firewall\nenabled, and receive more packets per second than the kernel\ncan handle (indicating drops) and observe that kernel\nstarts printing OOM errors. After OOM errors, stop incoming\ntraffic and make sure all rx queues are still active/working.\n\n drivers/net/ethernet/intel/i40e/i40e_txrx.c | 51 ++++++++++++++++++++++-----\n drivers/net/ethernet/intel/i40e/i40e_txrx.h | 6 ++--\n drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 51 ++++++++++++++++++++++-----\n drivers/net/ethernet/intel/i40evf/i40e_txrx.h | 4 +--\n 4 files changed, 89 insertions(+), 23 deletions(-)", "diff": "diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c\nindex c2f0b7c..cbedc2b 100644\n--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c\n+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c\n@@ -1195,8 +1195,10 @@ static inline void i40e_release_rx_desc(struct i40e_ring *rx_ring, u32 val)\n * i40e_alloc_rx_buffers_ps - Replace used receive buffers; packet split\n * @rx_ring: ring to place buffers on\n * @cleaned_count: number of buffers to replace\n+ *\n+ * Returns true if any errors on allocation\n **/\n-void i40e_alloc_rx_buffers_ps(struct i40e_ring *rx_ring, u16 cleaned_count)\n+bool i40e_alloc_rx_buffers_ps(struct i40e_ring *rx_ring, u16 cleaned_count)\n {\n \tu16 i = rx_ring->next_to_use;\n \tunion i40e_rx_desc *rx_desc;\n@@ -1204,7 +1206,7 @@ void i40e_alloc_rx_buffers_ps(struct i40e_ring *rx_ring, u16 cleaned_count)\n \n \t/* do nothing if no valid netdev defined */\n \tif (!rx_ring->netdev || !cleaned_count)\n-\t\treturn;\n+\t\treturn false;\n \n \twhile (cleaned_count--) {\n \t\trx_desc = I40E_RX_DESC(rx_ring, i);\n@@ -1251,17 +1253,29 @@ void i40e_alloc_rx_buffers_ps(struct i40e_ring *rx_ring, u16 cleaned_count)\n \t\t\ti = 0;\n \t}\n \n+\tif (rx_ring->next_to_use != i)\n+\t\ti40e_release_rx_desc(rx_ring, i);\n+\n+\treturn false;\n+\n no_buffers:\n \tif (rx_ring->next_to_use != i)\n \t\ti40e_release_rx_desc(rx_ring, i);\n+\n+\t/* make sure to come back via polling to try again after\n+\t * allocation failure\n+\t */\n+\treturn true;\n }\n \n /**\n * i40e_alloc_rx_buffers_1buf - Replace used receive buffers; single buffer\n * @rx_ring: ring to place buffers on\n * @cleaned_count: number of buffers to replace\n+ *\n+ * Returns true if any errors on allocation\n **/\n-void i40e_alloc_rx_buffers_1buf(struct i40e_ring *rx_ring, u16 cleaned_count)\n+bool i40e_alloc_rx_buffers_1buf(struct i40e_ring *rx_ring, u16 cleaned_count)\n {\n \tu16 i = rx_ring->next_to_use;\n \tunion i40e_rx_desc *rx_desc;\n@@ -1270,7 +1284,7 @@ void i40e_alloc_rx_buffers_1buf(struct i40e_ring *rx_ring, u16 cleaned_count)\n \n \t/* do nothing if no valid netdev defined */\n \tif (!rx_ring->netdev || !cleaned_count)\n-\t\treturn;\n+\t\treturn false;\n \n \twhile (cleaned_count--) {\n \t\trx_desc = I40E_RX_DESC(rx_ring, i);\n@@ -1297,6 +1311,8 @@ void i40e_alloc_rx_buffers_1buf(struct i40e_ring *rx_ring, u16 cleaned_count)\n \t\t\tif (dma_mapping_error(rx_ring->dev, bi->dma)) {\n \t\t\t\trx_ring->rx_stats.alloc_buff_failed++;\n \t\t\t\tbi->dma = 0;\n+\t\t\t\tdev_kfree_skb(bi->skb);\n+\t\t\t\tbi->skb = NULL;\n \t\t\t\tgoto no_buffers;\n \t\t\t}\n \t\t}\n@@ -1308,9 +1324,19 @@ void i40e_alloc_rx_buffers_1buf(struct i40e_ring *rx_ring, u16 cleaned_count)\n \t\t\ti = 0;\n \t}\n \n+\tif (rx_ring->next_to_use != i)\n+\t\ti40e_release_rx_desc(rx_ring, i);\n+\n+\treturn false;\n+\n no_buffers:\n \tif (rx_ring->next_to_use != i)\n \t\ti40e_release_rx_desc(rx_ring, i);\n+\n+\t/* make sure to come back via polling to try again after\n+\t * allocation failure\n+\t */\n+\treturn true;\n }\n \n /**\n@@ -1494,7 +1520,7 @@ static inline void i40e_rx_hash(struct i40e_ring *ring,\n *\n * Returns true if there's any budget left (e.g. the clean is finished)\n **/\n-static int i40e_clean_rx_irq_ps(struct i40e_ring *rx_ring, int budget)\n+static int i40e_clean_rx_irq_ps(struct i40e_ring *rx_ring, const int budget)\n {\n \tunsigned int total_rx_bytes = 0, total_rx_packets = 0;\n \tu16 rx_packet_len, rx_header_len, rx_sph, rx_hbo;\n@@ -1504,6 +1530,7 @@ static int i40e_clean_rx_irq_ps(struct i40e_ring *rx_ring, int budget)\n \tu16 i = rx_ring->next_to_clean;\n \tunion i40e_rx_desc *rx_desc;\n \tu32 rx_error, rx_status;\n+\tbool failure = false;\n \tu8 rx_ptype;\n \tu64 qword;\n \n@@ -1516,7 +1543,9 @@ static int i40e_clean_rx_irq_ps(struct i40e_ring *rx_ring, int budget)\n \t\tu16 vlan_tag;\n \t\t/* return some buffers to hardware, one at a time is too slow */\n \t\tif (cleaned_count >= I40E_RX_BUFFER_WRITE) {\n-\t\t\ti40e_alloc_rx_buffers_ps(rx_ring, cleaned_count);\n+\t\t\tfailure = failure ||\n+\t\t\t\t i40e_alloc_rx_buffers_ps(rx_ring,\n+\t\t\t\t\t\t\t cleaned_count);\n \t\t\tcleaned_count = 0;\n \t\t}\n \n@@ -1546,6 +1575,7 @@ static int i40e_clean_rx_irq_ps(struct i40e_ring *rx_ring, int budget)\n \t\t\t\t\t\t\trx_ring->rx_hdr_len);\n \t\t\tif (!skb) {\n \t\t\t\trx_ring->rx_stats.alloc_buff_failed++;\n+\t\t\t\tfailure = true;\n \t\t\t\tbreak;\n \t\t\t}\n \n@@ -1675,7 +1705,7 @@ static int i40e_clean_rx_irq_ps(struct i40e_ring *rx_ring, int budget)\n \trx_ring->q_vector->rx.total_packets += total_rx_packets;\n \trx_ring->q_vector->rx.total_bytes += total_rx_bytes;\n \n-\treturn total_rx_packets;\n+\treturn failure ? budget : total_rx_packets;\n }\n \n /**\n@@ -1693,6 +1723,7 @@ static int i40e_clean_rx_irq_1buf(struct i40e_ring *rx_ring, int budget)\n \tunion i40e_rx_desc *rx_desc;\n \tu32 rx_error, rx_status;\n \tu16 rx_packet_len;\n+\tbool failure = false;\n \tu8 rx_ptype;\n \tu64 qword;\n \tu16 i;\n@@ -1703,7 +1734,9 @@ static int i40e_clean_rx_irq_1buf(struct i40e_ring *rx_ring, int budget)\n \t\tu16 vlan_tag;\n \t\t/* return some buffers to hardware, one at a time is too slow */\n \t\tif (cleaned_count >= I40E_RX_BUFFER_WRITE) {\n-\t\t\ti40e_alloc_rx_buffers_1buf(rx_ring, cleaned_count);\n+\t\t\tfailure = failure ||\n+\t\t\t\t i40e_alloc_rx_buffers_1buf(rx_ring,\n+\t\t\t\t\t\t\t cleaned_count);\n \t\t\tcleaned_count = 0;\n \t\t}\n \n@@ -1802,7 +1835,7 @@ static int i40e_clean_rx_irq_1buf(struct i40e_ring *rx_ring, int budget)\n \trx_ring->q_vector->rx.total_packets += total_rx_packets;\n \trx_ring->q_vector->rx.total_bytes += total_rx_bytes;\n \n-\treturn total_rx_packets;\n+\treturn failure ? budget : total_rx_packets;\n }\n \n static u32 i40e_buildreg_itr(const int type, const u16 itr)\ndiff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h\nindex 1d167b6..2e52889 100644\n--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h\n+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h\n@@ -1,7 +1,7 @@\n /*******************************************************************************\n *\n * Intel Ethernet Controller XL710 Family Linux Driver\n- * Copyright(c) 2013 - 2014 Intel Corporation.\n+ * Copyright(c) 2013 - 2016 Intel Corporation.\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n@@ -316,8 +316,8 @@ struct i40e_ring_container {\n #define i40e_for_each_ring(pos, head) \\\n \tfor (pos = (head).ring; pos != NULL; pos = pos->next)\n \n-void i40e_alloc_rx_buffers_ps(struct i40e_ring *rxr, u16 cleaned_count);\n-void i40e_alloc_rx_buffers_1buf(struct i40e_ring *rxr, u16 cleaned_count);\n+bool i40e_alloc_rx_buffers_ps(struct i40e_ring *rxr, u16 cleaned_count);\n+bool i40e_alloc_rx_buffers_1buf(struct i40e_ring *rxr, u16 cleaned_count);\n void i40e_alloc_rx_headers(struct i40e_ring *rxr);\n netdev_tx_t i40e_lan_xmit_frame(struct sk_buff *skb, struct net_device *netdev);\n void i40e_clean_tx_ring(struct i40e_ring *tx_ring);\ndiff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c\nindex 155f2c1..0f9442e 100644\n--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c\n+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c\n@@ -667,8 +667,10 @@ static inline void i40e_release_rx_desc(struct i40e_ring *rx_ring, u32 val)\n * i40evf_alloc_rx_buffers_ps - Replace used receive buffers; packet split\n * @rx_ring: ring to place buffers on\n * @cleaned_count: number of buffers to replace\n+ *\n+ * Returns true if any errors on allocation\n **/\n-void i40evf_alloc_rx_buffers_ps(struct i40e_ring *rx_ring, u16 cleaned_count)\n+bool i40evf_alloc_rx_buffers_ps(struct i40e_ring *rx_ring, u16 cleaned_count)\n {\n \tu16 i = rx_ring->next_to_use;\n \tunion i40e_rx_desc *rx_desc;\n@@ -676,7 +678,7 @@ void i40evf_alloc_rx_buffers_ps(struct i40e_ring *rx_ring, u16 cleaned_count)\n \n \t/* do nothing if no valid netdev defined */\n \tif (!rx_ring->netdev || !cleaned_count)\n-\t\treturn;\n+\t\treturn false;\n \n \twhile (cleaned_count--) {\n \t\trx_desc = I40E_RX_DESC(rx_ring, i);\n@@ -723,17 +725,29 @@ void i40evf_alloc_rx_buffers_ps(struct i40e_ring *rx_ring, u16 cleaned_count)\n \t\t\ti = 0;\n \t}\n \n+\tif (rx_ring->next_to_use != i)\n+\t\ti40e_release_rx_desc(rx_ring, i);\n+\n+\treturn false;\n+\n no_buffers:\n \tif (rx_ring->next_to_use != i)\n \t\ti40e_release_rx_desc(rx_ring, i);\n+\n+\t/* make sure to come back via polling to try again after\n+\t * allocation failure\n+\t */\n+\treturn true;\n }\n \n /**\n * i40evf_alloc_rx_buffers_1buf - Replace used receive buffers; single buffer\n * @rx_ring: ring to place buffers on\n * @cleaned_count: number of buffers to replace\n+ *\n+ * Returns true if any errors on allocation\n **/\n-void i40evf_alloc_rx_buffers_1buf(struct i40e_ring *rx_ring, u16 cleaned_count)\n+bool i40evf_alloc_rx_buffers_1buf(struct i40e_ring *rx_ring, u16 cleaned_count)\n {\n \tu16 i = rx_ring->next_to_use;\n \tunion i40e_rx_desc *rx_desc;\n@@ -742,7 +756,7 @@ void i40evf_alloc_rx_buffers_1buf(struct i40e_ring *rx_ring, u16 cleaned_count)\n \n \t/* do nothing if no valid netdev defined */\n \tif (!rx_ring->netdev || !cleaned_count)\n-\t\treturn;\n+\t\treturn false;\n \n \twhile (cleaned_count--) {\n \t\trx_desc = I40E_RX_DESC(rx_ring, i);\n@@ -769,6 +783,8 @@ void i40evf_alloc_rx_buffers_1buf(struct i40e_ring *rx_ring, u16 cleaned_count)\n \t\t\tif (dma_mapping_error(rx_ring->dev, bi->dma)) {\n \t\t\t\trx_ring->rx_stats.alloc_buff_failed++;\n \t\t\t\tbi->dma = 0;\n+\t\t\t\tdev_kfree_skb(bi->skb);\n+\t\t\t\tbi->skb = NULL;\n \t\t\t\tgoto no_buffers;\n \t\t\t}\n \t\t}\n@@ -780,9 +796,19 @@ void i40evf_alloc_rx_buffers_1buf(struct i40e_ring *rx_ring, u16 cleaned_count)\n \t\t\ti = 0;\n \t}\n \n+\tif (rx_ring->next_to_use != i)\n+\t\ti40e_release_rx_desc(rx_ring, i);\n+\n+\treturn false;\n+\n no_buffers:\n \tif (rx_ring->next_to_use != i)\n \t\ti40e_release_rx_desc(rx_ring, i);\n+\n+\t/* make sure to come back via polling to try again after\n+\t * allocation failure\n+\t */\n+\treturn true;\n }\n \n /**\n@@ -965,7 +991,7 @@ static inline void i40e_rx_hash(struct i40e_ring *ring,\n *\n * Returns true if there's any budget left (e.g. the clean is finished)\n **/\n-static int i40e_clean_rx_irq_ps(struct i40e_ring *rx_ring, int budget)\n+static int i40e_clean_rx_irq_ps(struct i40e_ring *rx_ring, const int budget)\n {\n \tunsigned int total_rx_bytes = 0, total_rx_packets = 0;\n \tu16 rx_packet_len, rx_header_len, rx_sph, rx_hbo;\n@@ -975,6 +1001,7 @@ static int i40e_clean_rx_irq_ps(struct i40e_ring *rx_ring, int budget)\n \tu16 i = rx_ring->next_to_clean;\n \tunion i40e_rx_desc *rx_desc;\n \tu32 rx_error, rx_status;\n+\tbool failure = false;\n \tu8 rx_ptype;\n \tu64 qword;\n \n@@ -984,7 +1011,9 @@ static int i40e_clean_rx_irq_ps(struct i40e_ring *rx_ring, int budget)\n \t\tu16 vlan_tag;\n \t\t/* return some buffers to hardware, one at a time is too slow */\n \t\tif (cleaned_count >= I40E_RX_BUFFER_WRITE) {\n-\t\t\ti40evf_alloc_rx_buffers_ps(rx_ring, cleaned_count);\n+\t\t\tfailure = failure ||\n+\t\t\t\t i40evf_alloc_rx_buffers_ps(rx_ring,\n+\t\t\t\t\t\t\t cleaned_count);\n \t\t\tcleaned_count = 0;\n \t\t}\n \n@@ -1009,6 +1038,7 @@ static int i40e_clean_rx_irq_ps(struct i40e_ring *rx_ring, int budget)\n \t\t\t\t\t\t\trx_ring->rx_hdr_len);\n \t\t\tif (!skb) {\n \t\t\t\trx_ring->rx_stats.alloc_buff_failed++;\n+\t\t\t\tfailure = true;\n \t\t\t\tbreak;\n \t\t\t}\n \n@@ -1131,7 +1161,7 @@ static int i40e_clean_rx_irq_ps(struct i40e_ring *rx_ring, int budget)\n \trx_ring->q_vector->rx.total_packets += total_rx_packets;\n \trx_ring->q_vector->rx.total_bytes += total_rx_bytes;\n \n-\treturn total_rx_packets;\n+\treturn failure ? budget : total_rx_packets;\n }\n \n /**\n@@ -1149,6 +1179,7 @@ static int i40e_clean_rx_irq_1buf(struct i40e_ring *rx_ring, int budget)\n \tunion i40e_rx_desc *rx_desc;\n \tu32 rx_error, rx_status;\n \tu16 rx_packet_len;\n+\tbool failure = false;\n \tu8 rx_ptype;\n \tu64 qword;\n \tu16 i;\n@@ -1159,7 +1190,9 @@ static int i40e_clean_rx_irq_1buf(struct i40e_ring *rx_ring, int budget)\n \t\tu16 vlan_tag;\n \t\t/* return some buffers to hardware, one at a time is too slow */\n \t\tif (cleaned_count >= I40E_RX_BUFFER_WRITE) {\n-\t\t\ti40evf_alloc_rx_buffers_1buf(rx_ring, cleaned_count);\n+\t\t\tfailure = failure ||\n+\t\t\t\t i40evf_alloc_rx_buffers_1buf(rx_ring,\n+\t\t\t\t\t\t\t cleaned_count);\n \t\t\tcleaned_count = 0;\n \t\t}\n \n@@ -1240,7 +1273,7 @@ static int i40e_clean_rx_irq_1buf(struct i40e_ring *rx_ring, int budget)\n \trx_ring->q_vector->rx.total_packets += total_rx_packets;\n \trx_ring->q_vector->rx.total_bytes += total_rx_bytes;\n \n-\treturn total_rx_packets;\n+\treturn failure ? budget : total_rx_packets;\n }\n \n static u32 i40e_buildreg_itr(const int type, const u16 itr)\ndiff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.h b/drivers/net/ethernet/intel/i40evf/i40e_txrx.h\nindex a565e6f..1438017 100644\n--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.h\n+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.h\n@@ -313,8 +313,8 @@ struct i40e_ring_container {\n #define i40e_for_each_ring(pos, head) \\\n \tfor (pos = (head).ring; pos != NULL; pos = pos->next)\n \n-void i40evf_alloc_rx_buffers_ps(struct i40e_ring *rxr, u16 cleaned_count);\n-void i40evf_alloc_rx_buffers_1buf(struct i40e_ring *rxr, u16 cleaned_count);\n+bool i40evf_alloc_rx_buffers_ps(struct i40e_ring *rxr, u16 cleaned_count);\n+bool i40evf_alloc_rx_buffers_1buf(struct i40e_ring *rxr, u16 cleaned_count);\n void i40evf_alloc_rx_headers(struct i40e_ring *rxr);\n netdev_tx_t i40evf_xmit_frame(struct sk_buff *skb, struct net_device *netdev);\n void i40evf_clean_tx_ring(struct i40e_ring *tx_ring);\n", "prefixes": [ "next", "S27", "09/15" ] }