Netdev List
 help / color / mirror / Atom feed
From: Yun Lu <luyun_611@163.com>
To: andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
	kuba@kernel.org, pabeni@redhat.com
Cc: netdev@vger.kernel.org
Subject: [PATCH 01/13] 8139cp: fix DMA mapping unwind on TX frag map failure
Date: Fri, 17 Jul 2026 18:37:23 +0800	[thread overview]
Message-ID: <20260717103724.13971-2-luyun_611@163.com> (raw)
In-Reply-To: <20260717103724.13971-1-luyun_611@163.com>

From: Yun Lu <luyun@kylinos.cn>

When dma_map_single() fails for one of the TX fragments in
cp_start_xmit(), unwind_tx_frag_mapping() is supposed to drop the
DMA mappings that have been established so far. The current code
gets this wrong in three ways:

- it unmaps the DMA address read from the descriptor of the head
  slot, but the head descriptor is only written after the fragment
  loop, so a stale address of a previously completed (and already
  unmapped) packet gets unmapped again;
- the unmap sizes are off by one slot: slot first_entry + 1 + k
  holds frags[k], but is unmapped with the size of frags[k + 1];
- the head buffer mapping (first_mapping) is never unmapped at all,
  leaking one DMA mapping on every failure.

Pass the head mapping and its length to the unwind helper, unmap it
explicitly, and unmap the successfully mapped fragments with their
matching sizes.

Fixes: cf3c4c03060b ("8139cp: Add dma_mapping_error checking")
Signed-off-by: Yun Lu <luyun@kylinos.cn>
---
 drivers/net/ethernet/realtek/8139cp.c | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
index 5652da8a178c..03929bb0bd79 100644
--- a/drivers/net/ethernet/realtek/8139cp.c
+++ b/drivers/net/ethernet/realtek/8139cp.c
@@ -713,13 +713,24 @@ static inline u32 cp_tx_vlan_tag(struct sk_buff *skb)
 }
 
 static void unwind_tx_frag_mapping(struct cp_private *cp, struct sk_buff *skb,
+				   dma_addr_t first_mapping, u32 first_len,
 				   int first, int entry_last)
 {
 	int frag, index;
-	struct cp_desc *txd;
-	skb_frag_t *this_frag;
-	for (frag = 0; frag+first < entry_last; frag++) {
-		index = first+frag;
+
+	/* The head mapping was never written to the ring, unmap it
+	 * using the saved address.
+	 */
+	dma_unmap_single(&cp->pdev->dev, first_mapping, first_len,
+			 DMA_TO_DEVICE);
+	cp->tx_skb[first] = NULL;
+
+	/* Unmap the frags that were successfully mapped. */
+	for (frag = 0; first + 1 + frag < entry_last; frag++) {
+		struct cp_desc *txd;
+		skb_frag_t *this_frag;
+
+		index = first + 1 + frag;
 		cp->tx_skb[index] = NULL;
 		txd = &cp->tx_ring[index];
 		this_frag = &skb_shinfo(skb)->frags[frag];
@@ -828,7 +839,9 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
 						 skb_frag_address(this_frag),
 						 len, DMA_TO_DEVICE);
 			if (dma_mapping_error(&cp->pdev->dev, mapping)) {
-				unwind_tx_frag_mapping(cp, skb, first_entry, entry);
+				unwind_tx_frag_mapping(cp, skb, first_mapping,
+						       first_len, first_entry,
+						       entry);
 				goto out_dma_error;
 			}
 
-- 
2.25.1


  reply	other threads:[~2026-07-17 10:38 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-17 10:37 [PATCH net 0/2] 8139cp: fix two TX error handling bugs Yun Lu
2026-07-17 10:37 ` Yun Lu [this message]
2026-07-22  7:37   ` [PATCH 01/13] 8139cp: fix DMA mapping unwind on TX frag map failure luyun
2026-07-22 19:43     ` Jakub Kicinski
2026-07-23  1:57       ` luyun
2026-07-23 13:32         ` Jakub Kicinski
2026-07-17 10:37 ` [PATCH 02/13] 8139cp: handle cp_init_rings() failure in cp_tx_timeout() Yun Lu

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=20260717103724.13971-2-luyun_611@163.com \
    --to=luyun_611@163.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=kuba@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.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