From nobody Fri Apr 10 04:15:43 2026 Received: from smtpout-04.galae.net (smtpout-04.galae.net [185.171.202.116]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E15693D75A1 for ; Wed, 4 Mar 2026 18:23:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.171.202.116 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772648641; cv=none; b=GFtj+7/eYMtCphTqyCqb6bq3kKrEAVqwd2Q2nzPq/4lb1o2VNSNUSUYdPhD9Nq2ZY+nPK+ybT94yNN3mrbLdFEsJYAwt3XkIqPbp71afWK/uU3qEfVG0khlNyBjv+ULnxO2rru8hID6QE3uJ1scUpeO8LS5uBkIzEGPEFeDVmTM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772648641; c=relaxed/simple; bh=gExp/m0uv0I2CpCXmMKevKdtVBq/K6XyZ9iXZ8ojeYw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=kX5V1FjBMlq//Q+Pr+/xJH5+kajfbYNWC4IkKrHFlKCpYXG5H7t1Ggzv7eTAmbmmMFuMCjFVMPhh2X6/ceZ1yw8CpXRWplDBCfpcrLmENom34381m2sFWQANRY2MGLHKfEean+LGtkUqMOono2K59hSrITXXgP6AQ1d1X910jdw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=xYj+FOig; arc=none smtp.client-ip=185.171.202.116 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="xYj+FOig" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id ACA01C143E5; Wed, 4 Mar 2026 18:24:16 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 788015FF5C; Wed, 4 Mar 2026 18:23:58 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id CB476103694F8; Wed, 4 Mar 2026 19:23:55 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1772648637; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=dzl/qreKh68sppWaNDnY8qNK5Kh//0XfSDDQisblgGk=; b=xYj+FOigGbPONNXz/Vyy9F0IOlMRie/Vb9p8u3BKuobRRDcyImEvUHtrnBoXEkBiJTou8g fKIai177jJ9uOXnxbkdd5FQVgQI/2zCoGy6zcR47FLilNGTCtV0OmXCeJ7E/qpz+gvEyN1 sP3juI9IUHT+TbU0vjj+6qyIuK3Kydwha+QvXXmAwEw0M6VtmqhzALeu1PGS9g+utnt4jV bHC0DmV0gDnA6U2E9lijBCaETWvg00fuOUiwLXXApuHi+BAVrra3bg5nMvjydtm3LLpn/p gbxl5PiQJe++4Jgd7htOqpn/nNh3BqggfLit+ik2ofvvWHGRU9myYw9orD01XQ== From: =?utf-8?q?Th=C3=A9o_Lebrun?= Date: Wed, 04 Mar 2026 19:23:46 +0100 Subject: [PATCH net-next 3/8] net: macb: account for stats in Tx XDP codepaths Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260304-macb-xsk-v1-3-3d036076abf5@bootlin.com> References: <20260304-macb-xsk-v1-0-3d036076abf5@bootlin.com> In-Reply-To: <20260304-macb-xsk-v1-0-3d036076abf5@bootlin.com> To: Nicolas Ferre , Claudiu Beznea , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Alexei Starovoitov , Daniel Borkmann , Jesper Dangaard Brouer , John Fastabend , Stanislav Fomichev , Richard Cochran Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, Vladimir Kondratiev , Gregory CLEMENT , =?utf-8?q?Beno=C3=AEt_Monin?= , Tawfik Bayouk , Thomas Petazzoni , Maxime Chevallier , =?utf-8?q?Th=C3=A9o_Lebrun?= X-Mailer: b4 0.14.3 X-Last-TLS-Session-Version: TLSv1.3 macb_tx_complete() processing loop assumes a packet is composed of multiple frames and composes around this idea. However, this is only true in the SKB case ie `tx_buff->type =3D=3D MACB_TYPE_SKB`. Rework macb_tx_complete() to bring the tx_buff->type switch statement outside and the frame iteration loop now lives only inside the SKB case. Fix Tx XDP stats that were not accounted for, in the XDP_TX|NDO cases. Only increment statistics once per macb_tx_complete() call rather than once per frame. The `bytes` and `packets` stack variables now gets incremented for completed XDP XMIT/TX packets. This implies the DQL subsystem through netdev_tx_completed_queue() now gets notified of those packets completing. We must therefore also report those bytes as sent, using netdev_tx_sent_queue(), in macb_xdp_submit_frame() called by: - Rx XDP programs returning action XDP_TX and, - the .ndo_xdp_xmit() callback. Incrementing `packets` also implies XDP packets are accounted for in our NAPI budget calculation. Signed-off-by: Th=C3=A9o Lebrun --- drivers/net/ethernet/cadence/macb_main.c | 71 +++++++++++++++-------------= ---- 1 file changed, 33 insertions(+), 38 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/etherne= t/cadence/macb_main.c index 1aa90499343a..c1677f1d8f23 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -1212,7 +1212,7 @@ static int macb_tx_complete(struct macb_queue *queue,= int budget) { struct macb *bp =3D queue->bp; unsigned long flags; - int skb_packets =3D 0; + int xsk_frames =3D 0; unsigned int tail; unsigned int head; u16 queue_index; @@ -1227,7 +1227,6 @@ static int macb_tx_complete(struct macb_queue *queue,= int budget) struct macb_tx_buff *tx_buff; struct macb_dma_desc *desc; struct sk_buff *skb; - void *data =3D NULL; u32 ctrl; =20 desc =3D macb_tx_desc(queue, tail); @@ -1243,52 +1242,46 @@ static int macb_tx_complete(struct macb_queue *queu= e, int budget) if (!(ctrl & MACB_BIT(TX_USED))) break; =20 - /* Process all buffers of the current transmitted frame */ - for (;; tail++) { - tx_buff =3D macb_tx_buff(queue, tail); + tx_buff =3D macb_tx_buff(queue, tail); =20 - if (tx_buff->type !=3D MACB_TYPE_SKB) { - data =3D tx_buff->ptr; - packets++; - goto unmap; + switch (tx_buff->type) { + case MACB_TYPE_SKB: + /* Process all buffers of the current transmitted frame */ + while (!tx_buff->ptr) { + macb_tx_unmap(bp, tx_buff, budget); + tail++; + tx_buff =3D macb_tx_buff(queue, tail); } =20 - /* First, update TX stats if needed */ - if (tx_buff->ptr) { - data =3D tx_buff->ptr; - skb =3D tx_buff->ptr; + skb =3D tx_buff->ptr; =20 - if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && - !ptp_one_step_sync(skb)) - gem_ptp_do_txstamp(bp, skb, desc); + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && + !ptp_one_step_sync(skb)) + gem_ptp_do_txstamp(bp, skb, desc); =20 - netdev_vdbg(bp->dev, "skb %u (data %p) TX complete\n", - macb_tx_ring_wrap(bp, tail), - skb->data); - bp->dev->stats.tx_packets++; - queue->stats.tx_packets++; - bp->dev->stats.tx_bytes +=3D skb->len; - queue->stats.tx_bytes +=3D skb->len; - skb_packets++; - packets++; - bytes +=3D skb->len; - } + netdev_vdbg(bp->dev, "skb %u (data %p) TX complete\n", + macb_tx_ring_wrap(bp, tail), + skb->data); + bytes +=3D skb->len; + break; =20 -unmap: - /* Now we can safely release resources */ - macb_tx_unmap(bp, tx_buff, budget); - - /* data is set only for the last buffer of the frame. - * WARNING: at this point the buffer has been freed by - * macb_tx_unmap(). - */ - if (data) - break; + case MACB_TYPE_XDP_TX: + case MACB_TYPE_XDP_NDO: + bytes +=3D tx_buff->size; + break; } + + packets++; + macb_tx_unmap(bp, tx_buff, budget); } =20 + bp->dev->stats.tx_packets +=3D packets; + queue->stats.tx_packets +=3D packets; + bp->dev->stats.tx_bytes +=3D bytes; + queue->stats.tx_bytes +=3D bytes; + netdev_tx_completed_queue(netdev_get_tx_queue(bp->dev, queue_index), - skb_packets, bytes); + packets, bytes); =20 queue->tx_tail =3D tail; if (__netif_subqueue_stopped(bp->dev, queue_index) && @@ -1529,6 +1522,8 @@ static int macb_xdp_submit_frame(struct macb *bp, str= uct xdp_frame *xdpf, macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART)); spin_unlock(&bp->lock); =20 + netdev_tx_sent_queue(netdev_get_tx_queue(bp->dev, queue_index), xdpf->len= ); + if (CIRC_SPACE(queue->tx_head, queue->tx_tail, bp->tx_ring_size) < 1) netif_stop_subqueue(dev, queue_index); =20 --=20 2.53.0