All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net] net: mana: report RX checksum offload for IPv6
@ 2026-11-09 14:28 Hamza Mahfooz
  2026-11-10 14:29 ` sashiko-bot
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Hamza Mahfooz @ 2026-11-09 14:28 UTC (permalink / raw)
  To: netdev
  Cc: Haiyang Zhang, Wei Liu, Dexuan Cui, Andrew Lunn, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
	Stephen Hemminger, linux-hyperv, Hamza Mahfooz, stable

The hardware validates TCP and UDP checksums for both IPv4 and IPv6 and
reports the result in rx_tcp_csum_succeed and rx_udp_csum_succeed.
However, mana_rx_skb() also requires rx_iphdr_csum_succeed before it
sets CHECKSUM_UNNECESSARY. That bit is only set for IPv4 (since IPv6
has no header checksum), so IPv6 TCP and UDP traffic is always
checksummed again in software.

So, only look at the L4 result. For IPv4 this makes no material
difference since CHECKSUM_UNNECESSARY only covers the L4 checksum, and
ip_rcv_core() always verifies the IPv4 header checksum in software.

Between two Azure Standard_E16s_v6 VMs (VF enabled), IPv6 TCP and UDP
packets (including VXLAN over IPv6), now arrive with
CHECKSUM_UNNECESSARY instead of CHECKSUM_NONE, so GRO no longer
checksums them in software. Calls to __skb_gro_checksum_complete() on
the receiver during an 8 second iperf3 run:

                               before    after
  TCP/IPv4, 12.2 Gbps              23       28
  TCP/IPv6, 12.1 Gbps         8728419       25
  UDP/IPv6, 1.5 Gbps          1071380       20
  TCP/VXLAN/IPv6, 10.9 Gbps   7934373       18

Cc: stable@vger.kernel.org
Fixes: ca9c54d2d6a5 ("net: mana: Add a driver for Microsoft Azure Network Adapter (MANA)")
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: Hamza Mahfooz <hamzamahfooz@linux.microsoft.com>
---
 drivers/net/ethernet/microsoft/mana/mana_en.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
index e6d494df22e4..05bd4b4b8349 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
@@ -2179,10 +2179,9 @@ static void mana_rx_skb(void *buf_va, bool from_pool,
 	skb_checksum_none_assert(skb);
 	skb_record_rx_queue(skb, rxq_idx);
 
-	if ((ndev->features & NETIF_F_RXCSUM) && cqe->rx_iphdr_csum_succeed) {
-		if (cqe->rx_tcp_csum_succeed || cqe->rx_udp_csum_succeed)
-			skb->ip_summed = CHECKSUM_UNNECESSARY;
-	}
+	if ((ndev->features & NETIF_F_RXCSUM) &&
+	    (cqe->rx_tcp_csum_succeed || cqe->rx_udp_csum_succeed))
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
 
 	if (cqe->rx_hashtype != 0 && (ndev->features & NETIF_F_RXHASH)) {
 		if (cqe->rx_hashtype & MANA_HASH_L4)
-- 
2.56.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH net] net: mana: report RX checksum offload for IPv6
  2026-11-09 14:28 [PATCH net] net: mana: report RX checksum offload for IPv6 Hamza Mahfooz
@ 2026-11-10 14:29 ` sashiko-bot
  2026-11-10 15:41   ` Hamza Mahfooz
  2026-11-12 17:10 ` patchwork-bot+netdevbpf
  2026-11-13  2:31 ` netdev-bot+sashiko
  2 siblings, 1 reply; 5+ messages in thread
From: sashiko-bot @ 2026-11-10 14:29 UTC (permalink / raw)
  To: Hamza Mahfooz; +Cc: linux-hyperv

Thank you for your contribution! Sashiko AI review found no new issues
in this patch, but noticed 1 related pre-existing issue it does not
introduce:
- [High] net: mana: memory leak on XDP drop path in mana_rx_skb() [1]
--

commit 44321b6481b9b9f9a70166beb9fc63a817e238f6
Author: Hamza Mahfooz <hamzamahfooz@linux.microsoft.com>

net: mana: report RX checksum offload for IPv6

This commit removes the rx_iphdr_csum_succeed check in mana_rx_skb() so
that IPv6 TCP and UDP packets with validated L4 checksums receive
CHECKSUM_UNNECESSARY.

> diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
> index e6d494df22e4d..05bd4b4b8349e 100644
> --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
> +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
> @@ -2179,10 +2179,9 @@ static void mana_rx_skb(void *buf_va, bool from_pool,
>  	skb_checksum_none_assert(skb);
>  	skb_record_rx_queue(skb, rxq_idx);
>  
> -	if ((ndev->features & NETIF_F_RXCSUM) && cqe->rx_iphdr_csum_succeed) {
> -		if (cqe->rx_tcp_csum_succeed || cqe->rx_udp_csum_succeed)
> -			skb->ip_summed = CHECKSUM_UNNECESSARY;
> -	}
> +	if ((ndev->features & NETIF_F_RXCSUM) &&
> +	    (cqe->rx_tcp_csum_succeed || cqe->rx_udp_csum_succeed))
> +		skb->ip_summed = CHECKSUM_UNNECESSARY;

[Severity: High]
This problem wasn't introduced by this patch, but can mana_rx_skb() leak
rxq->xdp_save_va [1] on its drop path when rxq->frag_count > 1?

When a pre-allocated buffer (from_pool == false) is dropped, mana_rx_skb()
stores buf_va in rxq->xdp_save_va for reuse:

drivers/net/ethernet/microsoft/mana/mana_en.c:mana_rx_skb() {
	...
drop:
	if (from_pool) {
		...
	} else {
		WARN_ON_ONCE(rxq->xdp_save_va);
		/* Save for reuse */
		rxq->xdp_save_va = buf_va;
	}
}

However, mana_get_rxfrag() only checks and reclaims rxq->xdp_save_va when
rxq->frag_count == 1:

drivers/net/ethernet/microsoft/mana/mana_en.c:mana_get_rxfrag() {
	...
	if (rxq->frag_count == 1) {
		/* Reuse XDP dropped page if available */
		if (rxq->xdp_save_va) {
			va = rxq->xdp_save_va;
			page = virt_to_head_page(va);
			rxq->xdp_save_va = NULL;
		...
		return va;
	}

	page =  page_pool_dev_alloc_frag(rxq->page_pool, &offset,
					 rxq->alloc_size);
}

When rxq->frag_count > 1, mana_get_rxfrag() ignores rxq->xdp_save_va and
allocates a new fragment from the page pool, so a subsequent drop of a
pre-allocated buffer triggers the WARN_ON_ONCE() and overwrites
rxq->xdp_save_va, leaking the saved page.

[1] https://sashiko.dev/#/bug/linux-2ba39e78-7dc4-4027-a76e-f2d315147bad

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261109142856.779955-1-hamzamahfooz@linux.microsoft.com?part=1

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net] net: mana: report RX checksum offload for IPv6
  2026-11-10 14:29 ` sashiko-bot
@ 2026-11-10 15:41   ` Hamza Mahfooz
  0 siblings, 0 replies; 5+ messages in thread
From: Hamza Mahfooz @ 2026-11-10 15:41 UTC (permalink / raw)
  To: sashiko-reviews; +Cc: linux-hyperv

On Tue, Nov 10, 2026 at 02:29:17PM +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found no new issues
> in this patch, but noticed 1 related pre-existing issue it does not
> introduce:
> - [High] net: mana: memory leak on XDP drop path in mana_rx_skb() [1]
> --
> 
> commit 44321b6481b9b9f9a70166beb9fc63a817e238f6
> Author: Hamza Mahfooz <hamzamahfooz@linux.microsoft.com>
> 
> net: mana: report RX checksum offload for IPv6
> 
> This commit removes the rx_iphdr_csum_succeed check in mana_rx_skb() so
> that IPv6 TCP and UDP packets with validated L4 checksums receive
> CHECKSUM_UNNECESSARY.
> 
> > diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
> > index e6d494df22e4d..05bd4b4b8349e 100644
> > --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
> > +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
> > @@ -2179,10 +2179,9 @@ static void mana_rx_skb(void *buf_va, bool from_pool,
> >  	skb_checksum_none_assert(skb);
> >  	skb_record_rx_queue(skb, rxq_idx);
> >  
> > -	if ((ndev->features & NETIF_F_RXCSUM) && cqe->rx_iphdr_csum_succeed) {
> > -		if (cqe->rx_tcp_csum_succeed || cqe->rx_udp_csum_succeed)
> > -			skb->ip_summed = CHECKSUM_UNNECESSARY;
> > -	}
> > +	if ((ndev->features & NETIF_F_RXCSUM) &&
> > +	    (cqe->rx_tcp_csum_succeed || cqe->rx_udp_csum_succeed))
> > +		skb->ip_summed = CHECKSUM_UNNECESSARY;
> 
> [Severity: High]
> This problem wasn't introduced by this patch, but can mana_rx_skb() leak
> rxq->xdp_save_va [1] on its drop path when rxq->frag_count > 1?
> 
> When a pre-allocated buffer (from_pool == false) is dropped, mana_rx_skb()
> stores buf_va in rxq->xdp_save_va for reuse:
> 
> drivers/net/ethernet/microsoft/mana/mana_en.c:mana_rx_skb() {
> 	...
> drop:
> 	if (from_pool) {
> 		...
> 	} else {
> 		WARN_ON_ONCE(rxq->xdp_save_va);
> 		/* Save for reuse */
> 		rxq->xdp_save_va = buf_va;
> 	}
> }
> 
> However, mana_get_rxfrag() only checks and reclaims rxq->xdp_save_va when
> rxq->frag_count == 1:
> 
> drivers/net/ethernet/microsoft/mana/mana_en.c:mana_get_rxfrag() {
> 	...
> 	if (rxq->frag_count == 1) {
> 		/* Reuse XDP dropped page if available */
> 		if (rxq->xdp_save_va) {
> 			va = rxq->xdp_save_va;
> 			page = virt_to_head_page(va);
> 			rxq->xdp_save_va = NULL;
> 		...
> 		return va;
> 	}
> 
> 	page =  page_pool_dev_alloc_frag(rxq->page_pool, &offset,
> 					 rxq->alloc_size);
> }
> 
> When rxq->frag_count > 1, mana_get_rxfrag() ignores rxq->xdp_save_va and
> allocates a new fragment from the page pool, so a subsequent drop of a
> pre-allocated buffer triggers the WARN_ON_ONCE() and overwrites
> rxq->xdp_save_va, leaking the saved page.
> 

Since, this is an existing issue, I will fix it in it's own patch.

> [1] https://sashiko.dev/#/bug/linux-2ba39e78-7dc4-4027-a76e-f2d315147bad
> 
> -- 
> Sashiko AI review · https://sashiko.dev/#/patchset/20261109142856.779955-1-hamzamahfooz@linux.microsoft.com?part=1

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net] net: mana: report RX checksum offload for IPv6
  2026-11-09 14:28 [PATCH net] net: mana: report RX checksum offload for IPv6 Hamza Mahfooz
  2026-11-10 14:29 ` sashiko-bot
@ 2026-11-12 17:10 ` patchwork-bot+netdevbpf
  2026-11-13  2:31 ` netdev-bot+sashiko
  2 siblings, 0 replies; 5+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-11-12 17:10 UTC (permalink / raw)
  To: Hamza Mahfooz
  Cc: netdev, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
	kuba, pabeni, horms, stephen, linux-hyperv, stable

Hello:

This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Mon,  9 Nov 2026 09:28:56 -0500 you wrote:
> The hardware validates TCP and UDP checksums for both IPv4 and IPv6 and
> reports the result in rx_tcp_csum_succeed and rx_udp_csum_succeed.
> However, mana_rx_skb() also requires rx_iphdr_csum_succeed before it
> sets CHECKSUM_UNNECESSARY. That bit is only set for IPv4 (since IPv6
> has no header checksum), so IPv6 TCP and UDP traffic is always
> checksummed again in software.
> 
> [...]

Here is the summary with links:
  - [net] net: mana: report RX checksum offload for IPv6
    https://git.kernel.org/netdev/net/c/bbcd02741c4c

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net] net: mana: report RX checksum offload for IPv6
  2026-11-09 14:28 [PATCH net] net: mana: report RX checksum offload for IPv6 Hamza Mahfooz
  2026-11-10 14:29 ` sashiko-bot
  2026-11-12 17:10 ` patchwork-bot+netdevbpf
@ 2026-11-13  2:31 ` netdev-bot+sashiko
  2 siblings, 0 replies; 5+ messages in thread
From: netdev-bot+sashiko @ 2026-11-13  2:31 UTC (permalink / raw)
  To: hamzamahfooz
  Cc: netdev, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
	kuba, pabeni, horms, stephen, linux-hyperv, stable

Thank you for your contribution! Sashiko AI review found 1 potential
issue(s) to consider.

Critical: 0 · High: 0 · Medium: 1 · Low: 0

If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).

- [Medium] In mana_rx_skb()
  (drivers/net/ethernet/microsoft/mana/mana_en.c), the patch removed the…

--

net: mana: report RX checksum offload for IPv6

This commit removes the rx_iphdr_csum_succeed check from mana_rx_skb().
CHECKSUM_UNNECESSARY is now set from the hardware's TCP/UDP checksum
result bits alone. This lets IPv6 TCP and UDP traffic, including VXLAN
over IPv6, skip software checksum verification in GRO.

> diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
> index e6d494df22e4d..05bd4b4b8349e 100644
> --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
> +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
> @@ -2179,10 +2179,9 @@ static void mana_rx_skb(void *buf_va, bool from_pool,
>  	skb_checksum_none_assert(skb);
>  	skb_record_rx_queue(skb, rxq_idx);
>  
> -	if ((ndev->features & NETIF_F_RXCSUM) && cqe->rx_iphdr_csum_succeed) {
> -		if (cqe->rx_tcp_csum_succeed || cqe->rx_udp_csum_succeed)
> -			skb->ip_summed = CHECKSUM_UNNECESSARY;
> -	}
> +	if ((ndev->features & NETIF_F_RXCSUM) &&
> +	    (cqe->rx_tcp_csum_succeed || cqe->rx_udp_csum_succeed))
> +		skb->ip_summed = CHECKSUM_UNNECESSARY;

[Severity: Medium]
For encapsulated frames, which L4 checksum do rx_tcp_csum_succeed and
rx_udp_csum_succeed refer to?

When CHECKSUM_UNNECESSARY is set with the default csum_level of 0, the
stack takes it to mean the outermost TCP/UDP checksum was verified. For a
VXLAN frame, that is the outer UDP checksum.

struct mana_rxcomp_oob in include/net/mana/mana.h reports outer and inner
IP header results separately, but it has only one set of L4 bits:

	u32 rx_outer_iphdr_csum_succeed	: 1;
	u32 rx_outer_iphdr_csum_fail	: 1;
	...
	u32 rx_iphdr_csum_succeed	: 1;
	u32 rx_iphdr_csum_fail		: 1;
	u32 rx_tcp_csum_succeed		: 1;
	u32 rx_tcp_csum_fail		: 1;
	u32 rx_udp_csum_succeed		: 1;
	u32 rx_udp_csum_fail		: 1;

struct mana_tx_long_oob also has is_encap, inner_is_ipv6 and
inner_frame_offset, so the hardware seems to understand tunnels. That
makes it plausible that the unprefixed L4 bits describe the inner header
of a tunnelled frame.

The driver never reads rx_outer_iphdr_csum_*, never sets csum_level, and
does not set up hw_enc_features or udp_tunnel_nic.

If the unprefixed bits describe the inner headers, then before this patch
a tunnelled frame with an inner IPv6 header never had
rx_iphdr_csum_succeed set. It stayed CHECKSUM_NONE, and the outer UDP
checksum was checked in software. After this change, the same frame
becomes CHECKSUM_UNNECESSARY at level 0.

In the udp4/udp6 GRO receive path, the outer UDP check then uses up the
single csum_cnt. skb_gro_checksum_try_convert() then builds a complete
checksum from the outer checksum, which was never checked. Only the inner
TCP checksum ends up being checked in software.

If the hardware only checked the inner L4 checksum, could some bad frames
be accepted instead of dropped? That would cover frames with a bad outer
UDP checksum, and frames corrupted in the VXLAN header/VNI, the inner
Ethernet header, or inner IPv6 fields outside the inner pseudo-header.

The commit message lists VXLAN over IPv6 as a case that benefits:

  TCP/VXLAN/IPv6, 10.9 Gbps   7934373       18

These counts would look the same under either reading of the hardware.
Once the outer checksum is assumed valid, GRO checksum conversion skips
the full software sum.

Tunnels with an inner IPv4 header already had this problem under the old
check. This patch extends it to tunnels with an inner IPv6 header.

Does the hardware or firmware guarantee that these bits always refer to
the outermost L4 header? If not, there are two options. One is to use the
outer/inner bits and set skb->csum_level = 1 where it applies. The other
is to leave encapsulated frames as CHECKSUM_NONE.

>  
>  	if (cqe->rx_hashtype != 0 && (ndev->features & NETIF_F_RXHASH)) {
>  		if (cqe->rx_hashtype & MANA_HASH_L4)

-- 
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261109142856.779955-1-hamzamahfooz%40linux.microsoft.com

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-11-13  2:31 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-09 14:28 [PATCH net] net: mana: report RX checksum offload for IPv6 Hamza Mahfooz
2026-11-10 14:29 ` sashiko-bot
2026-11-10 15:41   ` Hamza Mahfooz
2026-11-12 17:10 ` patchwork-bot+netdevbpf
2026-11-13  2:31 ` netdev-bot+sashiko

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.