Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2205086/?format=api
{ "id": 2205086, "url": "http://patchwork.ozlabs.org/api/patches/2205086/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20260304160345.1340940-4-larysa.zaremba@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": "<20260304160345.1340940-4-larysa.zaremba@intel.com>", "list_archive_url": null, "date": "2026-03-04T16:03:35", "name": "[iwl-next,v3,03/10] ixgbevf: use libeth in Rx processing", "commit_ref": null, "pull_url": null, "state": "changes-requested", "archived": false, "hash": "e619fc4282634390e30a8d63ff77e6daa885d2a9", "submitter": { "id": 84900, "url": "http://patchwork.ozlabs.org/api/people/84900/?format=api", "name": "Larysa Zaremba", "email": "larysa.zaremba@intel.com" }, "delegate": { "id": 109701, "url": "http://patchwork.ozlabs.org/api/users/109701/?format=api", "username": "anguy11", "first_name": "Anthony", "last_name": "Nguyen", "email": "anthony.l.nguyen@intel.com" }, "mbox": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20260304160345.1340940-4-larysa.zaremba@intel.com/mbox/", "series": [ { "id": 494412, "url": "http://patchwork.ozlabs.org/api/series/494412/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=494412", "date": "2026-03-04T16:03:32", "name": "libeth and full XDP for ixgbevf", "version": 3, "mbox": "http://patchwork.ozlabs.org/series/494412/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2205086/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2205086/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<intel-wired-lan-bounces@osuosl.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Delivered-To": [ "patchwork-incoming@legolas.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=osuosl.org header.i=@osuosl.org header.a=rsa-sha256\n header.s=default header.b=1x49lssP;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=osuosl.org\n (client-ip=140.211.166.138; helo=smtp1.osuosl.org;\n envelope-from=intel-wired-lan-bounces@osuosl.org;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fQywW08Wtz1xws\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 05 Mar 2026 03:36:11 +1100 (AEDT)", "from localhost (localhost [127.0.0.1])\n\tby smtp1.osuosl.org (Postfix) with ESMTP id B96D581346;\n\tWed, 4 Mar 2026 16:36:07 +0000 (UTC)", "from smtp1.osuosl.org ([127.0.0.1])\n by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id LfARButinDC8; Wed, 4 Mar 2026 16:36:06 +0000 (UTC)", "from lists1.osuosl.org (lists1.osuosl.org [140.211.166.142])\n\tby smtp1.osuosl.org (Postfix) with ESMTP id 6E3B081339;\n\tWed, 4 Mar 2026 16:36:06 +0000 (UTC)", "from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136])\n by lists1.osuosl.org (Postfix) with ESMTP id F24761EB\n for <intel-wired-lan@lists.osuosl.org>; Wed, 4 Mar 2026 16:36:04 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n by smtp3.osuosl.org (Postfix) with ESMTP id E462960870\n for <intel-wired-lan@lists.osuosl.org>; Wed, 4 Mar 2026 16:36:04 +0000 (UTC)", "from smtp3.osuosl.org ([127.0.0.1])\n by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id D7J1eynfv8Mp for <intel-wired-lan@lists.osuosl.org>;\n Wed, 4 Mar 2026 16:36:03 +0000 (UTC)", "from mgamail.intel.com (mgamail.intel.com [192.198.163.12])\n by smtp3.osuosl.org (Postfix) with ESMTPS id BACFF6086D\n for <intel-wired-lan@lists.osuosl.org>; Wed, 4 Mar 2026 16:36:03 +0000 (UTC)", "from orviesa004.jf.intel.com ([10.64.159.144])\n by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 04 Mar 2026 08:36:03 -0800", "from irvmail002.ir.intel.com ([10.43.11.120])\n by orviesa004.jf.intel.com with ESMTP; 04 Mar 2026 08:35:57 -0800", "from lincoln.igk.intel.com (lincoln.igk.intel.com [10.102.21.235])\n by irvmail002.ir.intel.com (Postfix) with ESMTP id C7AE3312CA;\n Wed, 4 Mar 2026 16:35:55 +0000 (GMT)" ], "X-Virus-Scanned": [ "amavis at osuosl.org", "amavis at osuosl.org" ], "X-Comment": "SPF check N/A for local connections - client-ip=140.211.166.142;\n helo=lists1.osuosl.org; envelope-from=intel-wired-lan-bounces@osuosl.org;\n receiver=<UNKNOWN> ", "DKIM-Filter": [ "OpenDKIM Filter v2.11.0 smtp1.osuosl.org 6E3B081339", "OpenDKIM Filter v2.11.0 smtp3.osuosl.org BACFF6086D" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=osuosl.org;\n\ts=default; t=1772642166;\n\tbh=HHFY1YmBXBJB9aFb7UYdezTl1FusTPXFJlrw8k3MnFk=;\n\th=From:To:Cc:Date:In-Reply-To:References:Subject:List-Id:\n\t List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe:\n\t From;\n\tb=1x49lssPyuzJPtsFVRAovR1Z7uV0pzCvBbW5zFle6RkddJ5yVuyDEuX9gQyb7VGGc\n\t YL2V9FQiRWPKLR85F9eno0oTmgoHZfsUHO524rEONhnRM3xGMRAMD4ouBwiEi4J+0j\n\t 0h8h0KSArJJpL3AzODkhYa33C3RW83Npa6SH7BRbdf7rORXfm0e2sRflkoGG3LJOGN\n\t Wtk+dwZrE9fkK3a4r4BqWJv0ci0SAQ85sl7O4k65fe7PfrF9Jt7Ov+qbqA0WNqT5pH\n\t 9WGudKkQM8IKsIYN46CFIhbYtZZuisZ5em46p8YJPLyOAeLT0vNoPCwqb40RgIPjJz\n\t 8bebp/IS5CTjw==", "Received-SPF": "Pass (mailfrom) identity=mailfrom; client-ip=192.198.163.12;\n helo=mgamail.intel.com; envelope-from=larysa.zaremba@intel.com;\n receiver=<UNKNOWN>", "DMARC-Filter": "OpenDMARC Filter v1.4.2 smtp3.osuosl.org BACFF6086D", "X-CSE-ConnectionGUID": [ "GcLcx/+QQbKmxRyX3vKfWg==", "CzrczvLoTVG4MwFyK7iUKQ==" ], "X-CSE-MsgGUID": [ "sUyuEWDVQpC5UUdqdSEnlQ==", "wvDWb5MFSNSmpczv3biUgg==" ], "X-IronPort-AV": [ "E=McAfee;i=\"6800,10657,11719\"; a=\"77580037\"", "E=Sophos;i=\"6.21,324,1763452800\"; d=\"scan'208\";a=\"77580037\"", "E=Sophos;i=\"6.21,324,1763452800\"; d=\"scan'208\";a=\"222895569\"" ], "X-ExtLoop1": "1", "From": "Larysa Zaremba <larysa.zaremba@intel.com>", "To": "Tony Nguyen <anthony.l.nguyen@intel.com>, intel-wired-lan@lists.osuosl.org", "Cc": "Larysa Zaremba <larysa.zaremba@intel.com>,\n Przemek Kitszel <przemyslaw.kitszel@intel.com>,\n Andrew Lunn <andrew+netdev@lunn.ch>,\n \"David S. Miller\" <davem@davemloft.net>,\n Eric Dumazet <edumazet@google.com>, Jakub Kicinski <kuba@kernel.org>,\n Paolo Abeni <pabeni@redhat.com>,\n Alexander Lobakin <aleksander.lobakin@intel.com>,\n Simon Horman <horms@kernel.org>, Alexei Starovoitov <ast@kernel.org>,\n Daniel Borkmann <daniel@iogearbox.net>,\n Jesper Dangaard Brouer <hawk@kernel.org>,\n John Fastabend <john.fastabend@gmail.com>,\n Stanislav Fomichev <sdf@fomichev.me>,\n Aleksandr Loktionov <aleksandr.loktionov@intel.com>,\n Natalia Wochtman <natalia.wochtman@intel.com>, netdev@vger.kernel.org,\n linux-kernel@vger.kernel.org, bpf@vger.kernel.org", "Date": "Wed, 4 Mar 2026 17:03:35 +0100", "Message-ID": "<20260304160345.1340940-4-larysa.zaremba@intel.com>", "X-Mailer": "git-send-email 2.52.0", "In-Reply-To": "<20260304160345.1340940-1-larysa.zaremba@intel.com>", "References": "<20260304160345.1340940-1-larysa.zaremba@intel.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-Mailman-Original-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1772642164; x=1804178164;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=XmXgIlPS/QT1PKsgToHXtE34poJzGGSWVGBe5XGheoM=;\n b=QRcfkHw/YPhVhBI1IDBlaht03teS+EDARz+Uw5cejFyMfUGGnI0ZU5FL\n BikQk5gSEwHocjxhxIeXxZQcu+iflu/W6JONBjwgg+cfRhXOhAXrNrdra\n pLVZvAocU33R7402qTodkK6qBUnJ+mSn3PebNubZpiK9X43CPPCE3nFcj\n 2XPG1mSHclr/z5xEPj8eiZtiK5eLJ4b3RpDQDdajxs0O4WSQ+IwVhSPlM\n thkIQadOx6zYzjhL5XzzXRJ/0F0h3CqqSsaddcev+vki+ywL6rzX9ixcD\n gQoHQ4UI6oSMDZnyjXuV0bxdHw3+k6fRbEmBvofy2ItUyHp8DQ/B+fm6f\n Q==;", "X-Mailman-Original-Authentication-Results": [ "smtp3.osuosl.org;\n dmarc=pass (p=none dis=none)\n header.from=intel.com", "smtp3.osuosl.org;\n dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com\n header.a=rsa-sha256 header.s=Intel header.b=QRcfkHw/" ], "Subject": "[Intel-wired-lan] [PATCH iwl-next v3 03/10] ixgbevf: use libeth in\n Rx processing", "X-BeenThere": "intel-wired-lan@osuosl.org", "X-Mailman-Version": "2.1.30", "Precedence": "list", "List-Id": "Intel Wired Ethernet Linux Kernel Driver Development\n <intel-wired-lan.osuosl.org>", "List-Unsubscribe": "<https://lists.osuosl.org/mailman/options/intel-wired-lan>,\n <mailto:intel-wired-lan-request@osuosl.org?subject=unsubscribe>", "List-Archive": "<http://lists.osuosl.org/pipermail/intel-wired-lan/>", "List-Post": "<mailto:intel-wired-lan@osuosl.org>", "List-Help": "<mailto:intel-wired-lan-request@osuosl.org?subject=help>", "List-Subscribe": "<https://lists.osuosl.org/mailman/listinfo/intel-wired-lan>,\n <mailto:intel-wired-lan-request@osuosl.org?subject=subscribe>", "Errors-To": "intel-wired-lan-bounces@osuosl.org", "Sender": "\"Intel-wired-lan\" <intel-wired-lan-bounces@osuosl.org>" }, "content": "Use page_pool buffers by the means of libeth in the Rx queues, this\nsignificantly reduces code complexity of the driver itself.\n\nSuggested-by: Alexander Lobakin <aleksander.lobakin@intel.com>\nReviewed-by: Alexander Lobakin <aleksander.lobakin@intel.com>\nReviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>\nSigned-off-by: Larysa Zaremba <larysa.zaremba@intel.com>\n---\n drivers/net/ethernet/intel/Kconfig | 1 +\n drivers/net/ethernet/intel/ixgbevf/defines.h | 2 +-\n drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 21 +-\n .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 313 ++++++------------\n 4 files changed, 120 insertions(+), 217 deletions(-)", "diff": "diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig\nindex 780f113986ea..42637514e804 100644\n--- a/drivers/net/ethernet/intel/Kconfig\n+++ b/drivers/net/ethernet/intel/Kconfig\n@@ -203,6 +203,7 @@ config IXGBE_IPSEC\n config IXGBEVF\n \ttristate \"Intel(R) 10GbE PCI Express Virtual Function Ethernet support\"\n \tdepends on PCI_MSI\n+\tselect LIBETH_XDP\n \thelp\n \t This driver supports Intel(R) PCI Express virtual functions for the\n \t Intel(R) ixgbe driver. For more information on how to identify your\ndiff --git a/drivers/net/ethernet/intel/ixgbevf/defines.h b/drivers/net/ethernet/intel/ixgbevf/defines.h\nindex e177d1d58696..afc927dd1438 100644\n--- a/drivers/net/ethernet/intel/ixgbevf/defines.h\n+++ b/drivers/net/ethernet/intel/ixgbevf/defines.h\n@@ -71,7 +71,7 @@ typedef u32 ixgbe_link_speed;\n #define IXGBE_PSRTYPE_L2HDR\t0x00001000\n \n /* SRRCTL bit definitions */\n-#define IXGBE_SRRCTL_BSIZEPKT_SHIFT\t10 /* so many KBs */\n+#define IXGBE_SRRCTL_BSIZEPKT_STEP\t1024\n #define IXGBE_SRRCTL_RDMTS_SHIFT\t22\n #define IXGBE_SRRCTL_RDMTS_MASK\t\t0x01C00000\n #define IXGBE_SRRCTL_DROP_EN\t\t0x10000000\ndiff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h\nindex 2d7ca3f86868..ebf771f0caa4 100644\n--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h\n+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h\n@@ -42,12 +42,6 @@ struct ixgbevf_tx_buffer {\n \tu32 tx_flags;\n };\n \n-struct ixgbevf_rx_buffer {\n-\tdma_addr_t dma;\n-\tstruct page *page;\n-\t__u32 page_offset;\n-};\n-\n struct ixgbevf_stats {\n \tu64 packets;\n \tu64 bytes;\n@@ -84,19 +78,22 @@ struct ixgbevf_ring {\n \tstruct ixgbevf_ring *next;\n \tstruct ixgbevf_q_vector *q_vector;\t/* backpointer to q_vector */\n \tstruct net_device *netdev;\n-\tstruct bpf_prog *xdp_prog;\n-\tstruct device *dev;\n+\tstruct bpf_prog __rcu *xdp_prog;\n+\tunion {\n+\t\tstruct page_pool *pp;\t/* Rx ring */\n+\t\tstruct device *dev;\t/* Tx ring */\n+\t};\n \tvoid *desc;\t\t\t/* descriptor ring memory */\n \tdma_addr_t dma;\t\t\t/* phys. address of descriptor ring */\n \tunsigned int size;\t\t/* length in bytes */\n+\tu32 truesize;\t\t\t/* Rx buffer full size */\n \tu16 count;\t\t\t/* amount of descriptors */\n \tu16 next_to_use;\n \tu16 next_to_clean;\n-\tu16 next_to_alloc;\n \n \tunion {\n+\t\tstruct libeth_fqe *rx_fqes;\n \t\tstruct ixgbevf_tx_buffer *tx_buffer_info;\n-\t\tstruct ixgbevf_rx_buffer *rx_buffer_info;\n \t};\n \tunsigned long state;\n \tstruct ixgbevf_stats stats;\n@@ -115,6 +112,7 @@ struct ixgbevf_ring {\n \t */\n \tu16 reg_idx;\n \tint queue_index; /* needed for multiqueue queue management */\n+\tu32 rx_buf_len;\n } ____cacheline_internodealigned_in_smp;\n \n /* How many Rx Buffers do we bundle into one write to the hardware ? */\n@@ -144,7 +142,8 @@ struct ixgbevf_ring {\n \n #define MAXIMUM_ETHERNET_VLAN_SIZE (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN)\n \n-#define IXGBEVF_SKB_PAD\t\t(NET_SKB_PAD + NET_IP_ALIGN)\n+#define IXGBEVF_RX_PAGE_LEN(hr)\t\t(ALIGN_DOWN(LIBETH_RX_PAGE_LEN(hr), \\\n+\t\t\t\t\t IXGBE_SRRCTL_BSIZEPKT_STEP))\n \n #define IXGBE_TX_FLAGS_CSUM\t\tBIT(0)\n #define IXGBE_TX_FLAGS_VLAN\t\tBIT(1)\ndiff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c\nindex f5a7dd37084f..5a270dd2c7aa 100644\n--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c\n+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c\n@@ -30,6 +30,7 @@\n #include <linux/bpf.h>\n #include <linux/bpf_trace.h>\n #include <linux/atomic.h>\n+#include <net/libeth/xdp.h>\n #include <net/xfrm.h>\n \n #include \"ixgbevf.h\"\n@@ -82,6 +83,7 @@ static const struct pci_device_id ixgbevf_pci_tbl[] = {\n MODULE_DEVICE_TABLE(pci, ixgbevf_pci_tbl);\n \n MODULE_DESCRIPTION(\"Intel(R) 10 Gigabit Virtual Function Network Driver\");\n+MODULE_IMPORT_NS(\"LIBETH\");\n MODULE_LICENSE(\"GPL v2\");\n \n #define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK)\n@@ -304,7 +306,7 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_q_vector *q_vector,\n \n \t\t/* free the skb */\n \t\tif (ring_is_xdp(tx_ring))\n-\t\t\tpage_frag_free(tx_buffer->data);\n+\t\t\tlibeth_xdp_return_va(tx_buffer->data, true);\n \t\telse\n \t\t\tnapi_consume_skb(tx_buffer->skb, napi_budget);\n \n@@ -521,35 +523,6 @@ static void ixgbevf_process_skb_fields(struct ixgbevf_ring *rx_ring,\n \n \tif (ixgbevf_test_staterr(rx_desc, IXGBE_RXDADV_STAT_SECP))\n \t\tixgbevf_ipsec_rx(rx_ring, rx_desc, skb);\n-\n-\tskb->protocol = eth_type_trans(skb, rx_ring->netdev);\n-}\n-\n-static\n-struct ixgbevf_rx_buffer *ixgbevf_get_rx_buffer(struct ixgbevf_ring *rx_ring,\n-\t\t\t\t\t\tconst unsigned int size)\n-{\n-\tstruct ixgbevf_rx_buffer *rx_buffer;\n-\n-\trx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean];\n-\tprefetchw(rx_buffer->page);\n-\n-\t/* we are reusing so sync this buffer for CPU use */\n-\tdma_sync_single_range_for_cpu(rx_ring->dev,\n-\t\t\t\t rx_buffer->dma,\n-\t\t\t\t rx_buffer->page_offset,\n-\t\t\t\t size,\n-\t\t\t\t DMA_FROM_DEVICE);\n-\n-\treturn rx_buffer;\n-}\n-\n-static void ixgbevf_put_rx_buffer(struct ixgbevf_ring *rx_ring,\n-\t\t\t\t struct ixgbevf_rx_buffer *rx_buffer)\n-{\n-\tdma_unmap_page_attrs(rx_ring->dev, rx_buffer->dma, PAGE_SIZE,\n-\t\t\t DMA_FROM_DEVICE, IXGBEVF_RX_DMA_ATTR);\n-\trx_buffer->page = NULL;\n }\n \n /**\n@@ -579,41 +552,6 @@ static bool ixgbevf_is_non_eop(struct ixgbevf_ring *rx_ring,\n \treturn true;\n }\n \n-static bool ixgbevf_alloc_mapped_page(struct ixgbevf_ring *rx_ring,\n-\t\t\t\t struct ixgbevf_rx_buffer *bi)\n-{\n-\tstruct page *page = bi->page;\n-\tdma_addr_t dma;\n-\n-\t/* alloc new page for storage */\n-\tpage = dev_alloc_page();\n-\tif (unlikely(!page)) {\n-\t\trx_ring->rx_stats.alloc_rx_page_failed++;\n-\t\treturn false;\n-\t}\n-\n-\t/* map page for use */\n-\tdma = dma_map_page_attrs(rx_ring->dev, page, 0, PAGE_SIZE,\n-\t\t\t\t DMA_FROM_DEVICE, IXGBEVF_RX_DMA_ATTR);\n-\n-\t/* if mapping failed free memory back to system since\n-\t * there isn't much point in holding memory we can't use\n-\t */\n-\tif (dma_mapping_error(rx_ring->dev, dma)) {\n-\t\t__free_page(page);\n-\n-\t\trx_ring->rx_stats.alloc_rx_page_failed++;\n-\t\treturn false;\n-\t}\n-\n-\tbi->dma = dma;\n-\tbi->page = page;\n-\tbi->page_offset = IXGBEVF_SKB_PAD;\n-\trx_ring->rx_stats.alloc_rx_page++;\n-\n-\treturn true;\n-}\n-\n /**\n * ixgbevf_alloc_rx_buffers - Replace used receive buffers; packet split\n * @rx_ring: rx descriptor ring (for a specific queue) to setup buffers on\n@@ -623,39 +561,34 @@ static void ixgbevf_alloc_rx_buffers(struct ixgbevf_ring *rx_ring,\n \t\t\t\t u16 cleaned_count)\n {\n \tunion ixgbe_adv_rx_desc *rx_desc;\n-\tstruct ixgbevf_rx_buffer *bi;\n-\tunsigned int i = rx_ring->next_to_use;\n+\tconst struct libeth_fq_fp fq = {\n+\t\t.pp\t\t= rx_ring->pp,\n+\t\t.fqes\t\t= rx_ring->rx_fqes,\n+\t\t.truesize\t= rx_ring->truesize,\n+\t\t.count\t\t= rx_ring->count,\n+\t};\n+\tu16 ntu = rx_ring->next_to_use;\n \n \t/* nothing to do or no valid netdev defined */\n \tif (!cleaned_count || !rx_ring->netdev)\n \t\treturn;\n \n-\trx_desc = IXGBEVF_RX_DESC(rx_ring, i);\n-\tbi = &rx_ring->rx_buffer_info[i];\n-\ti -= rx_ring->count;\n+\trx_desc = IXGBEVF_RX_DESC(rx_ring, ntu);\n \n \tdo {\n-\t\tif (!ixgbevf_alloc_mapped_page(rx_ring, bi))\n-\t\t\tbreak;\n+\t\tdma_addr_t addr;\n \n-\t\t/* sync the buffer for use by the device */\n-\t\tdma_sync_single_range_for_device(rx_ring->dev, bi->dma,\n-\t\t\t\t\t\t bi->page_offset,\n-\t\t\t\t\t\t IXGBEVF_RXBUFFER_3072,\n-\t\t\t\t\t\t DMA_FROM_DEVICE);\n+\t\taddr = libeth_rx_alloc(&fq, ntu);\n+\t\tif (addr == DMA_MAPPING_ERROR)\n+\t\t\tbreak;\n \n-\t\t/* Refresh the desc even if pkt_addr didn't change\n-\t\t * because each write-back erases this info.\n-\t\t */\n-\t\trx_desc->read.pkt_addr = cpu_to_le64(bi->dma + bi->page_offset);\n+\t\trx_desc->read.pkt_addr = cpu_to_le64(addr);\n \n \t\trx_desc++;\n-\t\tbi++;\n-\t\ti++;\n-\t\tif (unlikely(!i)) {\n+\t\tntu++;\n+\t\tif (unlikely(ntu == rx_ring->count)) {\n \t\t\trx_desc = IXGBEVF_RX_DESC(rx_ring, 0);\n-\t\t\tbi = rx_ring->rx_buffer_info;\n-\t\t\ti -= rx_ring->count;\n+\t\t\tntu = 0;\n \t\t}\n \n \t\t/* clear the length for the next_to_use descriptor */\n@@ -664,14 +597,9 @@ static void ixgbevf_alloc_rx_buffers(struct ixgbevf_ring *rx_ring,\n \t\tcleaned_count--;\n \t} while (cleaned_count);\n \n-\ti += rx_ring->count;\n-\n-\tif (rx_ring->next_to_use != i) {\n+\tif (likely(rx_ring->next_to_use != ntu)) {\n \t\t/* record the next descriptor to use */\n-\t\trx_ring->next_to_use = i;\n-\n-\t\t/* update next to alloc since we have filled the ring */\n-\t\trx_ring->next_to_alloc = i;\n+\t\trx_ring->next_to_use = ntu;\n \n \t\t/* Force memory writes to complete before letting h/w\n \t\t * know there are new descriptors to fetch. (Only\n@@ -679,7 +607,7 @@ static void ixgbevf_alloc_rx_buffers(struct ixgbevf_ring *rx_ring,\n \t\t * such as IA-64).\n \t\t */\n \t\twmb();\n-\t\tixgbevf_write_tail(rx_ring, i);\n+\t\tixgbevf_write_tail(rx_ring, ntu);\n \t}\n }\n \n@@ -716,10 +644,6 @@ static bool ixgbevf_cleanup_headers(struct ixgbevf_ring *rx_ring,\n \t\t}\n \t}\n \n-\t/* if eth_skb_pad returns an error the skb was freed */\n-\tif (eth_skb_pad(skb))\n-\t\treturn true;\n-\n \treturn false;\n }\n \n@@ -732,15 +656,15 @@ static bool ixgbevf_cleanup_headers(struct ixgbevf_ring *rx_ring,\n *\n * This function will add the data contained in rx_buffer->page to the skb.\n **/\n-static void ixgbevf_add_rx_frag(struct ixgbevf_ring *rx_ring,\n-\t\t\t\tstruct ixgbevf_rx_buffer *rx_buffer,\n+static void ixgbevf_add_rx_frag(const struct libeth_fqe *rx_buffer,\n \t\t\t\tstruct sk_buff *skb,\n \t\t\t\tunsigned int size)\n {\n-\tunsigned int truesize = SKB_DATA_ALIGN(IXGBEVF_SKB_PAD + size);\n+\tu32 hr = netmem_get_pp(rx_buffer->netmem)->p.offset;\n \n-\tskb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rx_buffer->page,\n-\t\t\trx_buffer->page_offset, size, truesize);\n+\tskb_add_rx_frag_netmem(skb, skb_shinfo(skb)->nr_frags,\n+\t\t\t rx_buffer->netmem, rx_buffer->offset + hr,\n+\t\t\t size, rx_buffer->truesize);\n }\n \n static inline void ixgbevf_irq_enable_queues(struct ixgbevf_adapter *adapter,\n@@ -751,38 +675,6 @@ static inline void ixgbevf_irq_enable_queues(struct ixgbevf_adapter *adapter,\n \tIXGBE_WRITE_REG(hw, IXGBE_VTEIMS, qmask);\n }\n \n-static struct sk_buff *ixgbevf_build_skb(struct ixgbevf_ring *rx_ring,\n-\t\t\t\t\t struct ixgbevf_rx_buffer *rx_buffer,\n-\t\t\t\t\t struct xdp_buff *xdp,\n-\t\t\t\t\t union ixgbe_adv_rx_desc *rx_desc)\n-{\n-\tunsigned int metasize = xdp->data - xdp->data_meta;\n-\tunsigned int truesize = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) +\n-\t\t\t\tSKB_DATA_ALIGN(xdp->data_end -\n-\t\t\t\t\t xdp->data_hard_start);\n-\tstruct sk_buff *skb;\n-\n-\t/* Prefetch first cache line of first page. If xdp->data_meta\n-\t * is unused, this points to xdp->data, otherwise, we likely\n-\t * have a consumer accessing first few bytes of meta data,\n-\t * and then actual data.\n-\t */\n-\tnet_prefetch(xdp->data_meta);\n-\n-\t/* build an skb around the page buffer */\n-\tskb = napi_build_skb(xdp->data_hard_start, truesize);\n-\tif (unlikely(!skb))\n-\t\treturn NULL;\n-\n-\t/* update pointers within the skb to store the data */\n-\tskb_reserve(skb, xdp->data - xdp->data_hard_start);\n-\t__skb_put(skb, xdp->data_end - xdp->data);\n-\tif (metasize)\n-\t\tskb_metadata_set(skb, metasize);\n-\n-\treturn skb;\n-}\n-\n #define IXGBEVF_XDP_PASS 0\n #define IXGBEVF_XDP_CONSUMED 1\n #define IXGBEVF_XDP_TX 2\n@@ -866,7 +758,7 @@ static int ixgbevf_xmit_xdp_ring(struct ixgbevf_ring *ring,\n \n static int ixgbevf_run_xdp(struct ixgbevf_adapter *adapter,\n \t\t\t struct ixgbevf_ring *rx_ring,\n-\t\t\t struct xdp_buff *xdp)\n+\t\t\t struct libeth_xdp_buff *xdp)\n {\n \tint result = IXGBEVF_XDP_PASS;\n \tstruct ixgbevf_ring *xdp_ring;\n@@ -878,13 +770,13 @@ static int ixgbevf_run_xdp(struct ixgbevf_adapter *adapter,\n \tif (!xdp_prog)\n \t\tgoto xdp_out;\n \n-\tact = bpf_prog_run_xdp(xdp_prog, xdp);\n+\tact = bpf_prog_run_xdp(xdp_prog, &xdp->base);\n \tswitch (act) {\n \tcase XDP_PASS:\n \t\tbreak;\n \tcase XDP_TX:\n \t\txdp_ring = adapter->xdp_ring[rx_ring->queue_index];\n-\t\tresult = ixgbevf_xmit_xdp_ring(xdp_ring, xdp);\n+\t\tresult = ixgbevf_xmit_xdp_ring(xdp_ring, &xdp->base);\n \t\tif (result == IXGBEVF_XDP_CONSUMED)\n \t\t\tgoto out_failure;\n \t\tbreak;\n@@ -897,6 +789,7 @@ static int ixgbevf_run_xdp(struct ixgbevf_adapter *adapter,\n \t\tfallthrough; /* handle aborts by dropping packet */\n \tcase XDP_DROP:\n \t\tresult = IXGBEVF_XDP_CONSUMED;\n+\t\tlibeth_xdp_return_buff(xdp);\n \t\tbreak;\n \t}\n xdp_out:\n@@ -911,16 +804,15 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,\n \tstruct ixgbevf_adapter *adapter = q_vector->adapter;\n \tu16 cleaned_count = ixgbevf_desc_unused(rx_ring);\n \tstruct sk_buff *skb = rx_ring->skb;\n+\tLIBETH_XDP_ONSTACK_BUFF(xdp);\n \tbool xdp_xmit = false;\n-\tstruct xdp_buff xdp;\n \tint xdp_res = 0;\n \n-\t/* Frame size depend on rx_ring setup when PAGE_SIZE=4K */\n-\txdp_init_buff(&xdp, IXGBEVF_RXBUFFER_3072, &rx_ring->xdp_rxq);\n+\txdp->base.rxq = &rx_ring->xdp_rxq;\n \n \twhile (likely(total_rx_packets < budget)) {\n-\t\tstruct ixgbevf_rx_buffer *rx_buffer;\n \t\tunion ixgbe_adv_rx_desc *rx_desc;\n+\t\tstruct libeth_fqe *rx_buffer;\n \t\tunsigned int size;\n \n \t\t/* return some buffers to hardware, one at a time is too slow */\n@@ -940,18 +832,14 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,\n \t\t */\n \t\trmb();\n \n-\t\trx_buffer =\n-\t\t\tixgbevf_get_rx_buffer(rx_ring, IXGBEVF_RXBUFFER_3072);\n+\t\trx_buffer = &rx_ring->rx_fqes[rx_ring->next_to_clean];\n+\t\tlibeth_rx_sync_for_cpu(rx_buffer, size);\n \n \t\t/* retrieve a buffer from the ring */\n \t\tif (!skb) {\n-\t\t\tunsigned int offset = rx_buffer->page_offset;\n-\t\t\tunsigned char *hard_start;\n-\n-\t\t\thard_start = page_address(rx_buffer->page) +\n-\t\t\t\t rx_buffer->page_offset - offset;\n-\t\t\txdp_prepare_buff(&xdp, hard_start, offset, size, true);\n-\t\t\txdp_res = ixgbevf_run_xdp(adapter, rx_ring, &xdp);\n+\t\t\tlibeth_xdp_prepare_buff(xdp, rx_buffer, size);\n+\t\t\tprefetch(xdp->data);\n+\t\t\txdp_res = ixgbevf_run_xdp(adapter, rx_ring, xdp);\n \t\t}\n \n \t\tif (xdp_res) {\n@@ -961,10 +849,9 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,\n \t\t\ttotal_rx_packets++;\n \t\t\ttotal_rx_bytes += size;\n \t\t} else if (skb) {\n-\t\t\tixgbevf_add_rx_frag(rx_ring, rx_buffer, skb, size);\n+\t\t\tixgbevf_add_rx_frag(rx_buffer, skb, size);\n \t\t} else {\n-\t\t\tskb = ixgbevf_build_skb(rx_ring, rx_buffer,\n-\t\t\t\t\t\t&xdp, rx_desc);\n+\t\t\tskb = xdp_build_skb_from_buff(&xdp->base);\n \t\t}\n \n \t\t/* exit if we failed to retrieve a buffer */\n@@ -973,7 +860,6 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,\n \t\t\tbreak;\n \t\t}\n \n-\t\tixgbevf_put_rx_buffer(rx_ring, rx_buffer);\n \t\tcleaned_count++;\n \n \t\t/* fetch next buffer in frame if non-eop */\n@@ -1542,7 +1428,8 @@ static void ixgbevf_configure_tx(struct ixgbevf_adapter *adapter)\n #define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT\t2\n \n static void ixgbevf_configure_srrctl(struct ixgbevf_adapter *adapter,\n-\t\t\t\t struct ixgbevf_ring *ring, int index)\n+\t\t\t\t struct ixgbevf_ring *ring, int index,\n+\t\t\t\t bool rlpml_valid)\n {\n \tstruct ixgbe_hw *hw = &adapter->hw;\n \tu32 srrctl;\n@@ -1550,7 +1437,11 @@ static void ixgbevf_configure_srrctl(struct ixgbevf_adapter *adapter,\n \tsrrctl = IXGBE_SRRCTL_DROP_EN;\n \n \tsrrctl |= IXGBEVF_RX_HDR_SIZE << IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT;\n-\tsrrctl |= IXGBEVF_RXBUFFER_3072 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;\n+\tif (rlpml_valid)\n+\t\tsrrctl |= DIV_ROUND_UP(ring->rx_buf_len,\n+\t\t\t\t IXGBE_SRRCTL_BSIZEPKT_STEP);\n+\telse\n+\t\tsrrctl |= ring->rx_buf_len / IXGBE_SRRCTL_BSIZEPKT_STEP;\n \tsrrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;\n \n \tIXGBE_WRITE_REG(hw, IXGBE_VFSRRCTL(index), srrctl);\n@@ -1681,9 +1572,10 @@ static void ixgbevf_configure_rx_ring(struct ixgbevf_adapter *adapter,\n {\n \tstruct ixgbe_hw *hw = &adapter->hw;\n \tunion ixgbe_adv_rx_desc *rx_desc;\n+\tu8 reg_idx = ring->reg_idx;\n+\tbool rlpml_valid = false;\n \tu64 rdba = ring->dma;\n \tu32 rxdctl;\n-\tu8 reg_idx = ring->reg_idx;\n \n \t/* disable queue to avoid issues while updating state */\n \trxdctl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(reg_idx));\n@@ -1709,10 +1601,6 @@ static void ixgbevf_configure_rx_ring(struct ixgbevf_adapter *adapter,\n \tIXGBE_WRITE_REG(hw, IXGBE_VFRDT(reg_idx), 0);\n \tring->tail = adapter->io_addr + IXGBE_VFRDT(reg_idx);\n \n-\t/* initialize rx_buffer_info */\n-\tmemset(ring->rx_buffer_info, 0,\n-\t sizeof(struct ixgbevf_rx_buffer) * ring->count);\n-\n \t/* initialize Rx descriptor 0 */\n \trx_desc = IXGBEVF_RX_DESC(ring, 0);\n \trx_desc->wb.upper.length = 0;\n@@ -1720,16 +1608,21 @@ static void ixgbevf_configure_rx_ring(struct ixgbevf_adapter *adapter,\n \t/* reset ntu and ntc to place SW in sync with hardwdare */\n \tring->next_to_clean = 0;\n \tring->next_to_use = 0;\n-\tring->next_to_alloc = 0;\n-\n-\tixgbevf_configure_srrctl(adapter, ring, reg_idx);\n \n \t/* RXDCTL.RLPML does not work on 82599 */\n \tif (adapter->hw.mac.type != ixgbe_mac_82599_vf) {\n-\t\trxdctl &= ~(IXGBE_RXDCTL_RLPMLMASK |\n-\t\t\t IXGBE_RXDCTL_RLPML_EN);\n+\t\tu32 pkt_len =\n+\t\t\tREAD_ONCE(adapter->netdev->mtu) + LIBETH_RX_LL_LEN;\n+\n+\t\trxdctl &= ~(IXGBE_RXDCTL_RLPMLMASK | IXGBE_RXDCTL_RLPML_EN);\n+\t\tif (pkt_len <= IXGBE_RXDCTL_RLPMLMASK) {\n+\t\t\trxdctl |= pkt_len | IXGBE_RXDCTL_RLPML_EN;\n+\t\t\trlpml_valid = true;\n+\t\t}\n \t}\n \n+\tixgbevf_configure_srrctl(adapter, ring, reg_idx, rlpml_valid);\n+\n \trxdctl |= IXGBE_RXDCTL_ENABLE | IXGBE_RXDCTL_VME;\n \tIXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(reg_idx), rxdctl);\n \n@@ -2125,8 +2018,6 @@ void ixgbevf_up(struct ixgbevf_adapter *adapter)\n **/\n static void ixgbevf_clean_rx_ring(struct ixgbevf_ring *rx_ring)\n {\n-\tu16 i = rx_ring->next_to_clean;\n-\n \t/* Free Rx ring sk_buff */\n \tif (rx_ring->skb) {\n \t\tdev_kfree_skb(rx_ring->skb);\n@@ -2134,29 +2025,14 @@ static void ixgbevf_clean_rx_ring(struct ixgbevf_ring *rx_ring)\n \t}\n \n \t/* Free all the Rx ring pages */\n-\twhile (i != rx_ring->next_to_alloc) {\n-\t\tstruct ixgbevf_rx_buffer *rx_buffer;\n+\tfor (u32 i = rx_ring->next_to_clean; i != rx_ring->next_to_use; ) {\n+\t\tconst struct libeth_fqe *rx_fqe = &rx_ring->rx_fqes[i];\n \n-\t\trx_buffer = &rx_ring->rx_buffer_info[i];\n-\n-\t\t/* Invalidate cache lines that may have been written to by\n-\t\t * device so that we avoid corrupting memory.\n-\t\t */\n-\t\tdma_sync_single_range_for_cpu(rx_ring->dev,\n-\t\t\t\t\t rx_buffer->dma,\n-\t\t\t\t\t rx_buffer->page_offset,\n-\t\t\t\t\t IXGBEVF_RXBUFFER_3072,\n-\t\t\t\t\t DMA_FROM_DEVICE);\n-\n-\t\t/* free resources associated with mapping */\n-\t\tixgbevf_put_rx_buffer(rx_ring, rx_buffer);\n-\t\t__free_page(rx_buffer->page);\n-\t\ti++;\n-\t\tif (i == rx_ring->count)\n+\t\tlibeth_rx_recycle_slow(rx_fqe->netmem);\n+\t\tif (unlikely(++i == rx_ring->count))\n \t\t\ti = 0;\n \t}\n \n-\trx_ring->next_to_alloc = 0;\n \trx_ring->next_to_clean = 0;\n \trx_ring->next_to_use = 0;\n }\n@@ -2175,7 +2051,7 @@ static void ixgbevf_clean_tx_ring(struct ixgbevf_ring *tx_ring)\n \n \t\t/* Free all the Tx ring sk_buffs */\n \t\tif (ring_is_xdp(tx_ring))\n-\t\t\tpage_frag_free(tx_buffer->data);\n+\t\t\tlibeth_xdp_return_va(tx_buffer->data, false);\n \t\telse\n \t\t\tdev_kfree_skb_any(tx_buffer->skb);\n \n@@ -3257,12 +3133,26 @@ static int ixgbevf_setup_all_tx_resources(struct ixgbevf_adapter *adapter)\n int ixgbevf_setup_rx_resources(struct ixgbevf_adapter *adapter,\n \t\t\t struct ixgbevf_ring *rx_ring)\n {\n-\tint size;\n+\tstruct libeth_fq fq = {\n+\t\t.count\t\t= rx_ring->count,\n+\t\t.nid\t\t= NUMA_NO_NODE,\n+\t\t.type\t\t= LIBETH_FQE_MTU,\n+\t\t.xdp\t\t= !!rx_ring->xdp_prog,\n+\t\t.idx\t\t= rx_ring->queue_index,\n+\t\t.buf_len\t= IXGBEVF_RX_PAGE_LEN(rx_ring->xdp_prog ?\n+\t\t\t\t\t\t LIBETH_XDP_HEADROOM :\n+\t\t\t\t\t\t LIBETH_SKB_HEADROOM),\n+\t};\n+\tint ret;\n \n-\tsize = sizeof(struct ixgbevf_rx_buffer) * rx_ring->count;\n-\trx_ring->rx_buffer_info = vmalloc(size);\n-\tif (!rx_ring->rx_buffer_info)\n-\t\tgoto err;\n+\tret = libeth_rx_fq_create(&fq, &rx_ring->q_vector->napi);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\trx_ring->pp = fq.pp;\n+\trx_ring->rx_fqes = fq.fqes;\n+\trx_ring->truesize = fq.truesize;\n+\trx_ring->rx_buf_len = fq.buf_len;\n \n \tu64_stats_init(&rx_ring->syncp);\n \n@@ -3270,25 +3160,31 @@ int ixgbevf_setup_rx_resources(struct ixgbevf_adapter *adapter,\n \trx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc);\n \trx_ring->size = ALIGN(rx_ring->size, 4096);\n \n-\trx_ring->desc = dma_alloc_coherent(rx_ring->dev, rx_ring->size,\n+\trx_ring->desc = dma_alloc_coherent(fq.pp->p.dev, rx_ring->size,\n \t\t\t\t\t &rx_ring->dma, GFP_KERNEL);\n \n-\tif (!rx_ring->desc)\n+\tif (!rx_ring->desc) {\n+\t\tret = -ENOMEM;\n \t\tgoto err;\n+\t}\n \n \t/* XDP RX-queue info */\n-\tif (xdp_rxq_info_reg(&rx_ring->xdp_rxq, adapter->netdev,\n-\t\t\t rx_ring->queue_index, 0) < 0)\n+\tret = __xdp_rxq_info_reg(&rx_ring->xdp_rxq, adapter->netdev,\n+\t\t\t\t rx_ring->queue_index, 0, rx_ring->truesize);\n+\tif (ret)\n \t\tgoto err;\n \n+\txdp_rxq_info_attach_page_pool(&rx_ring->xdp_rxq, fq.pp);\n+\n \trx_ring->xdp_prog = adapter->xdp_prog;\n \n \treturn 0;\n err:\n-\tvfree(rx_ring->rx_buffer_info);\n-\trx_ring->rx_buffer_info = NULL;\n+\tlibeth_rx_fq_destroy(&fq);\n+\trx_ring->rx_fqes = NULL;\n+\trx_ring->pp = NULL;\n \tdev_err(rx_ring->dev, \"Unable to allocate memory for the Rx descriptor ring\\n\");\n-\treturn -ENOMEM;\n+\treturn ret;\n }\n \n /**\n@@ -3329,17 +3225,24 @@ static int ixgbevf_setup_all_rx_resources(struct ixgbevf_adapter *adapter)\n **/\n void ixgbevf_free_rx_resources(struct ixgbevf_ring *rx_ring)\n {\n+\tstruct libeth_fq fq = {\n+\t\t.fqes\t= rx_ring->rx_fqes,\n+\t\t.pp\t= rx_ring->pp,\n+\t};\n+\n \tixgbevf_clean_rx_ring(rx_ring);\n \n \trx_ring->xdp_prog = NULL;\n+\txdp_rxq_info_detach_mem_model(&rx_ring->xdp_rxq);\n \txdp_rxq_info_unreg(&rx_ring->xdp_rxq);\n-\tvfree(rx_ring->rx_buffer_info);\n-\trx_ring->rx_buffer_info = NULL;\n \n-\tdma_free_coherent(rx_ring->dev, rx_ring->size, rx_ring->desc,\n+\tdma_free_coherent(fq.pp->p.dev, rx_ring->size, rx_ring->desc,\n \t\t\t rx_ring->dma);\n-\n \trx_ring->desc = NULL;\n+\n+\tlibeth_rx_fq_destroy(&fq);\n+\trx_ring->rx_fqes = NULL;\n+\trx_ring->pp = NULL;\n }\n \n /**\n", "prefixes": [ "iwl-next", "v3", "03/10" ] }