From: Nicolai Buchwitz <nb@tipi-net.de>
To: netdev@vger.kernel.org
Cc: Justin Chen <justin.chen@broadcom.com>,
Simon Horman <horms@kernel.org>,
Mohsin Bashir <mohsin.bashr@gmail.com>,
Doug Berger <opendmb@gmail.com>,
Florian Fainelli <florian.fainelli@broadcom.com>,
Broadcom internal kernel review list
<bcm-kernel-feedback-list@broadcom.com>,
Andrew Lunn <andrew+netdev@lunn.ch>,
Eric Dumazet <edumazet@google.com>,
Paolo Abeni <pabeni@redhat.com>,
"David S. Miller" <davem@davemloft.net>,
Jakub Kicinski <kuba@kernel.org>,
Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Jesper Dangaard Brouer <hawk@kernel.org>,
John Fastabend <john.fastabend@gmail.com>,
Stanislav Fomichev <sdf@fomichev.me>,
linux-kernel@vger.kernel.org, bpf@vger.kernel.org
Subject: Re: [PATCH net-next v6 4/7] net: bcmgenet: add XDP_TX support
Date: Mon, 06 Apr 2026 20:52:37 +0200 [thread overview]
Message-ID: <97d07c9ee2fa450fcf5329847491e392@tipi-net.de> (raw)
In-Reply-To: <20260406083536.839517-5-nb@tipi-net.de>
On 6.4.2026 10:35, Nicolai Buchwitz wrote:
> Implement XDP_TX using ring 16 (DESC_INDEX), the hardware default
> descriptor ring, dedicated to XDP TX for isolation from SKB TX queues.
> [...]
> +
> + if (dma_map) {
> + void *tsb_start;
> +
> + /* The GENET MAC has TBUF_64B_EN set globally, so hardware
> + * expects a 64-byte TSB prefix on every TX buffer. For
> + * redirected frames (ndo_xdp_xmit) we prepend a zeroed TSB
> + * using the frame's headroom.
> + */
> + if (unlikely(xdpf->headroom < sizeof(struct status_64))) {
> + bcmgenet_put_txcb(priv, ring);
> + spin_unlock(&ring->lock);
> + return false;
> + }
> +
> + tsb_start = xdpf->data - sizeof(struct status_64);
> + memset(tsb_start, 0, sizeof(struct status_64));
Sashiko:
Does this memset() overwrite the struct xdp_frame? The xdp_frame is
typically
stored in the headroom immediately before xdpf->data (or before the
metadata).
If the 64-byte status_64 block is zeroed out here, could it destroy the
xdp_frame memory structure and cause a panic when xdp_return_frame() is
later
called during TX completion?
Reponse:
No. The xdp_frame struct ends at data_hard_start + sizeof(xdp_frame).
The headroom (xdpf->headroom) is the gap between that and xdpf->data.
The TSB is written at xdpf->data - 64, which falls inside the headroom,
after
the xdp_frame. The check xdpf->headroom < sizeof(struct status_64)
prevents overlap.
> +
> + dma_len = xdpf->len + sizeof(struct status_64);
> + mapping = dma_map_single(kdev, tsb_start, dma_len,
> + DMA_TO_DEVICE);
> + if (dma_mapping_error(kdev, mapping)) {
> + tx_cb_ptr->skb = NULL;
> + tx_cb_ptr->xdpf = NULL;
> + bcmgenet_put_txcb(priv, ring);
> + spin_unlock(&ring->lock);
> + return false;
> + }
> + } else {
> + struct page *page = virt_to_page(xdpf->data);
> +
> + /* For local XDP_TX the caller already prepended the TSB
> + * into xdpf->data/len, so dma_len == xdpf->len.
> + */
> + dma_len = xdpf->len;
> + mapping = page_pool_get_dma_addr(page) +
> + sizeof(*xdpf) + xdpf->headroom;
Sashiko:
Is this DMA address calculation correct? It evaluates to the offset of
xdp->data_meta relative to xdp->data_hard_start, which completely drops
the
GENET_XDP_HEADROOM (256 bytes) offset applied to the page pool base
address.
Also, if metadata is present, this will point to the metadata instead of
xdpf->data. Could this cause the hardware to read the wrong memory
location
for the Transmit Status Block and truncate the payload?
Reponse:
Correct. page_pool_get_dma_addr() returns the DMA address of the page
start,
not offset by the pool's .offset. sizeof(*xdpf) + xdpf->headroom equals
xdpf->data - data_hard_start, pointing to the TSB. No metadata issue:
for local XDP_TX, data already includes the prepended TSB.
> + dma_sync_single_for_device(kdev, mapping, dma_len,
> [...]
> }
> @@ -2542,9 +2684,15 @@ static int bcmgenet_rx_poll(struct napi_struct
> *napi, int budget)
> {
> struct bcmgenet_rx_ring *ring = container_of(napi,
> struct bcmgenet_rx_ring, napi);
> + struct bcmgenet_priv *priv = ring->priv;
> struct dim_sample dim_sample = {};
> unsigned int work_done;
>
> + /* Reclaim completed XDP TX frames (ring 16 has no interrupt) */
> + if (priv->xdp_tx_ring.free_bds < priv->xdp_tx_ring.size)
> + bcmgenet_tx_reclaim(priv->dev,
> + &priv->xdp_tx_ring, false);
Sashiko:
Since the XDP TX ring capacity is 32 (GENET_Q16_TX_BD_CNT) and the NAPI
budget can be up to 64, could a burst of XDP_TX packets exhaust the TX
ring?
Because the reclaim only happens once at the beginning of the poll,
would
subsequent XDP_TX packets within the same poll be dropped when the ring
fills up?
Reponse:
By design. If the ring fills, frames are dropped, which is kinda
standard XDP backpressure.
Same approach as bnxt, mvneta, and other piggybacked-reclaim drivers.
Adding mid-poll reclaim would add complexity for probably minimal
benefit at 1Gbps.
> [...]
next prev parent reply other threads:[~2026-04-06 18:52 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-06 8:35 [PATCH net-next v6 0/7] net: bcmgenet: add XDP support Nicolai Buchwitz
2026-04-06 8:35 ` [PATCH net-next v6 1/7] net: bcmgenet: convert RX path to page_pool Nicolai Buchwitz
2026-04-06 17:10 ` Florian Fainelli
2026-04-06 8:35 ` [PATCH net-next v6 2/7] net: bcmgenet: register xdp_rxq_info for each RX ring Nicolai Buchwitz
2026-04-06 17:22 ` Florian Fainelli
2026-04-06 8:35 ` [PATCH net-next v6 3/7] net: bcmgenet: add basic XDP support (PASS/DROP) Nicolai Buchwitz
2026-04-06 18:57 ` Nicolai Buchwitz
2026-04-06 8:35 ` [PATCH net-next v6 4/7] net: bcmgenet: add XDP_TX support Nicolai Buchwitz
2026-04-06 18:52 ` Nicolai Buchwitz [this message]
2026-04-06 8:35 ` [PATCH net-next v6 5/7] net: bcmgenet: add XDP_REDIRECT and ndo_xdp_xmit support Nicolai Buchwitz
2026-04-06 8:35 ` [PATCH net-next v6 6/7] net: bcmgenet: add XDP statistics counters Nicolai Buchwitz
2026-04-06 17:20 ` Florian Fainelli
2026-04-06 8:35 ` [PATCH net-next v6 7/7] net: bcmgenet: reject MTU changes incompatible with XDP Nicolai Buchwitz
2026-04-06 17:19 ` Florian Fainelli
2026-04-06 18:30 ` Mohsin Bashir
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=97d07c9ee2fa450fcf5329847491e392@tipi-net.de \
--to=nb@tipi-net.de \
--cc=andrew+netdev@lunn.ch \
--cc=ast@kernel.org \
--cc=bcm-kernel-feedback-list@broadcom.com \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=florian.fainelli@broadcom.com \
--cc=hawk@kernel.org \
--cc=horms@kernel.org \
--cc=john.fastabend@gmail.com \
--cc=justin.chen@broadcom.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mohsin.bashr@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=opendmb@gmail.com \
--cc=pabeni@redhat.com \
--cc=sdf@fomichev.me \
/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