Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/567223/?format=api
{ "id": 567223, "url": "http://patchwork.ozlabs.org/api/patches/567223/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/1452732712-12248-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": "<1452732712-12248-10-git-send-email-joshua.a.hay@intel.com>", "list_archive_url": null, "date": "2016-01-14T00:51:46", "name": "[v2,next,S27,09/15] i40e/i40evf: try again after failure", "commit_ref": null, "pull_url": null, "state": "accepted", "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/1452732712-12248-10-git-send-email-joshua.a.hay@intel.com/mbox/", "series": [], "comments": "http://patchwork.ozlabs.org/api/patches/567223/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/567223/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 00521140662\n\tfor <incoming@patchwork.ozlabs.org>;\n\tThu, 14 Jan 2016 11:52:08 +1100 (AEDT)", "from localhost (localhost [127.0.0.1])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id 4D391A592C;\n\tThu, 14 Jan 2016 00:52:08 +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 ey1kiW4d1KoA; Thu, 14 Jan 2016 00:52:06 +0000 (UTC)", "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id 175FEA5963;\n\tThu, 14 Jan 2016 00:52:02 +0000 (UTC)", "from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133])\n\tby ash.osuosl.org (Postfix) with ESMTP id 1B1F61C0F4A\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 14 Jan 2016 00:51:57 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n\tby hemlock.osuosl.org (Postfix) with ESMTP id 1712F8A7BC\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 14 Jan 2016 00:51:57 +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 PziRdCzALEsx for <intel-wired-lan@lists.osuosl.org>;\n\tThu, 14 Jan 2016 00:51:53 +0000 (UTC)", "from mga03.intel.com (mga03.intel.com [134.134.136.65])\n\tby hemlock.osuosl.org (Postfix) with ESMTP id 5FE1C89461\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 14 Jan 2016 00:51:53 +0000 (UTC)", "from orsmga002.jf.intel.com ([10.7.209.21])\n\tby orsmga103.jf.intel.com with ESMTP; 13 Jan 2016 16:51:52 -0800", "from jahay1-mobl2.amr.corp.intel.com (HELO\n\tlocalhost.localdomain.localdomain) ([134.134.176.160])\n\tby orsmga002.jf.intel.com with ESMTP; 13 Jan 2016 16:51:52 -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,291,1449561600\"; d=\"scan'208\";a=\"890056924\"", "From": "Joshua Hay <joshua.a.hay@intel.com>", "To": "intel-wired-lan@lists.osuosl.org", "Date": "Wed, 13 Jan 2016 16:51:46 -0800", "Message-Id": "<1452732712-12248-10-git-send-email-joshua.a.hay@intel.com>", "X-Mailer": "git-send-email 2.1.0", "In-Reply-To": "<1452732712-12248-1-git-send-email-joshua.a.hay@intel.com>", "References": "<1452732712-12248-1-git-send-email-joshua.a.hay@intel.com>", "Subject": "[Intel-wired-lan] [v2 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 d4e149b..692e723 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": [ "v2", "next", "S27", "09/15" ] }