From: Paolo Valerio <pvalerio@redhat.com>
To: "Théo Lebrun" <theo.lebrun@bootlin.com>, netdev@vger.kernel.org
Cc: "Nicolas Ferre" <nicolas.ferre@microchip.com>,
"Claudiu Beznea" <claudiu.beznea@tuxon.dev>,
"Andrew Lunn" <andrew+netdev@lunn.ch>,
"David S. Miller" <davem@davemloft.net>,
"Eric Dumazet" <edumazet@google.com>,
"Jakub Kicinski" <kuba@kernel.org>,
"Paolo Abeni" <pabeni@redhat.com>,
"Lorenzo Bianconi" <lorenzo@kernel.org>,
"Thomas Petazzoni" <thomas.petazzoni@bootlin.com>,
"Grégory Clement" <gregory.clement@bootlin.com>,
"Benoît Monin" <benoit.monin@bootlin.com>
Subject: Re: [PATCH RFC net-next 4/6] cadence: macb/gem: add XDP support for gem
Date: Tue, 02 Dec 2025 18:32:41 +0100 [thread overview]
Message-ID: <87bjkgzt52.fsf@redhat.com> (raw)
In-Reply-To: <DEJK1461002Y.TQON2T91OS6B@bootlin.com>
On 27 Nov 2025 at 03:41:56 PM, Théo Lebrun <theo.lebrun@bootlin.com> wrote:
> On Wed Nov 19, 2025 at 2:53 PM CET, Paolo Valerio wrote:
>> @@ -1273,6 +1275,7 @@ struct macb_queue {
>> struct queue_stats stats;
>> struct page_pool *page_pool;
>> struct sk_buff *skb;
>> + struct xdp_rxq_info xdp_q;
>> };
>
> Those are always named `xdp_rxq` inside the kernel, we should stick with
> the calling convention no?
>
sure
>> diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
>> index 5829c1f773dd..53ea1958b8e4 100644
>> --- a/drivers/net/ethernet/cadence/macb_main.c
>> +++ b/drivers/net/ethernet/cadence/macb_main.c
>> @@ -1344,10 +1344,51 @@ static void discard_partial_frame(struct macb_queue *queue, unsigned int begin,
>> */
>> }
>>
>> +static u32 gem_xdp_run(struct macb_queue *queue, struct xdp_buff *xdp,
>> + struct net_device *dev)
>
> Why pass `struct net_device` explicitly? It is in queue->bp->dev.
>
let's avoid this
>> +{
>> + struct bpf_prog *prog;
>> + u32 act = XDP_PASS;
>> +
>> + rcu_read_lock();
>> +
>> + prog = rcu_dereference(queue->bp->prog);
>> + if (!prog)
>> + goto out;
>> +
>> + act = bpf_prog_run_xdp(prog, xdp);
>> + switch (act) {
>> + case XDP_PASS:
>> + goto out;
>> + case XDP_REDIRECT:
>> + if (unlikely(xdp_do_redirect(dev, xdp, prog))) {
>> + act = XDP_DROP;
>> + break;
>> + }
>> + goto out;
>
> Why the `unlikely()`?
>
just expecting the err path to be the exception, although this is not
consistend with the XDP_TX path.
Do you prefer to remove it?
>> + default:
>> + bpf_warn_invalid_xdp_action(dev, prog, act);
>> + fallthrough;
>> + case XDP_ABORTED:
>> + trace_xdp_exception(dev, prog, act);
>> + fallthrough;
>> + case XDP_DROP:
>> + break;
>> + }
>> +
>> + page_pool_put_full_page(queue->page_pool,
>> + virt_to_head_page(xdp->data), true);
>
> Maybe move that to the XDP_DROP, it is the only `break` in the above
> switch statement. It will be used by the default and XDP_ABORTED cases
> through fallthrough. We can avoid the out label and its two gotos that
> way.
>
We'd not put to page pool in case the redirect fails or am I missing
something?
>> static int gem_rx(struct macb_queue *queue, struct napi_struct *napi,
>> int budget)
>> {
>> struct macb *bp = queue->bp;
>> + bool xdp_flush = false;
>> unsigned int len;
>> unsigned int entry;
>> void *data;
>> @@ -1356,9 +1397,11 @@ static int gem_rx(struct macb_queue *queue, struct napi_struct *napi,
>> int count = 0;
>>
>> while (count < budget) {
>> - u32 ctrl;
>> - dma_addr_t addr;
>> bool rxused, first_frame;
>> + struct xdp_buff xdp;
>> + dma_addr_t addr;
>> + u32 ctrl;
>> + u32 ret;
>>
>> entry = macb_rx_ring_wrap(bp, queue->rx_tail);
>> desc = macb_rx_desc(queue, entry);
>> @@ -1403,6 +1446,22 @@ static int gem_rx(struct macb_queue *queue, struct napi_struct *napi,
>> data_len = SKB_WITH_OVERHEAD(bp->rx_buffer_size) - bp->rx_offset;
>> }
>>
>> + if (!(ctrl & MACB_BIT(RX_SOF) && ctrl & MACB_BIT(RX_EOF)))
>> + goto skip_xdp;
>> +
>> + xdp_init_buff(&xdp, bp->rx_buffer_size, &queue->xdp_q);
>> + xdp_prepare_buff(&xdp, data, bp->rx_offset, len,
>> + false);
>> + xdp_buff_clear_frags_flag(&xdp);
>
> You prepare the XDP buffer before checking an XDP program is attached.
> Could we avoid this work? We'd move the xdp_buff preparation into
> gem_xdp_run(), after the RCU pointer dereference.
>
ack, makes sense
>> -static void gem_create_page_pool(struct macb_queue *queue)
>> +static void gem_create_page_pool(struct macb_queue *queue, int qid)
>> {
>> struct page_pool_params pp_params = {
>> .order = 0,
>> .flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV,
>> .pool_size = queue->bp->rx_ring_size,
>> .nid = NUMA_NO_NODE,
>> - .dma_dir = DMA_FROM_DEVICE,
>> + .dma_dir = rcu_access_pointer(queue->bp->prog)
>> + ? DMA_BIDIRECTIONAL
>> + : DMA_FROM_DEVICE,
>
> Ah, that is the reason for page_pool_get_dma_dir() calls!
>
:)
>> static int macb_change_mtu(struct net_device *dev, int new_mtu)
>> {
>> + int frame_size = new_mtu + ETH_HLEN + ETH_FCS_LEN + MACB_MAX_PAD;
>> + struct macb *bp = netdev_priv(dev);
>> + struct bpf_prog *prog = bp->prog;
>
> No fancy RCU macro?
>
right, guess an rcu_access_pointer() call is needed here
>> +static int macb_xdp(struct net_device *dev, struct netdev_bpf *xdp)
>> +{
>> + struct macb *bp = netdev_priv(dev);
>> +
>> + if (!macb_is_gem(bp))
>> + return 0;
>
> Returning 0 sounds like a mistake, -EOPNOTSUPP sounds more appropriate.
>
agreed
>> + switch (xdp->command) {
>> + case XDP_SETUP_PROG:
>> + return gem_xdp_setup(dev, xdp->prog, xdp->extack);
>> + default:
>> + return -EINVAL;
>
> Same here: we want -EOPNOTSUPP. Otherwise caller cannot dissociate an
> unsupported call from one that is supported but failed.
>
ack
>> + }
>> +}
>> +
>> static void gem_update_stats(struct macb *bp)
>> {
>> struct macb_queue *queue;
>> @@ -4390,6 +4529,7 @@ static const struct net_device_ops macb_netdev_ops = {
>> .ndo_hwtstamp_set = macb_hwtstamp_set,
>> .ndo_hwtstamp_get = macb_hwtstamp_get,
>> .ndo_setup_tc = macb_setup_tc,
>> + .ndo_bpf = macb_xdp,
>
> We want it to be "gem_" prefixed as it does not support MACB.
>
ack
> Thanks,
>
> --
> Théo Lebrun, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
next prev parent reply other threads:[~2025-12-02 17:32 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-19 13:53 [PATCH RFC net-next 0/6] net: macb: Add XDP support and page pool integration Paolo Valerio
2025-11-19 13:53 ` [PATCH RFC net-next 1/6] cadence: macb/gem: Add page pool support Paolo Valerio
2025-11-27 13:21 ` Théo Lebrun
2025-12-02 17:30 ` Paolo Valerio
2025-11-19 13:53 ` [PATCH RFC net-next 2/6] cadence: macb/gem: handle multi-descriptor frame reception Paolo Valerio
2025-11-27 13:38 ` Théo Lebrun
2025-12-02 17:32 ` Paolo Valerio
2025-12-08 10:21 ` Théo Lebrun
2025-12-08 10:22 ` [PATCH 1/8] net: macb: move Rx buffers alloc from link up to open Théo Lebrun
2025-12-08 12:53 ` [PATCH RFC net-next 2/6] cadence: macb/gem: handle multi-descriptor frame reception Paolo Valerio
2025-12-09 9:01 ` Théo Lebrun
2025-11-19 13:53 ` [PATCH RFC net-next 3/6] cadence: macb/gem: use the current queue number for stats Paolo Valerio
2025-11-19 13:53 ` [PATCH RFC net-next 4/6] cadence: macb/gem: add XDP support for gem Paolo Valerio
2025-11-27 14:41 ` Théo Lebrun
2025-12-02 17:32 ` Paolo Valerio [this message]
2025-12-08 10:59 ` Théo Lebrun
2025-11-19 13:53 ` [PATCH RFC net-next 5/6] cadence: macb/gem: make tx path skb agnostic Paolo Valerio
2025-11-27 14:49 ` Théo Lebrun
2025-12-02 17:33 ` Paolo Valerio
2025-11-19 13:53 ` [PATCH RFC net-next 6/6] cadence: macb/gem: introduce xmit support Paolo Valerio
2025-11-22 20:49 ` kernel test robot
2025-11-27 15:07 ` Théo Lebrun
2025-12-02 17:34 ` Paolo Valerio
2025-12-08 11:01 ` Théo Lebrun
2025-11-25 16:50 ` [PATCH RFC net-next 0/6] net: macb: Add XDP support and page pool integration Théo Lebrun
2025-11-25 23:11 ` Paolo Valerio
2025-11-26 18:08 ` Théo Lebrun
2025-12-02 17:24 ` Paolo Valerio
2025-12-03 14:28 ` Théo Lebrun
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=87bjkgzt52.fsf@redhat.com \
--to=pvalerio@redhat.com \
--cc=andrew+netdev@lunn.ch \
--cc=benoit.monin@bootlin.com \
--cc=claudiu.beznea@tuxon.dev \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=gregory.clement@bootlin.com \
--cc=kuba@kernel.org \
--cc=lorenzo@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=nicolas.ferre@microchip.com \
--cc=pabeni@redhat.com \
--cc=theo.lebrun@bootlin.com \
--cc=thomas.petazzoni@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.