public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
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;
> +

[ ... ]

      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