From: Jakub Kicinski <kuba@kernel.org>
To: pvalerio@redhat.com
Cc: Jakub Kicinski <kuba@kernel.org>,
davem@davemloft.net, claudiu.beznea@tuxon.dev,
nicolas.ferre@microchip.com, edumazet@google.com,
pabeni@redhat.com, theo.lebrun@bootlin.com,
netdev@vger.kernel.org, lorenzo@kernel.org,
andrew+netdev@lunn.ch
Subject: Re: [net-next,v2,8/8] net: macb: introduce xmit support
Date: Mon, 23 Feb 2026 16:09:02 -0800 [thread overview]
Message-ID: <20260224000902.140599-1-kuba@kernel.org> (raw)
In-Reply-To: <20260223182632.1681809-9-pvalerio@redhat.com>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
For local reproduction steps see https://netdev-ai.bots.linux.dev/ai-local.html
---
net: macb: introduce xmit support
This commit adds XDP_TX verdict support and introduces ndo_xdp_xmit
function for redirection. It updates macb_tx_unmap() to handle both
skbs and xdp frames advertising NETDEV_XDP_ACT_NDO_XMIT capability.
> diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
> index 50646ee90672..69392ec0065f 100644
> --- a/drivers/net/ethernet/cadence/macb_main.c
> +++ b/drivers/net/ethernet/cadence/macb_main.c
[ ... ]
> @@ -967,6 +967,17 @@ static int macb_halt_tx(struct macb *bp)
> bp, TSR);
> }
>
> +static void macb_tx_release_buff(void *buff, enum macb_tx_buff_type type, int budget)
> +{
> + if (type == MACB_TYPE_SKB) {
> + napi_consume_skb(buff, budget);
> + } else if (type == MACB_TYPE_XDP_TX) {
> + xdp_return_frame_rx_napi(buff);
^^^^
Can xdp_return_frame_rx_napi() be called in workqueue context?
This function is only safe in NAPI or softirq context because it calls
__xdp_return() with napi_direct=true, which eventually calls
bpf_net_ctx_get_ri() -> bpf_net_ctx_get(), dereferencing
current->bpf_net_context without a NULL check.
In NAPI context, bpf_net_context is set up by bpf_net_ctx_set() in
net_rx_action/napi_poll. In workqueue context, current->bpf_net_context
is NULL.
macb_tx_release_buff() is called from macb_tx_unmap(), which is called
from macb_tx_error_task(). macb_tx_error_task() runs as a workqueue
task, scheduled by:
macb_interrupt() ->
schedule_work(&queue->tx_error_task) ->
macb_tx_error_task() ->
macb_tx_unmap() ->
macb_tx_release_buff(ptr, MACB_TYPE_XDP_TX, 0) ->
xdp_return_frame_rx_napi() ->
__xdp_return(napi_direct=true) ->
xdp_return_frame_no_direct() ->
bpf_net_ctx_get_ri() ->
NULL deref crash
Should this use xdp_return_frame() instead of xdp_return_frame_rx_napi()
when not in NAPI context, similar to how napi_consume_skb() uses the
budget parameter to distinguish contexts (budget=0 means non-NAPI)?
> + } else {
> + xdp_return_frame(buff);
> + }
> +}
> +
[ ... ]
> @@ -1069,6 +1080,10 @@ static void macb_tx_error_task(struct work_struct *work)
> desc = macb_tx_desc(queue, tail);
> ctrl = desc->ctrl;
> tx_buff = macb_tx_buff(queue, tail);
> +
> + if (tx_buff->type != MACB_TYPE_SKB)
> + goto unmap;
> +
> skb = tx_buff->ptr;
Does macb_tx_error_task() hold the necessary locks when accessing the TX
ring?
macb_tx_error_task accesses queue->tx_head (loop boundary in line 1077)
and queue->tx_tail without holding queue->tx_ptr_lock. It only holds
bp->lock.
The new macb_xdp_submit_frame modifies queue->tx_head (line 1461) under
tx_ptr_lock but BEFORE acquiring the nested bp->lock (line 1464).
macb_tx_error_task only calls napi_disable(&queue->napi_tx), so RX NAPI
(which calls gem_xdp_run -> macb_xdp_submit_frame for XDP_TX) remains
active. netif_tx_stop_all_queues does not stop ndo_xdp_xmit (gem_xdp_xmit
-> macb_xdp_submit_frame).
The race can occur:
CPU 0: macb_tx_error_task
- holds bp->lock
- iterates ring using tx_head as boundary
CPU 1: macb_xdp_submit_frame
- acquires tx_ptr_lock
- submits a frame
- updates tx_head
- blocks on bp->lock
CPU 0:
- sees updated tx_head
- iterates into newly submitted frame
- frees its buffer via macb_tx_unmap
- resets tx_head=0, tx_tail=0
CPU 1:
- acquires bp->lock
- kicks TSTART on reset ring
This results in a freed DMA buffer in an active ring, and inconsistent
tx_head/tx_tail state.
[ ... ]
> @@ -1184,6 +1200,7 @@ static int macb_tx_complete(struct macb_queue *queue, int budget)
> spin_lock_irqsave(&queue->tx_ptr_lock, flags);
> head = queue->tx_head;
> for (tail = queue->tx_tail; tail != head && packets < budget; tail++) {
> + void *data = NULL;
> struct macb_tx_buff *tx_buff;
> struct sk_buff *skb;
> struct macb_dma_desc *desc;
[ ... ]
> @@ -1206,11 +1223,16 @@ static int macb_tx_complete(struct macb_queue *queue, int budget)
> for (;; tail++) {
> tx_buff = macb_tx_buff(queue, tail);
>
> - if (tx_buff->type == MACB_TYPE_SKB)
> - skb = tx_buff->ptr;
> + if (tx_buff->type != MACB_TYPE_SKB) {
> + data = tx_buff->ptr;
> + goto unmap;
> + }
>
> /* First, update TX stats if needed */
> - if (skb) {
> + if (tx_buff->type == MACB_TYPE_SKB && tx_buff->ptr) {
^^^^
This isn't a bug, but could the type check here be simplified?
At line 1226, non-SKB types are filtered out with 'if (tx_buff->type !=
MACB_TYPE_SKB) goto unmap'. At line 1232, the condition checks the type
again with 'if (tx_buff->type == MACB_TYPE_SKB && tx_buff->ptr)', but at
this point the type is always MACB_TYPE_SKB.
The condition could be simplified to 'if (tx_buff->ptr)' for clarity.
> + data = tx_buff->ptr;
> + skb = tx_buff->ptr;
> +
[ ... ]
prev parent reply other threads:[~2026-02-24 0:09 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-23 18:26 [PATCH net-next v2 0/8] net: macb: Add XDP support and page pool integration Paolo Valerio
2026-02-23 18:26 ` [PATCH net-next v2 1/8] net: macb: move Rx buffers alloc from link up to open Paolo Valerio
2026-02-24 0:08 ` [net-next,v2,1/8] " Jakub Kicinski
2026-02-25 18:29 ` Paolo Valerio
2026-02-23 18:26 ` [PATCH net-next v2 2/8] net: macb: rename rx_skbuff into rx_buff Paolo Valerio
2026-02-23 18:26 ` [PATCH net-next v2 3/8] net: macb: Add page pool support handle multi-descriptor frame rx Paolo Valerio
2026-02-23 18:26 ` [PATCH net-next v2 4/8] net: macb: use the current queue number for stats Paolo Valerio
2026-02-23 18:26 ` [PATCH net-next v2 5/8] net: macb: add XDP support for gem Paolo Valerio
2026-02-23 23:23 ` kernel test robot
2026-02-24 0:08 ` [net-next,v2,5/8] " Jakub Kicinski
2026-02-25 18:30 ` Paolo Valerio
2026-02-27 10:52 ` Théo Lebrun
2026-02-28 13:49 ` Claudiu Beznea
2026-02-23 18:26 ` [PATCH net-next v2 6/8] net: macb: make macb_tx_skb generic Paolo Valerio
2026-02-24 0:08 ` [net-next,v2,6/8] " Jakub Kicinski
2026-02-23 18:26 ` [PATCH net-next v2 7/8] net: macb: make tx path skb agnostic Paolo Valerio
2026-02-24 0:09 ` [net-next,v2,7/8] " Jakub Kicinski
2026-02-25 18:36 ` Paolo Valerio
2026-02-23 18:26 ` [PATCH net-next v2 8/8] net: macb: introduce xmit support Paolo Valerio
2026-02-24 0:09 ` Jakub Kicinski [this message]
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=20260224000902.140599-1-kuba@kernel.org \
--to=kuba@kernel.org \
--cc=andrew+netdev@lunn.ch \
--cc=claudiu.beznea@tuxon.dev \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=lorenzo@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=nicolas.ferre@microchip.com \
--cc=pabeni@redhat.com \
--cc=pvalerio@redhat.com \
--cc=theo.lebrun@bootlin.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