From: 赵金明 <zhaojinming@uniontech.com>
To: "Lorenzo Bianconi" <lorenzo.bianconi@oss.qualcomm.com>
Cc: maxime.chevallier <maxime.chevallier@bootlin.com>,
andrew+netdev <andrew+netdev@lunn.ch>,
davem <davem@davemloft.net>, edumazet <edumazet@google.com>,
kuba <kuba@kernel.org>, pabeni <pabeni@redhat.com>,
mcoquelin.stm32 <mcoquelin.stm32@gmail.com>,
alexandre.torgue <alexandre.torgue@foss.st.com>,
jose.abreu <Jose.Abreu@synopsys.com>,
netdev <netdev@vger.kernel.org>,
linux-stm32 <linux-stm32@st-md-mailman.stormreply.com>,
linux-arm-kernel <linux-arm-kernel@lists.infradead.org>,
linux-kernel <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH net] net: stmmac: fix stale descriptors and DMA mapping leak on Tx map failure
Date: Fri, 11 Sep 2026 16:34:43 +0800 [thread overview]
Message-ID: <30AFF1B9230534C1+202609111634420869983@uniontech.com> (raw)
In-Reply-To: aqJ2vGaushx4EL5q@lore-desk
>> In stmmac_xmit(), when the DMA mapping of the linear part or of a
>
>[...]
>
>>? if (unlikely(is_jumbo)) {
>> - entry = stmmac_jumbo_frm(priv, tx_q, skb, csum_insertion);
>> - if (unlikely(entry < 0) && (entry != -EINVAL))
>> + ret = stmmac_jumbo_frm(priv, tx_q, skb, csum_insertion);
>
>if jumbo_frm() returns an error on the subsequent frames, entry is not updated
>here, so we will end up with a DMA leak. Am I missing something?
>
You're right, that was a real leak in v1. If jumbo_frm() failed while mapping a subsequent jumbo buffer, the buffers mapped before the failure were never unmapped, because jumbo_frm() returns -1 without reporting how many buffers it had already mapped, so the error path in stmmac_xmit() could not release them.
v2 fixes this inside jumbo_frm() itself: it now saves the starting entry and, when a subsequent dma_map_single() fails, unmaps the buffers it has already mapped before returning an error, in both ring and chain modes. This keeps the stmmac_xmit() error path unchanged and avoids changing jumbo_frm()'s return semantics.
>
>> + if (unlikely(ret < 0) && (ret != -EINVAL))
>>? goto dma_map_err;
>> + entry = ret;
>>? } else {
>>? bool last_segment = (nfrags == 0);
>>?
>> @@ -4984,6 +4985,26 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
>>?
>>? dma_map_err:
>>? netdev_err(priv->dev, "Tx DMA map failed\n");
>> +
>> + /* entry points one past the last descriptor written for this frame:
>> + * on failure it is the descriptor whose DMA mapping failed, so walk
>> + * from first_entry up to, but not including, entry.? Reset cur_tx
>> + * unconditionally as both stmmac_vlan_insert() and stmmac_jumbo_frm()
>> + * may have advanced it, and release the VLAN context descriptor.
>> + */
>> + while (first_entry != entry) {
>> + desc = stmmac_get_tx_desc(priv, tx_q, first_entry);
>> + stmmac_release_tx_desc(priv, desc, priv->descriptor_mode);
>> + stmmac_free_tx_buffer(priv, &priv->dma_conf, queue, first_entry);
>> + first_entry = STMMAC_NEXT_ENTRY(first_entry,
>> + priv->dma_conf.dma_tx_size);
>> + }
>> +
>> + tx_q->cur_tx = first_tx;
>
>do we really need to update tx_q->cur_tx here?
Yes, it is needed. Two helpers advance tx_q->cur_tx before we reach the error path: stmmac_vlan_insert() (when a VLAN tag is present) moves it past the context descriptor, and stmmac_jumbo_frm() moves it past the jumbo head descriptors on success.
If we do not roll it back to first_tx, the released VLAN context descriptor (and any jumbo head descriptors) would be left inside the [dirty_tx, cur_tx) in-flight window, so stmmac_tx_clean() would treat them as completed frames, and the next xmit would skip those slots.
Unlike the TSO path, where the allocator uses a local entry and tx_q->cur_tx is only assigned on success, these are shared helpers that advance cur_tx as a side effect, so rolling it back here is the minimal correct fix.
>
>Regards,
>Lorenzo
>
>> + if (has_vlan) {
>> + desc = stmmac_get_tx_desc(priv, tx_q, first_tx);
>> + stmmac_release_tx_desc(priv, desc, priv->descriptor_mode);
>> + }
>>? max_sdu_err:
>>? dev_kfree_skb(skb);
>>? priv->xstats.tx_dropped++;
>>
>> ---
>> base-commit: 893e11787f78e43b534e252249ac3fff4d1333f8
>> change-id: 20260909-stmmac-fix-vlan-desc-leak-f057bb061daa
>>
>> Best regards,
>> --
>> ZhaoJinming <zhaojinming@uniontech.com>
>>
>>
next prev parent reply other threads:[~2026-09-11 8:36 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-10 5:19 [PATCH net] net: stmmac: fix stale descriptors and DMA mapping leak on Tx map failure ZhaoJinming
2026-09-10 9:22 ` Lorenzo Bianconi
2026-09-11 8:34 ` 赵金明 [this message]
[not found] ` <4a07a3d6-b515-43b6-918d-87806c479430@bootlin.com>
2026-09-11 8:40 ` 赵金明
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=30AFF1B9230534C1+202609111634420869983@uniontech.com \
--to=zhaojinming@uniontech.com \
--cc=Jose.Abreu@synopsys.com \
--cc=alexandre.torgue@foss.st.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=kuba@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-stm32@st-md-mailman.stormreply.com \
--cc=lorenzo.bianconi@oss.qualcomm.com \
--cc=maxime.chevallier@bootlin.com \
--cc=mcoquelin.stm32@gmail.com \
--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