From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
patches@lists.linux.dev, Suraj Gupta <suraj.gupta2@amd.com>,
Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
Subject: [PATCH 6.18 18/52] net: xilinx: axienet: Free outstanding DMA buffers on dmaengine stop
Date: Sat, 17 Oct 2026 17:54:19 +0200 [thread overview]
Message-ID: <20261017155105.443120452@linuxfoundation.org> (raw)
In-Reply-To: <20261017155104.830766652@linuxfoundation.org>
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Suraj Gupta <suraj.gupta2@amd.com>
[ Upstream commit bcf2573a68a808a5b54cadafa72b6672e662c2bf ]
In the dmaengine path the driver pre-submits RX buffers and holds
in-flight TX buffers whose SKBs are DMA-mapped by the driver and freed
only in the completion callbacks. On ndo_stop() dmaengine_terminate_sync()
aborts these descriptors without running their callbacks, and the driver
then frees only the ring shells, leaking every SKB still owned by the
engine and its DMA mapping on each ifdown. With 128 RX buffers pre-posted
per channel, the mapping leak can eventually exhaust a limited IOMMU
aperture.
Clear the slot's skb in the TX and RX callbacks so a non-NULL skb marks a
slot that still owns a live, DMA-mapped buffer, and on stop unmap and free
every such buffer.
axienet_dma_rx_cb() runs from the DMA tasklet and re-arms the RX ring on
each completion, so it can race axienet_stop(): a completion may submit a
fresh buffer after dmaengine_terminate_sync() has returned, leaving the
channel armed with a buffer the teardown then frees while the engine may
still write into it (dma_release_channel() does not stop it either). Add a
lock that axienet_dma_rx_cb() holds across the @stopping check and the
resubmit, and axienet_stop() holds to set @stopping before terminating.
Once @stopping is set no callback can arm a new buffer, and any armed just
before is aborted by the terminate, so teardown only frees buffers the
engine no longer owns.
Fixes: 6a91b846af85 ("net: axienet: Introduce dmaengine support")
Cc: stable@vger.kernel.org
Signed-off-by: Suraj Gupta <suraj.gupta2@amd.com>
Link: https://patch.msgid.link/20260928184207.2361931-1-suraj.gupta2@amd.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ sashal: Adjusted context to retain kcalloc() instead of upstream’s kzalloc_objs(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/xilinx/xilinx_axienet.h | 7 ++-
.../net/ethernet/xilinx/xilinx_axienet_main.c | 51 +++++++++++++++----
2 files changed, 47 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h
index fcd3aaef27fc3..c63d99686d0ba 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet.h
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h
@@ -523,8 +523,9 @@ struct skbuf_dma_descriptor {
* @stats_work: Work for reading the hardware statistics counters often enough
* to catch overflows.
* @dma_err_task: Work structure to process Axi DMA errors
- * @stopping: Set when @dma_err_task shouldn't do anything because we are
- * about to stop the device.
+ * @stopping: Set when we are about to stop the device: makes @dma_err_task
+ * a no-op (legacy DMA path) and fences RX descriptor
+ * resubmission in axienet_dma_rx_cb() (dmaengine path).
* @tx_irq: Axidma TX IRQ number
* @rx_irq: Axidma RX IRQ number
* @eth_irq: Ethernet core IRQ number
@@ -545,6 +546,7 @@ struct skbuf_dma_descriptor {
* @tx_ring_tail: TX skb ring buffer tail index.
* @rx_ring_head: RX skb ring buffer head index.
* @rx_ring_tail: RX skb ring buffer tail index.
+ * @rx_submit_lock: Protects RX ring resubmission vs teardown in dmaengine path.
*/
struct axienet_local {
struct net_device *ndev;
@@ -626,6 +628,7 @@ struct axienet_local {
int tx_ring_tail;
int rx_ring_head;
int rx_ring_tail;
+ spinlock_t rx_submit_lock;
};
/**
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index eefe54ce66852..50ddc7c53b630 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -881,6 +881,7 @@ static void axienet_dma_tx_cb(void *data, const struct dmaengine_result *result)
u64_stats_update_end(&lp->tx_stat_sync);
dma_unmap_sg(lp->dev, skbuf_dma->sgl, skbuf_dma->sg_len, DMA_TO_DEVICE);
dev_consume_skb_any(skbuf_dma->skb);
+ skbuf_dma->skb = NULL;
netif_txq_completed_wake(txq, 1, len,
CIRC_SPACE(lp->tx_ring_head, lp->tx_ring_tail, TX_BD_NUM_MAX),
2);
@@ -1171,6 +1172,7 @@ static void axienet_dma_rx_cb(void *data, const struct dmaengine_result *result)
&meta_max_len);
dma_unmap_single(lp->dev, skbuf_dma->dma_address, lp->max_frm_size,
DMA_FROM_DEVICE);
+ skbuf_dma->skb = NULL;
if (IS_ERR(app_metadata)) {
if (net_ratelimit())
@@ -1193,10 +1195,17 @@ static void axienet_dma_rx_cb(void *data, const struct dmaengine_result *result)
u64_stats_update_end(&lp->rx_stat_sync);
rx_submit:
+ spin_lock(&lp->rx_submit_lock);
+ if (lp->stopping) {
+ spin_unlock(&lp->rx_submit_lock);
+ return;
+ }
+
for (i = 0; i < CIRC_SPACE(lp->rx_ring_head, lp->rx_ring_tail,
RX_BUF_NUM_DEFAULT); i++)
axienet_rx_submit_desc(lp->ndev);
dma_async_issue_pending(lp->rx_chan);
+ spin_unlock(&lp->rx_submit_lock);
}
/**
@@ -1541,6 +1550,7 @@ static int axienet_init_dmaengine(struct net_device *ndev)
lp->tx_ring_head = 0;
lp->rx_ring_tail = 0;
lp->rx_ring_head = 0;
+ lp->stopping = false;
lp->tx_skb_ring = kcalloc(TX_BD_NUM_MAX, sizeof(*lp->tx_skb_ring),
GFP_KERNEL);
if (!lp->tx_skb_ring) {
@@ -1754,20 +1764,42 @@ static int axienet_stop(struct net_device *ndev)
free_irq(lp->rx_irq, ndev);
axienet_dma_bd_release(ndev);
} else {
+ struct skbuf_dma_descriptor *skbuf_dma;
+
+ spin_lock_bh(&lp->rx_submit_lock);
+ lp->stopping = true;
+ spin_unlock_bh(&lp->rx_submit_lock);
+
dmaengine_terminate_sync(lp->tx_chan);
- dmaengine_synchronize(lp->tx_chan);
dmaengine_terminate_sync(lp->rx_chan);
- dmaengine_synchronize(lp->rx_chan);
-
- for (i = 0; i < TX_BD_NUM_MAX; i++)
- kfree(lp->tx_skb_ring[i]);
- kfree(lp->tx_skb_ring);
- for (i = 0; i < RX_BUF_NUM_DEFAULT; i++)
- kfree(lp->rx_skb_ring[i]);
- kfree(lp->rx_skb_ring);
dma_release_channel(lp->rx_chan);
dma_release_channel(lp->tx_chan);
+
+ /* Unmap and free any buffer the terminate did not reclaim, so it
+ * is not leaked; a non-NULL skb marks such a slot.
+ */
+ for (i = 0; i < TX_BD_NUM_MAX; i++) {
+ skbuf_dma = lp->tx_skb_ring[i];
+ if (skbuf_dma && skbuf_dma->skb) {
+ dma_unmap_sg(lp->dev, skbuf_dma->sgl,
+ skbuf_dma->sg_len, DMA_TO_DEVICE);
+ dev_kfree_skb_any(skbuf_dma->skb);
+ }
+ kfree(skbuf_dma);
+ }
+ kfree(lp->tx_skb_ring);
+
+ for (i = 0; i < RX_BUF_NUM_DEFAULT; i++) {
+ skbuf_dma = lp->rx_skb_ring[i];
+ if (skbuf_dma && skbuf_dma->skb) {
+ dma_unmap_single(lp->dev, skbuf_dma->dma_address,
+ lp->max_frm_size, DMA_FROM_DEVICE);
+ dev_kfree_skb_any(skbuf_dma->skb);
+ }
+ kfree(skbuf_dma);
+ }
+ kfree(lp->rx_skb_ring);
}
netdev_reset_queue(ndev);
@@ -3060,6 +3092,7 @@ static int axienet_probe(struct platform_device *pdev)
spin_lock_init(&lp->rx_cr_lock);
spin_lock_init(&lp->tx_cr_lock);
+ spin_lock_init(&lp->rx_submit_lock);
INIT_WORK(&lp->rx_dim.work, axienet_rx_dim_work);
lp->rx_dim_enabled = true;
lp->rx_dim.profile_ix = 1;
--
2.53.0
next prev parent reply other threads:[~2026-10-17 15:58 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-17 15:54 [PATCH 6.18 00/52] 6.18.58-rc1 review Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 01/52] spi: mpc52xx: clean up interrupt handling Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 02/52] usb: gadget: f_hid: Add missing error code Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 03/52] RDMA/erdma: Use IRQ-safe XArray helpers for QP and CQ tables Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 04/52] PCI: dwc: Return -ENODEV from dw_pcie_wait_for_link() if device is not found Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 05/52] PCI: dwc: Return -EIO from dw_pcie_wait_for_link() if device is not active Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 06/52] ip6_gre: remove obsolete ERSPAN PMTU update Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 07/52] drm/amd: Create a device link between APU display and XHCI devices Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 08/52] iavf: iavf_virtchnl_completion: drop duplicate ether_addr_equal() test Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 09/52] iavf: send MAC change request synchronously Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 10/52] mm/mremap: fix locked_vm leak by splitting VMA for MREMAP_DONTUNMAP Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 11/52] mm/mremap: fix locked_vm leak from MREMAP_DONTUNMAP self-merge Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 12/52] nfsd: fix all-zero stateid in CB_OFFLOAD for async COPY Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 13/52] wifi: mt76: connac: tolerate inactive BSS deactivation Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 14/52] dm-integrity: fix NULL pointer dereference when the R flag is used Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 15/52] dm-integrity: validate the superblock on resume Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 16/52] sched_ext: Fix CPU hotplug hang when a dying CPUs tasks sit in the BPF scheduler Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 17/52] Bluetooth: RFCOMM: connect the session socket without rfcomm_mutex Greg Kroah-Hartman
2026-10-17 15:54 ` Greg Kroah-Hartman [this message]
2026-10-17 15:54 ` [PATCH 6.18 19/52] net: mana: reserve RX buffer headroom to fix forwarding performance Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 20/52] riscv: patch: Avoid early phys_to_page() Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 21/52] riscv: patch: fix handling of bpf-jit execmem addresses Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 22/52] scsi: ufs: core: Decouple CQ sweep from request iterator in MCQ Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 23/52] scsi: ch: Do not keep references to data transfer element devices Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 24/52] scsi: ufs: core: Move an assignment in ufshcd_mcq_process_cqe() Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 25/52] scsi: ufs: core: Add debug log for MCQ command timeout Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 26/52] scsi: ufs: core: Add a comment block above ufshcd_mcq_compl_all_cqes_lock() Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 27/52] scsi: ufs: core: Avoid unsafe MMIO reads in ufshcd_mcq_compl_all_cqes_lock() Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 28/52] drm/xe/i2c: cancel the client work on remove Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 29/52] cifs: fix time_last_write stamp placement in setattr/truncate paths Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 30/52] fat: stop reading directory entries past the end-of-directory marker Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 31/52] ima: Access decompressed kernel module to verify appended signature Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 32/52] ima: Fix stack-out-of-bounds in is_bprm_creds_for_exec() Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 33/52] ice: remove legacy Rx and construct SKB Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 34/52] ice: drop page splitting and recycling Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 35/52] ice: fix crash in ethtool offline loopback test Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 36/52] ice: fix rxq info registering in mbuf packets Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 37/52] ice: change XDP RxQ frag_size from DMA write length to xdp.frame_sz Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 38/52] xfs: factor out xfs_attr3_node_entry_remove Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 39/52] xfs: factor out xfs_attr3_leaf_init Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 40/52] xfs: close crash window in attr dabtree inactivation Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 41/52] mm/damon/core: cancel damos_walk() before damon_ctx->kdamond reset Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 42/52] mm/damon/core: fix damos_walk() vs kdamond_fn() exit race Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 43/52] selinux: allow multiple opens of /sys/fs/selinux/policy Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 44/52] usb: iowarrior: remove inherent race with minor number Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 45/52] USB: iowarrior: fix use-after-free on disconnect race Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 46/52] ice: fix broken Rx on VFs Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 47/52] rose: hold a reference on incoming sockets queued for accept() Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 48/52] io_uring: do not charge the SQ/CQ rings to RLIMIT_MEMLOCK Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 49/52] io_uring/kbuf: dont charge provided buffer " Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 50/52] kho: free chunks using free_page() instead of kfree() Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 51/52] bpf, sockmap: Account for receive queue in FIONREAD without a verdict program Greg Kroah-Hartman
2026-10-17 15:54 ` [PATCH 6.18 52/52] wifi: atk9k: Revert "wifi: ath9k: reject short WMI command responses" Greg Kroah-Hartman
2026-10-17 17:19 ` [PATCH 6.18 00/52] 6.18.58-rc1 review Brett A C Sheffield
2026-10-17 22:19 ` Peter Schneider
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261017155105.443120452@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=kuba@kernel.org \
--cc=patches@lists.linux.dev \
--cc=sashal@kernel.org \
--cc=stable@vger.kernel.org \
--cc=suraj.gupta2@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox