From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (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 004283D5647 for ; Wed, 4 Mar 2026 18:24:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772648691; cv=none; b=SJCJjLKibNh+W7RjAx62qdIRN0WE5kSqyXpRySISaBwZsOguSc5cxiKk92mcgukaQ5oZHKbs0COyhpAyko/o2e/0MWZlKhytTt5e5ShFdfA+KijVB3Oqk2cHt7+i6Mn/zVbs/vT3pjG4uQKk78GPtiEFsfWLxdpyd4FUBOCm8eI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772648691; c=relaxed/simple; bh=gExp/m0uv0I2CpCXmMKevKdtVBq/K6XyZ9iXZ8ojeYw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=oYZ9WGzlXLqMUZoSkZtppYK++T8BB+cx+KS5VrjKwjVYvGGCCvmZSyit2BscGsTQPrHa9645IQ34Z9iBkduOTdJ9H9EdYJeZtPQDspimngd+MBN0N1iuxmv9XXWRU6/yWzik3m/tEOFdOf/E07B5PZVT3cE4RKXoNCpgjIlHWZQ= 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=v65Ipeee; arc=none smtp.client-ip=185.246.85.4 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="v65Ipeee" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id CF5764E42543; Wed, 4 Mar 2026 18:24:48 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id A34385FF5C; Wed, 4 Mar 2026 18:24:48 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 29C5B103694F8; Wed, 4 Mar 2026 19:24:45 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1772648687; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=dzl/qreKh68sppWaNDnY8qNK5Kh//0XfSDDQisblgGk=; b=v65IpeeejbD0oHoj2meGzZPPVvCHaT8vnUuvyWBLILIUIM3STpr8+oLdKAZVKGrwGIxvcL XZRKNaLaWRf7yCsy394Tz61ZySsEVpw3E5IzZkqC4IYO2sYKvFdFN0p/o7nTq5KIX0b+Le h0CHd6/GGts0PClVorezX8tHnySON4q4P9jb1R8VpmJW8W4qdET70fhD5JuEuD4eddaE0G 11fOGaipy58b6bKhGFQkBRUAO4iad+WUd0LfFxiemfEW8Dwy2lOi5PIq2vLK16sxDuITHT FeiFl/VfYJALFEVcVvxkBrdMGXsw6DFrl10mky0JBmwp2j1e8Y9BCS1hOB0S4A== From: =?utf-8?q?Th=C3=A9o_Lebrun?= Date: Wed, 04 Mar 2026 19:24:26 +0100 Subject: [PATCH net-next 3/8] net: macb: account for stats in Tx XDP codepaths Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit Message-Id: <20260304-macb-xsk-v1-3-ba2ebe2bdaa3@bootlin.com> References: <20260304-macb-xsk-v1-0-ba2ebe2bdaa3@bootlin.com> In-Reply-To: <20260304-macb-xsk-v1-0-ba2ebe2bdaa3@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 == 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éo 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/ethernet/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 = queue->bp; unsigned long flags; - int skb_packets = 0; + int xsk_frames = 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 = NULL; u32 ctrl; desc = macb_tx_desc(queue, tail); @@ -1243,52 +1242,46 @@ static int macb_tx_complete(struct macb_queue *queue, int budget) if (!(ctrl & MACB_BIT(TX_USED))) break; - /* Process all buffers of the current transmitted frame */ - for (;; tail++) { - tx_buff = macb_tx_buff(queue, tail); + tx_buff = macb_tx_buff(queue, tail); - if (tx_buff->type != MACB_TYPE_SKB) { - data = 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 = macb_tx_buff(queue, tail); } - /* First, update TX stats if needed */ - if (tx_buff->ptr) { - data = tx_buff->ptr; - skb = tx_buff->ptr; + skb = tx_buff->ptr; - 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); - 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 += skb->len; - queue->stats.tx_bytes += skb->len; - skb_packets++; - packets++; - bytes += skb->len; - } + netdev_vdbg(bp->dev, "skb %u (data %p) TX complete\n", + macb_tx_ring_wrap(bp, tail), + skb->data); + bytes += skb->len; + break; -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 += tx_buff->size; + break; } + + packets++; + macb_tx_unmap(bp, tx_buff, budget); } + bp->dev->stats.tx_packets += packets; + queue->stats.tx_packets += packets; + bp->dev->stats.tx_bytes += bytes; + queue->stats.tx_bytes += bytes; + netdev_tx_completed_queue(netdev_get_tx_queue(bp->dev, queue_index), - skb_packets, bytes); + packets, bytes); queue->tx_tail = tail; if (__netif_subqueue_stopped(bp->dev, queue_index) && @@ -1529,6 +1522,8 @@ static int macb_xdp_submit_frame(struct macb *bp, struct xdp_frame *xdpf, macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART)); spin_unlock(&bp->lock); + 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); -- 2.53.0