Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net-next v9 0/9] BIG TCP for UDP tunnels
From: zebang.li @ 2026-07-15  6:11 UTC (permalink / raw)
  To: alice.kernel
  Cc: alice, andrew+netdev, daniel, davem, dsahern, edumazet, fw, horms,
	kuba, lucien.xin, netdev, pabeni, razor, shuah, stfomichev,
	willemb, willemdebruijn.kernel, nh78.kim, kwangho2.kim, h10.kim,
	hongfei.tang, yajie.yan
In-Reply-To: <20260710134242.216538-1-alice.kernel@fastmail.im>

On 10/07/2026 16:42, Alice Mikityanska wrote:
> From: Alice Mikityanska <alice@isovalent.com>
> 
> This series is a follow-up to "BIG TCP without HBH in IPv6", and it adds
> support for BIG TCP IPv4/IPv6 workloads in vxlan and geneve. Now that
> IPv6 BIG TCP doesn't require stripping the HBH in all various
> combinations in tunneled traffic, adding BIG TCP becomes feasible.
> 
> Patch 01 adds accessors for the length field in the UDP header, as
> suggested by Paolo in review. The usage of udp_set_len is then added in
> the following patches that start using length=0 in BIG TCP UDP packets.
> 
> Patches 02-04 close the gaps that prevent BIG TCP packets from going
> through UDP tunnel code.
> 
> Patch 05 validates packets in udp_gro_receive to exclude packets with
> length=0 from GRO aggregation.
> 
> Patch 06 is for proper formatting in tcpdump (set UDP len to 0 rather
> than a trimmed value on overflow).
> 
> Patches 07-08 bump up tso_max_size for VXLAN and GENEVE.
> 
> Patch 09 adds selftests.
> 
> Thanks all!
> 
> v9 changes: Converted the selftest to iptables counters to avoid the
> issue with tcpdump pcaps taking all space in /tmp.
> 
> v8: https://lore.kernel.org/netdev/20260706181941.385672-1-alice.kernel@fastmail.im/
> 
> v8 changes: Addressed Paolo's and Jason's review comments. Made the
> selftest more robust, added checks for SACK and mode with disabled tx
> checksum offload on lower veth netdevs. Added details to commit
> messages. Kept skb_segment logic unchanged, because the frags overflow
> issue is not specific to BIG TCP.
> 
> v7: https://lore.kernel.org/netdev/20260611192955.604661-1-alice.kernel@fastmail.im/
> 
> v7 changes: Addressed Paolo's comments to properly block malformed
> packets with UDP length=0 at udp_rcv level.
> 
> v6: https://lore.kernel.org/netdev/20260602093931.516281-1-alice.kernel@fastmail.im/
> 
> v6 changes: Lowered the packets threshold in the selftest to pass
> upstream CI on debug kernels, also made it configurable.
> 
> v5: https://lore.kernel.org/netdev/20260526161200.1135899-1-alice.kernel@fastmail.im/
> 
> v5 changes: Rebased, dropped one of the patches that came in via the net
> tree, addressed an overflow in nsim_do_psp found by Sashiko.
> 
> v4: https://lore.kernel.org/netdev/20260512165648.386518-1-alice.kernel@fastmail.im/
> 
> v4 changes: Rebased, addressed Sashiko AI review [1] and Willem's
> comment about netperf flags.
> 
> My comments on Sashiko AI review per patch:
> 
> 01: I'd prefer to keep the cases that I haven't tested outside of the
> scope of this series, which is for VXLAN/GENEVE tunnels, not for ESP.
> 
> 02: The patch doesn't have behavioral changes other than fixing the
> checksum. The final uh->len assignment assigns the actual length, not
> 64k.
> 
> 03: The check can't be loosened, because total_len is also assigned to
> UDP length. BIG TCP works in the mode without GRO hint option.
> 
> 04: Fixed the fallback value for udplen. BIG TCP is fine, it's the
> uh->len = 0 case, uh->len can't exceed 64k.
> 
> 05: In the BIG TCP case, partial GSO splits the SKB in two. If full
> segmentation is needed, the SKB is split in many MSS-sized SKBs without
> fragments.
> 
> 06: Invalid packets from the wire are addressed in 08.
> 
> 07: __udp_gso_segment only handles UDP GSO packets, which can't be
> bigger than 64k. Kept udp_set_len_short in nf_nat_mangle_udp_packet, as
> the function doesn't support BIG TCP packets anyway (see
> mangle_contents).
> 
> 08: udp_gro_receive handles packets before aggregation, there are no BIG
> TCP packets at this point. RFC 768 doesn't say that padded UDP packets
> are valid. Real jumbograms don't seem to be supported in this path
> anyway.
> 
> 09: The packet goes to skb_udp_tunnel_segment, not __udp_gso_segment.
> __skb_udp_tunnel_segment handles this case.
> 
> 12: Improved process cleanup by killing everything inside netns before
> deleting them, and by avoiding killing netserver outside of netns.
> netperf with -r in TCP_STREAM mode works, and the option has the
> intended effect, but I replaced it with -m. Added dependency check for
> tcpdump.
> 
> [1]: https://sashiko.dev/#/patchset/20260410150943.993350-1-alice.kernel%40fastmail.im
> 
> v3: https://lore.kernel.org/netdev/20260410150943.993350-1-alice.kernel@fastmail.im/
> 
> v3 changes: Fixed the redirect in the selftest, rebased over my L2TP fix
> [2] for the syzbot report [3].
> 
> [2]: https://lore.kernel.org/netdev/20260403174949.843941-1-alice.kernel@fastmail.im/
> [3]: https://lore.kernel.org/netdev/69a1dfba.050a0220.3a55be.0026.GAE@google.com/
> 
> v2: https://lore.kernel.org/netdev/20260226201600.222044-1-alice.kernel@fastmail.im/
> 
> v2 changes: Addressed the review comments: added UDP len helpers,
> consolidated UDP len sanity checks in patch 08 into one, added
> selftests. Added fixups to related code (patch 01-03).
> 
> v1: https://lore.kernel.org/netdev/20250923134742.1399800-1-maxtram95@gmail.com/
> 
> Alice Mikityanska (8):
>    net: Use helpers to get/set UDP len tree-wide
>    net: Enable BIG TCP with partial GSO
>    udp: Support BIG TCP GSO packets where they can occur
>    udp: Support gro_ipv4_max_size > 65536
>    udp: Validate UDP length in udp_gro_receive
>    udp: Set length in UDP header to 0 for big GSO packets
>    vxlan: Enable BIG TCP packets
>    selftests: net: Add a test for BIG TCP in UDP tunnels
> 
> Daniel Borkmann (1):
>    geneve: Enable BIG TCP packets
> 
>   drivers/infiniband/core/lag.c                 |   2 +-
>   drivers/infiniband/sw/rxe/rxe_net.c           |   4 +-
>   drivers/net/amt.c                             |   6 +-
>   drivers/net/ethernet/intel/i40e/i40e_txrx.c   |   2 +-
>   drivers/net/ethernet/intel/iavf/iavf_txrx.c   |   2 +-
>   drivers/net/ethernet/intel/ice/ice_txrx.c     |   2 +-
>   drivers/net/ethernet/intel/idpf/idpf_txrx.c   |   2 +-
>   .../marvell/octeontx2/nic/otx2_txrx.c         |   2 +-
>   .../net/ethernet/mellanox/mlx5/core/en_rx.c   |   4 +-
>   .../ethernet/mellanox/mlx5/core/en_selftest.c |   2 +-
>   drivers/net/ethernet/sfc/falcon/selftest.c    |   4 +-
>   drivers/net/ethernet/sfc/selftest.c           |   4 +-
>   drivers/net/ethernet/sfc/siena/selftest.c     |   4 +-
>   drivers/net/ethernet/sfc/tc_encap_actions.c   |   2 +-
>   .../stmicro/stmmac/stmmac_selftests.c         |   4 +-
>   drivers/net/geneve.c                          |   4 +-
>   drivers/net/netconsole.c                      |   2 +-
>   drivers/net/netdevsim/dev.c                   |   2 +-
>   drivers/net/netdevsim/psample.c               |   2 +-
>   drivers/net/netdevsim/psp.c                   |   8 +-
>   drivers/net/vxlan/vxlan_core.c                |   2 +
>   drivers/net/wireguard/receive.c               |   2 +-
>   include/linux/udp.h                           |  27 +++
>   include/trace/events/icmp.h                   |   2 +-
>   lib/tests/blackhole_dev_kunit.c               |   2 +-
>   net/6lowpan/nhc_udp.c                         |  10 +-
>   net/core/pktgen.c                             |   4 +-
>   net/core/selftests.c                          |   4 +-
>   net/core/skbuff.c                             |  10 +-
>   net/core/tso.c                                |   3 +-
>   net/ipv4/esp4.c                               |   2 +-
>   net/ipv4/fou_core.c                           |   2 +-
>   net/ipv4/ipconfig.c                           |   6 +-
>   net/ipv4/netfilter/nf_nat_snmp_basic_main.c   |   4 +-
>   net/ipv4/route.c                              |   2 +-
>   net/ipv4/udp.c                                |   7 +-
>   net/ipv4/udp_offload.c                        |  49 ++---
>   net/ipv4/udp_tunnel_core.c                    |   2 +-
>   net/ipv6/esp6.c                               |   5 +-
>   net/ipv6/fou6.c                               |   2 +-
>   net/ipv6/ip6_udp_tunnel.c                     |   2 +-
>   net/ipv6/udp.c                                |   7 +-
>   net/ipv6/udp_offload.c                        |   2 +-
>   net/l2tp/l2tp_core.c                          |   2 +-
>   net/netfilter/ipvs/ip_vs_xmit.c               |   2 +-
>   net/netfilter/nf_conntrack_proto_udp.c        |  15 +-
>   net/netfilter/nf_log_syslog.c                 |   2 +-
>   net/netfilter/nf_nat_helper.c                 |   2 +-
>   net/psp/psp_main.c                            |   2 +-
>   net/sched/act_csum.c                          |   4 +-
>   net/xfrm/xfrm_nat_keepalive.c                 |   2 +-
>   tools/testing/selftests/net/Makefile          |   1 +
>   .../testing/selftests/net/big_tcp_tunnels.sh  | 188 ++++++++++++++++++
>   53 files changed, 340 insertions(+), 102 deletions(-)
>   create mode 100755 tools/testing/selftests/net/big_tcp_tunnels.sh
> 


Hi Alice,

This patch looks promising, but I noticed that it does not include a modification for `skb_gro_receive`.

Currently, for UDP data aggregated via GRO, if the resulting packet size exceeds 65536 (`GRO_LEGACY_MAX_SIZE`), this check will return `-E2BIG`.

To allow UDP GRO aggregation beyond this limit (similar to the existing TCP behavior), we should update the condition to include `IPPROTO_UDP`.

I suggest the following modification:

diff --git a/net/core/gro.c b/net/core/gro.c
index 35f2f708f010..01e56ad629c2 100644
--- a/net/core/gro.c
+++ b/net/core/gro.c
@@ -117,7 +117,7 @@ int skb_gro_receive(struct sk_buff *p, struct sk_buff *skb)
                return -E2BIG;
        if (unlikely(p->len + len >= GRO_LEGACY_MAX_SIZE)) {
-               if (NAPI_GRO_CB(skb)->proto != IPPROTO_TCP ||
+               if ((NAPI_GRO_CB(skb)->proto != IPPROTO_TCP && NAPI_GRO_CB(skb)->proto != IPPROTO_UDP) ||
                    p->encapsulation)
                        return -E2BIG;
        }

Thanks,
zebang

^ permalink raw reply related

* [PATCH iwl-net v1 1/2] iavf: fix ASQ command buffer leak on init failure
From: xuanqiang.luo @ 2026-07-15  6:11 UTC (permalink / raw)
  To: Tony Nguyen, Przemek Kitszel, intel-wired-lan
  Cc: Andrew Lunn, Mitch Williams, Greg Rose, Sudheer Mogilappagari,
	netdev, Xuanqiang Luo, stable
In-Reply-To: <20260715061131.34420-1-xuanqiang.luo@linux.dev>

From: Xuanqiang Luo <luoxuanqiang@kylinos.cn>

iavf_alloc_adminq_asq_ring() allocates cmd_buf before the remaining ASQ
resources. If iavf_alloc_asq_bufs() or iavf_config_asq_regs() fails, the
unwind path elides cmd_buf while freeing the other allocations.

The ASQ count is not set until initialization succeeds, so the shutdown
path cannot reclaim the buffer. Free cmd_buf in the common unwind path.

Fixes: d358aa9a7a2d ("i40evf: init code and hardware support")
Cc: stable@vger.kernel.org
Signed-off-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
---
 drivers/net/ethernet/intel/iavf/iavf_adminq.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/intel/iavf/iavf_adminq.c b/drivers/net/ethernet/intel/iavf/iavf_adminq.c
index 6937b7dd44cbb..82a32f8e78c12 100644
--- a/drivers/net/ethernet/intel/iavf/iavf_adminq.c
+++ b/drivers/net/ethernet/intel/iavf/iavf_adminq.c
@@ -346,6 +346,7 @@ static enum iavf_status iavf_init_asq(struct iavf_hw *hw)
 	iavf_free_virt_mem(hw, &hw->aq.asq.dma_head);
 
 init_adminq_free_rings:
+	iavf_free_virt_mem(hw, &hw->aq.asq.cmd_buf);
 	iavf_free_adminq_asq(hw);
 
 init_adminq_exit:
-- 
2.43.0

^ permalink raw reply related

* [PATCH iwl-net v1 0/2] iavf: fix two memory leaks
From: xuanqiang.luo @ 2026-07-15  6:11 UTC (permalink / raw)
  To: Tony Nguyen, Przemek Kitszel, intel-wired-lan
  Cc: Andrew Lunn, Mitch Williams, Greg Rose, Sudheer Mogilappagari,
	netdev, Xuanqiang Luo

From: Xuanqiang Luo <luoxuanqiang@kylinos.cn>

This series fixes two memory leaks found by inspection in iavf. Release
the ASQ command buffer when initialization fails and the QoS capabilities
buffer when the device is removed.

Xuanqiang Luo (2):
  iavf: fix ASQ command buffer leak on init failure
  iavf: fix QoS capabilities memory leak

 drivers/net/ethernet/intel/iavf/iavf_adminq.c | 1 +
 drivers/net/ethernet/intel/iavf/iavf_main.c   | 1 +
 2 files changed, 2 insertions(+)


base-commit: 58717b2a1365d06c8c64b72aa948541b53fe31eb
-- 
2.43.0

^ permalink raw reply

* [PATCH net 2/2] geneve: require CAP_NET_ADMIN in the device netns for changelink
From: Doruk Tan Ozturk @ 2026-07-15  5:56 UTC (permalink / raw)
  To: davem, edumazet, kuba, pabeni, andrew+netdev
  Cc: sd, linville, mschiffer, maoyixie.tju, netdev, linux-kernel,
	stable
In-Reply-To: <20260715055648.33060-1-doruk@0sec.ai>

A tunnel changelink() operates on at most two netns, dev_net(dev) and
the sticky underlay netns geneve->net. They differ once the device is
created in or moved to a netns other than the one the request runs in.
The rtnl changelink path checks CAP_NET_ADMIN only against dev_net(dev),
so a caller privileged there but not in geneve->net can rewrite a geneve
device whose underlay lives in geneve->net.

geneve_changelink() applies the new configuration against geneve->net:
geneve_link_config() and the geneve_quiesce()/geneve_unquiesce() pair
reopen the underlay sockets in that netns (geneve_sock_add() uses
geneve->net), so the same reasoning as the tunnel changelink series
applies here.

Gate geneve_changelink() with rtnl_dev_link_net_capable(), at the top of
the op before any attribute is parsed, matching ipgre_changelink() and
the rest of the "require CAP_NET_ADMIN in the device netns for
changelink" series.

Found by 0sec automated security-research tooling (https://0sec.ai).

Fixes: 2d07dc79fe04 ("geneve: add initial netdev driver for GENEVE tunnels")
Cc: stable@vger.kernel.org
Assisted-by: 0sec:multi-model
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
---
 drivers/net/geneve.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index 396e1a113cd4..03c99a016298 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -2376,6 +2376,9 @@ static int geneve_changelink(struct net_device *dev, struct nlattr *tb[],
 	struct geneve_config cfg;
 	int err;
 
+	if (!rtnl_dev_link_net_capable(dev, geneve->net))
+		return -EPERM;
+
 	/* If the geneve device is configured for metadata (or externally
 	 * controlled, for example, OVS), then nothing can be changed.
 	 */
-- 
2.43.0


^ permalink raw reply related

* [PATCH net 1/2] vxlan: require CAP_NET_ADMIN in the device netns for changelink
From: Doruk Tan Ozturk @ 2026-07-15  5:56 UTC (permalink / raw)
  To: davem, edumazet, kuba, pabeni, andrew+netdev
  Cc: sd, linville, mschiffer, maoyixie.tju, netdev, linux-kernel,
	stable
In-Reply-To: <20260715055648.33060-1-doruk@0sec.ai>

A tunnel changelink() operates on at most two netns, dev_net(dev) and
the sticky underlay netns vxlan->net. They differ once the device is
created in or moved to a netns other than the one the request runs in.
The rtnl changelink path checks CAP_NET_ADMIN only against dev_net(dev),
so a caller privileged there but not in vxlan->net can rewrite a vxlan
device whose underlay lives in vxlan->net.

vxlan_changelink() validates and applies the new configuration against
vxlan->net (vxlan_config_validate(vxlan->net, ...)) and can reopen the
underlay socket in that netns, so the same reasoning as the tunnel
changelink series applies here.

Gate vxlan_changelink() with rtnl_dev_link_net_capable(), at the top of
the op before any attribute is parsed, matching ipgre_changelink() and
the rest of the "require CAP_NET_ADMIN in the device netns for
changelink" series.

Found by 0sec automated security-research tooling (https://0sec.ai).

Fixes: 889ce937c98f ("vxlan: correctly set vxlan->net when creating the device in a netns")
Cc: stable@vger.kernel.org
Assisted-by: 0sec:multi-model
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
---
 drivers/net/vxlan/vxlan_core.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index 67c367cc5662..d834a4865aec 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -4421,6 +4421,9 @@ static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[],
 	struct vxlan_rdst *dst;
 	int err;
 
+	if (!rtnl_dev_link_net_capable(dev, vxlan->net))
+		return -EPERM;
+
 	dst = &vxlan->default_dst;
 	err = vxlan_nl2conf(tb, data, dev, &conf, true, extack);
 	if (err)
-- 
2.43.0


^ permalink raw reply related

* [PATCH net 0/2] vxlan, geneve: require CAP_NET_ADMIN in the device netns for changelink
From: Doruk Tan Ozturk @ 2026-07-15  5:56 UTC (permalink / raw)
  To: davem, edumazet, kuba, pabeni, andrew+netdev
  Cc: sd, linville, mschiffer, maoyixie.tju, netdev, linux-kernel

The recent series "require CAP_NET_ADMIN in the device netns for
changelink" (8165f7ff57d9..27ccb68e7ccc) added rtnl_dev_link_net_capable()
and gated the eight IP tunnel drivers (ip_gre, ipip, ip_vti, ip6_tunnel,
ip6_gre, ip6_vti, sit, xfrm_interface). VXLAN and GENEVE share the exact
same shape but were not covered: both store the underlay netns sticky at
newlink (vxlan->net / geneve->net) and their changelink() operates on that
netns, while the generic RTM_NEWLINK path only checks CAP_NET_ADMIN against
dev_net(dev). Once such a device is created in or moved to another netns,
a caller privileged in dev_net(dev) but not in the underlay netns can
reconfigure the tunnel's underlay.

This completes that series for the two UDP tunnel drivers that were left
out. Same helper, same placement (top of changelink, before any attribute
is parsed).

Verified on next-20260714 in QEMU with CONFIG_VXLAN=y + CONFIG_USER_NS=y:
an unprivileged user namespace holding CAP_NET_ADMIN only in a child netns
issues an IFLA_INFO_DATA changelink on a vxlan device whose underlay lives
in init_net. Before: returns 0 (reconfigures the init_net underlay).
After: returns -EPERM.

Doruk Tan Ozturk (2):
  vxlan: require CAP_NET_ADMIN in the device netns for changelink
  geneve: require CAP_NET_ADMIN in the device netns for changelink

 drivers/net/geneve.c           | 3 +++
 drivers/net/vxlan/vxlan_core.c | 3 +++
 2 files changed, 6 insertions(+)

-- 
2.43.0


^ permalink raw reply

* [PATCH net] ppp: annotate concurrent dev->stats accesses
From: Eric Dumazet @ 2026-07-15  5:55 UTC (permalink / raw)
  To: David S . Miller, Jakub Kicinski, Paolo Abeni
  Cc: Simon Horman, Andrew Lunn, netdev, eric.dumazet, Eric Dumazet

dev->stats fields can be updated concurrently from multiple CPUs
without synchronization.

Use DEV_STATS_INC() for stats increments and DEV_STATS_READ()
when reading dev->stats in ppp_get_stats64() and ppp_get_stats()
to avoid data races.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
 drivers/net/ppp/ppp_generic.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index 717c1d3aa95380da64eb5ae6fc1da6e4dfaa9d87..ef54e0a0462a175bb989db8dda895e9ae755965f 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -1482,7 +1482,7 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
  outf:
 	kfree_skb(skb);
-	++dev->stats.tx_dropped;
+	DEV_STATS_INC(dev, tx_dropped);
 	return NETDEV_TX_OK;
 }
 
@@ -1532,11 +1532,11 @@ ppp_net_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
 static void
 ppp_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats64)
 {
-	stats64->rx_errors        = dev->stats.rx_errors;
-	stats64->tx_errors        = dev->stats.tx_errors;
-	stats64->rx_dropped       = dev->stats.rx_dropped;
-	stats64->tx_dropped       = dev->stats.tx_dropped;
-	stats64->rx_length_errors = dev->stats.rx_length_errors;
+	stats64->rx_errors        = DEV_STATS_READ(dev, rx_errors);
+	stats64->tx_errors        = DEV_STATS_READ(dev, tx_errors);
+	stats64->rx_dropped       = DEV_STATS_READ(dev, rx_dropped);
+	stats64->tx_dropped       = DEV_STATS_READ(dev, tx_dropped);
+	stats64->rx_length_errors = DEV_STATS_READ(dev, rx_length_errors);
 	dev_fetch_sw_netstats(stats64, dev->tstats);
 }
 
@@ -1889,7 +1889,7 @@ ppp_prepare_tx_skb(struct ppp *ppp, struct sk_buff **pskb)
 
  drop:
 	kfree_skb(skb);
-	++ppp->dev->stats.tx_errors;
+	DEV_STATS_INC(ppp->dev, tx_errors);
 	return 1;
 }
 
@@ -2156,7 +2156,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
  err_linearize:
 	if (ppp->debug & 1)
 		netdev_err(ppp->dev, "PPP: no memory (fragment)\n");
-	++ppp->dev->stats.tx_errors;
+	DEV_STATS_INC(ppp->dev, tx_errors);
 	++ppp->nxseq;
 	return 1;	/* abandon the frame */
 }
@@ -2329,7 +2329,7 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *skb)
 	if (!ppp_decompress_proto(skb)) {
 		kfree_skb(skb);
 		if (ppp) {
-			++ppp->dev->stats.rx_length_errors;
+			DEV_STATS_INC(ppp->dev, rx_length_errors);
 			ppp_receive_error(ppp);
 		}
 		goto done;
@@ -2391,7 +2391,7 @@ ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
 static void
 ppp_receive_error(struct ppp *ppp)
 {
-	++ppp->dev->stats.rx_errors;
+	DEV_STATS_INC(ppp->dev, rx_errors);
 	if (ppp->vj)
 		slhc_toss(ppp->vj);
 }
@@ -2658,7 +2658,7 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
 	 */
 	if (seq_before(seq, ppp->nextseq)) {
 		kfree_skb(skb);
-		++ppp->dev->stats.rx_dropped;
+		DEV_STATS_INC(ppp->dev, rx_dropped);
 		ppp_receive_error(ppp);
 		return;
 	}
@@ -2694,7 +2694,7 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
 		if (pskb_may_pull(skb, 2))
 			ppp_receive_nonmp_frame(ppp, skb);
 		else {
-			++ppp->dev->stats.rx_length_errors;
+			DEV_STATS_INC(ppp->dev, rx_length_errors);
 			kfree_skb(skb);
 			ppp_receive_error(ppp);
 		}
@@ -2800,7 +2800,7 @@ ppp_mp_reconstruct(struct ppp *ppp)
 		if (lost == 0 && (PPP_MP_CB(p)->BEbits & E) &&
 		    (PPP_MP_CB(head)->BEbits & B)) {
 			if (len > ppp->mrru + 2) {
-				++ppp->dev->stats.rx_length_errors;
+				DEV_STATS_INC(ppp->dev, rx_length_errors);
 				netdev_printk(KERN_DEBUG, ppp->dev,
 					      "PPP: reconstructed packet"
 					      " is too long (%d)\n", len);
@@ -2855,7 +2855,7 @@ ppp_mp_reconstruct(struct ppp *ppp)
 					      "  missed pkts %u..%u\n",
 					      ppp->nextseq,
 					      PPP_MP_CB(head)->sequence-1);
-			++ppp->dev->stats.rx_dropped;
+			DEV_STATS_INC(ppp->dev, rx_dropped);
 			ppp_receive_error(ppp);
 		}
 
@@ -3322,8 +3322,8 @@ ppp_get_stats(struct ppp *ppp, struct ppp_stats *st)
 		st->p.ppp_opackets += tx_packets;
 		st->p.ppp_obytes += tx_bytes;
 	}
-	st->p.ppp_ierrors = ppp->dev->stats.rx_errors;
-	st->p.ppp_oerrors = ppp->dev->stats.tx_errors;
+	st->p.ppp_ierrors = DEV_STATS_READ(ppp->dev, rx_errors);
+	st->p.ppp_oerrors = DEV_STATS_READ(ppp->dev, tx_errors);
 	if (!vj)
 		return;
 	st->vj.vjs_packets = vj->sls_o_compressed + vj->sls_o_uncompressed;
-- 
2.55.0.141.g00534a21ce-goog


^ permalink raw reply related

* [PATCH v4 net-next] net: neigh: avoid calling neigh_forced_gc on every alloc when table is full
From: Vimal Agrawal @ 2026-07-15  5:53 UTC (permalink / raw)
  To: pabeni, netdev; +Cc: kuba, kuniyu, edumazet, vimal.agrawal
In-Reply-To: <20260714133909.82424-1-vimal.agrawal@sophos.com>

Once the neighbour table exceeds gc_thresh3, neigh_forced_gc() is called
on every allocation attempt with no rate limiting. In workloads with mostly
active/reachable entries, the GC walk traverses a large portion of the
neighbour table without reclaiming entries, holding tbl->lock for an
extended period. This causes severe lock contention and allocation
latencies exceeding 16ms under sustained neighbour creation.

Add a pre-lock check in neigh_forced_gc() to skip the GC run if one was
performed within the last 50 ms, but only when the table actually contains
NEIGH_FORCED_GC_LARGE_TABLE_THRESH (16384) or more entries. This avoids
repeated full table scans and lock acquisitions on the hot allocation path
while leaving tables with few entries completely unaffected regardless of
how gc_thresh3 is configured.

Profiling of neigh_create() shows ~3 orders of magnitude latency
improvement with this change.

Link: https://lore.kernel.org/netdev/CALkUMdSCpx_ywYCx_ePLdm6yioO1nQWx7sSM=AEgsq0kywHxTw@mail.gmail.com/
Signed-off-by: Vimal Agrawal <vimal.agrawal@sophos.com>
---
v4: Rate-limit based on actual gc_entries count (>= 16384) rather than
    gc_thresh3 configuration, so tables with few entries are never
    rate-limited regardless of how gc_thresh3 is configured.
v3: Restrict rate limiting to tables with gc_thresh3 >= 16384 to avoid
    breaking selftests and default deployments (gc_thresh3=1024).
v2: Changed rate-limit window from 1s (HZ) to 50ms (msecs_to_jiffies(50))
    based on profiling data showing 44% -> 2.56% CPU reduction.

 net/core/neighbour.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 1349c0eed..9977b9f32 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -250,6 +250,8 @@ bool neigh_remove_one(struct neighbour *n)
 	return retval;
 }
 
+#define NEIGH_FORCED_GC_LARGE_TABLE_THRESH    16384
+
 static int neigh_forced_gc(struct neigh_table *tbl)
 {
 	int max_clean = atomic_read(&tbl->gc_entries) -
@@ -260,6 +262,15 @@ static int neigh_forced_gc(struct neigh_table *tbl)
 	int shrunk = 0;
 	int loop = 0;
 
+	/*
+	 * For large neighbor tables, repeated forced GC passes can spend
+	 * significant CPU scanning neighbor entries when most remain active.
+	 * Rate-limit consecutive forced GC passes to reduce CPU overhead.
+	 */
+	if (atomic_read(&tbl->gc_entries) >= NEIGH_FORCED_GC_LARGE_TABLE_THRESH &&
+	    time_before(jiffies, READ_ONCE(tbl->last_flush) + msecs_to_jiffies(50)))
+		return 0;
+
 	NEIGH_CACHE_STAT_INC(tbl, forced_gc_runs);
 
 	spin_lock_bh(&tbl->lock);
-- 
2.43.0


^ permalink raw reply related

* Re: [Intel-wired-lan] [PATCH 1/2] igc: Wait for MAC passthrough after reset
From: Chia-Lin Kao (AceLan) @ 2026-07-15  5:46 UTC (permalink / raw)
  To: Ruinskiy, Dima
  Cc: Loktionov, Aleksandr, Nguyen, Anthony L, Kitszel, Przemyslaw,
	Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, intel-wired-lan@lists.osuosl.org,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <1d6c3aae-c9b1-42da-b5fa-6f8ee9ebcae1@intel.com>

On Mon, Jun 29, 2026 at 07:42:43PM +0300, Ruinskiy, Dima wrote:
> Hi AceLan,
>
> Some more comments below.
>
> On 22/06/2026 4:57, Chia-Lin Kao (AceLan) wrote:
>
> > >
> > > Because 100 iterations of 100msec each - this translates to up-to 10
> > > seconds, no?
> > Yes, just in case it takes longer.
> > I think 5 seconds should be enough if you feel this is feasible.
> 5 seconds also sounds excessive, assuming the majority of the systems do not
> support / enable MAC passthrough via the FW feature (and I have a hunch it
> is the case). 2 seconds... maybe, but then you say that in some rare cases
> it exceeds 2 seconds as well. What if in some even rare cases it exceeds
> 5/10 seconds? Perhaps because of some glitch it will not come up at all on
> this cycle. Should the driver always wait?
>
> > I wish we can detect if the MAC passthrough is enabled, so that we
> > know if we need to poll for the MAC address.
> Unfortunately, like you I am not aware of any way for the driver to know
> whether MAC passthrough via FW is enabled. Because of this we have been
> exploring a simpler way to support this feature via ACPI objects (which are
> set by the BIOS when MAC passthrough is enabled and are easy for the driver
> to query). I know some vendors have already implemented it, and I am
> currently drafting a patch to send.
Any good news about this patch?

>
> > For the FW interrupt mechanism also needs BIOS support, and we don't
> > have the power to push this.
> The mechanism I have in mind does not require BIOS support - the I225/I226
> FW already supports the required interrupt, AFAIK - it merely needs to be
> enabled in the igc driver. With that said, there still remains the question
> of how to notify the network stack above us that the MAC address has changed
> post-probe - and whether it is even supported.
>
> --Dima
>
> >
> > >
> > > Thanks,
> > > Dima.
> > >
> > > >
> > > > > Signed-off-by: Chia-Lin Kao (AceLan) <acelan.kao@canonical.com>
> > > > > ---
> > > > >    drivers/net/ethernet/intel/igc/igc_main.c | 48
> > > > > +++++++++++++++++++++++
> > > > >    1 file changed, 48 insertions(+)
> > > > >
> > > > > diff --git a/drivers/net/ethernet/intel/igc/igc_main.c
> > > > > b/drivers/net/ethernet/intel/igc/igc_main.c
> > > > > index 2c9e2dfd8499..fa9752ed8bc5 100644
> > > > > --- a/drivers/net/ethernet/intel/igc/igc_main.c
> > > > > +++ b/drivers/net/ethernet/intel/igc/igc_main.c
> > > > > @@ -11,6 +11,7 @@
> > > > >    #include <net/pkt_sched.h>
> > > > >    #include <linux/bpf_trace.h>
> > > > >    #include <net/xdp_sock_drv.h>
> > > > > +#include <linux/etherdevice.h>
> > > > >    #include <linux/pci.h>
> > > > >    #include <linux/mdio.h>
> > > > >
> > > > > @@ -69,6 +70,52 @@ static const struct pci_device_id igc_pci_tbl[] = {
> > > > >
> > > > >    MODULE_DEVICE_TABLE(pci, igc_pci_tbl);
> > > > >
> > > > > +static void igc_read_rar0(struct igc_hw *hw, u8 *addr, u32 *ral, u32
> > > > > +*rah) {
> > > > > +	*ral = rd32(IGC_RAL(0));
> > > > > +	*rah = rd32(IGC_RAH(0));
> > > > > +
> > > > > +	addr[0] = *ral & 0xff;
> > > > > +	addr[1] = (*ral >> 8) & 0xff;
> > > > > +	addr[2] = (*ral >> 16) & 0xff;
> > > > > +	addr[3] = (*ral >> 24) & 0xff;
> > > > > +	addr[4] = *rah & 0xff;
> > > > > +	addr[5] = (*rah >> 8) & 0xff;
> > > > > +}
> > > > > +
> > > > > +static bool igc_is_lmvp_device(struct pci_dev *pdev) {
> > > > > +	switch (pdev->device) {
> > > > > +	case IGC_DEV_ID_I225_LMVP:
> > > > > +	case IGC_DEV_ID_I226_LMVP:
> > > > > +		return true;
> > > > > +	default:
> > > > > +		return false;
> > > > > +	}
> > > > > +}
> > > > > +
> > > > > +static void igc_wait_for_lmvp_mac_passthrough(struct pci_dev *pdev,
> > > > > +					      struct igc_hw *hw)
> > > > > +{
> > > > > +	u8 addr[ETH_ALEN] __aligned(2);
> > > > > +	u32 orig_ral, orig_rah;
> > > > > +	u32 ral, rah;
> > > > > +	int i;
> > > > > +
> > > > > +	if (!igc_is_lmvp_device(pdev))
> > > > > +		return;
> > > > > +
> > > > > +	igc_read_rar0(hw, addr, &orig_ral, &orig_rah);
> > > > > +
> > > > > +	for (i = 0; i < 100; i++) {
> > > > > +		msleep(100);
> > > > > +		igc_read_rar0(hw, addr, &ral, &rah);
> > > > > +		if ((ral != orig_ral || rah != orig_rah) &&
> > > > > +		    is_valid_ether_addr(addr))
> > > > > +			return;
> > > > > +	}
> > > > > +}
> > > > > +
> > > > >    enum latency_range {
> > > > >    	lowest_latency = 0,
> > > > >    	low_latency = 1,
> > > > > @@ -7259,6 +7306,7 @@ static int igc_probe(struct pci_dev *pdev,
> > > > >    	 * known good starting state
> > > > >    	 */
> > > > >    	hw->mac.ops.reset_hw(hw);
> > > > > +	igc_wait_for_lmvp_mac_passthrough(pdev, hw);
> > > > >
> > > > >    	if (igc_get_flash_presence_i225(hw)) {
> > > > >    		if (hw->nvm.ops.validate(hw) < 0) {
> > > > > --
> > > > > 2.53.0
> > > >
> > >
>

^ permalink raw reply

* Re: [PATCH net v5] tipc: serialize udp bearer replicast list updates
From: kernel test robot @ 2026-07-15  5:35 UTC (permalink / raw)
  To: Weiming Shi, Jon Maloy, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman
  Cc: oe-kbuild-all, netdev, tipc-discussion, linux-kernel, Tung Nguyen,
	xmei5, Weiming Shi
In-Reply-To: <20260714192140.1810202-1-bestswngs@gmail.com>

Hi Weiming,

kernel test robot noticed the following build warnings:

[auto build test WARNING on net/main]

url:    https://github.com/intel-lab-lkp/linux/commits/Weiming-Shi/tipc-serialize-udp-bearer-replicast-list-updates/20260715-033047
base:   net/main
patch link:    https://lore.kernel.org/r/20260714192140.1810202-1-bestswngs%40gmail.com
patch subject: [PATCH net v5] tipc: serialize udp bearer replicast list updates
config: x86_64-rhel-9.4 (https://download.01.org/0day-ci/archive/20260715/202607151342.sJOXeRCT-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260715/202607151342.sJOXeRCT-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202607151342.sJOXeRCT-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> Warning: net/tipc/udp_media.c:106 struct member 'disabled' not described in 'udp_bearer'
>> Warning: net/tipc/udp_media.c:106 struct member 'disabled' not described in 'udp_bearer'

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* Re: [PATCH net-next] ppp: reuse ppp_get_stats64() for ioctl stats
From: Qingfang Deng @ 2026-07-15  5:30 UTC (permalink / raw)
  To: Zhixing Chen, Andrew Lunn, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni
  Cc: linux-ppp, netdev
In-Reply-To: <20260714091941.33783-1-running910@gmail.com>

Hi,

On 2026/7/14 17:19, Zhixing Chen wrote:
> ppp_get_stats() open-codes the per-cpu tstats aggregation even though
> ppp_get_stats64() already collects the packet, byte and error counters
> needed by the legacy SIOCGPPPSTATS ioctl path.
>
> Reuse ppp_get_stats64() when filling struct ppp_stats. This keeps the
> ioctl stats path consistent with the netdev stats64 path and removes the
> open-coded per-cpu stats aggregation from the ioctl path.
>
> Signed-off-by: Zhixing Chen <running910@gmail.com>
> ---
>
> This is meant as a small cleanup. The ioctl path and the netdev stats64
> path already use the same underlying counters, so this just makes the
> ioctl path reuse ppp_get_stats64() instead of open-coding the per-cpu
> aggregation locally.

On a 32-bit architecture, this will introduce unnecessary seqlock 
overhead to get the upper 32-bit of a counter, which would then be 
immediately discarded.

Regards,

Qingfang


^ permalink raw reply

* Re: net: rnpgbe: Pass an expression directly in rnpgbe_rm_adapter()
From: Markus Elfring @ 2026-07-15  5:22 UTC (permalink / raw)
  To: Andrew Lunn, netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	MD Danish Anwar, Michael Grzeschik, Paolo Abeni,
	Uwe Kleine-König, Vadim Fedorenko, Yibo Dong, LKML,
	kernel-janitors
In-Reply-To: <dd0bb5df-22eb-481a-9274-7feb725172d0@lunn.ch>

>> The address of a data structure member was determined before
>> a corresponding null pointer check in the implementation of
>> the function “rnpgbe_rm_adapter”.
> 
> Please can you show the path taken that mucse is actually NULL.

The applied sanity check indicates a corresponding possibility.

Which result representations would you find helpful for the requested
data flow analysis?


> I tend to agree, that the correct change is to remove the NULL pointer
> test.
Will the omission of such a check gain wider acceptance?

Regards,
Markus

^ permalink raw reply

* [PATCH net] octeontx2-vf: set TC flower flag on MCAM entry allocation
From: Ratheesh Kannoth @ 2026-07-15  5:20 UTC (permalink / raw)
  To: davem, linux-kernel, netdev, sbhatta, sgoutham
  Cc: andrew+netdev, edumazet, kuba, pabeni, Suman Ghosh,
	Ratheesh Kannoth

From: Suman Ghosh <sumang@marvell.com>

When MCAM entries are allocated for a VF netdev via the devlink
mcam_count parameter, only OTX2_FLAG_NTUPLE_SUPPORT was set. That
enabled ethtool ntuple filters but not tc flower offload. Also set
OTX2_FLAG_TC_FLOWER_SUPPORT when entries are successfully allocated.

Fixes: 2da489432747 ("octeontx2-pf: devlink params support to set mcam entry count")
Signed-off-by: Suman Ghosh <sumang@marvell.com>
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
---
 drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
index 5dd0591fed99..99d78fc5a2c4 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
@@ -272,6 +272,7 @@ int otx2_alloc_mcam_entries(struct otx2_nic *pfvf, u16 count)
 	if (allocated) {
 		pfvf->flags |= OTX2_FLAG_MCAM_ENTRIES_ALLOC;
 		pfvf->flags |= OTX2_FLAG_NTUPLE_SUPPORT;
+		pfvf->flags |= OTX2_FLAG_TC_FLOWER_SUPPORT;
 	}
 
 	if (allocated != count)
-- 
2.43.0


^ permalink raw reply related

* [linus:master] [selftests]  6160ec9d03: kselftests-bpf.drivers/net.gro.py.fail
From: kernel test robot @ 2026-07-15  5:17 UTC (permalink / raw)
  To: Qingfang Deng; +Cc: oe-lkp, lkp, linux-kernel, Paolo Abeni, netdev, oliver.sang



Hello,

kernel test robot noticed "kselftests-bpf.drivers/net.gro.py.fail" on:

commit: 6160ec9d03d7af5aa345b8b994de80fa8454274b ("selftests: net: test PPPoE packets in gro.sh")
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git master

[test failed on linus/master      0e35b9b6ec0ffcc5e23cbdec09f5c622ad532b53]
[test failed on linux-next/master 5c73cd9f0819c1c44e373e3dabb68318b1de1a12]

in testcase: kselftests-bpf
version: 
with following parameters:

	group: drivers


config: x86_64-rhel-9.4-bpf
compiler: gcc-14
test machine: 16 threads Intel(R) Core(TM) i7-13620H (Raptor Lake) with 32G memory

(please refer to attached dmesg/kmsg for entire log/backtrace)


If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <oliver.sang@intel.com>
| Closes: https://lore.kernel.org/oe-lkp/202607150740.c8e9119d-lkp@intel.com


# timeout set to 300
# selftests: drivers/net: gro.py
# TAP version 13
# 1..318
# ok 1 gro.test.sw_ipv4_data_same
# ok 2 gro.test.sw_ipv4_data_lrg_sml
# ok 3 gro.test.sw_ipv4_data_sml_lrg
# ok 4 gro.test.sw_ipv4_data_lrg_1byte
# ok 5 gro.test.sw_ipv4_data_burst
# ok 6 gro.test.sw_ipv4_ack
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --ipv4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test flags_psh --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: psh flag ends coalescing:
# #   STDERR: Expected {300 200 }, Total 2 packets
# #           Received {200 [!=300]100 [!=200]200 [!=0]}, Total 3 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 1/6 failed, retrying...
# ok 7 gro.test.sw_ipv4_flags_psh
# ok 8 gro.test.sw_ipv4_flags_syn
# ok 9 gro.test.sw_ipv4_flags_rst
# ok 10 gro.test.sw_ipv4_flags_urg
# ok 11 gro.test.sw_ipv4_flags_cwr
# ok 12 gro.test.sw_ipv4_tcp_csum
# ok 13 gro.test.sw_ipv4_tcp_seq
# ok 14 gro.test.sw_ipv4_tcp_ts
# ok 15 gro.test.sw_ipv4_tcp_opt
# ok 16 gro.test.sw_ipv4_ip_ecn
# ok 17 gro.test.sw_ipv4_ip_tos
# ok 18 gro.test.sw_ipv4_large_max
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --ipv4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test large_rem --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: last segment sent individually:
# #   STDERR: Expected {64896 600 600 }, Total 3 packets
# #           Received {48672 [!=64896]16824 [!=600]600 }, Total 3 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect packet geometry
# # Attempt 1/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --ipv4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test large_rem --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: last segment sent individually:
# #   STDERR: Expected {64896 600 600 }, Total 3 packets
# #           Received {40560 [!=64896]24936 [!=600]600 }, Total 3 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect packet geometry
# # Attempt 2/6 failed, retrying...
# ok 19 gro.test.sw_ipv4_large_rem
# ok 20 gro.test.sw_ipv4_ip_csum
# ok 21 gro.test.sw_ipv4_ip_ttl
# ok 22 gro.test.sw_ipv4_ip_opt
# ok 23 gro.test.sw_ipv4_ip_frag4
# ok 24 gro.test.sw_ipv4_ip_id_df1_inc
# ok 25 gro.test.sw_ipv4_ip_id_df1_fixed
# ok 26 gro.test.sw_ipv4_ip_id_df0_inc
# ok 27 gro.test.sw_ipv4_ip_id_df0_fixed
# ok 28 gro.test.sw_ipv4_ip_id_df1_inc_fixed
# ok 29 gro.test.sw_ipv4_ip_id_df1_fixed_inc
# ok 30 gro.test.sw_ipv6_data_same
# ok 31 gro.test.sw_ipv6_data_lrg_sml
# ok 32 gro.test.sw_ipv6_data_sml_lrg
# ok 33 gro.test.sw_ipv6_data_lrg_1byte
# ok 34 gro.test.sw_ipv6_data_burst
# ok 35 gro.test.sw_ipv6_ack
# ok 36 gro.test.sw_ipv6_flags_psh
# ok 37 gro.test.sw_ipv6_flags_syn
# ok 38 gro.test.sw_ipv6_flags_rst
# ok 39 gro.test.sw_ipv6_flags_urg
# ok 40 gro.test.sw_ipv6_flags_cwr
# ok 41 gro.test.sw_ipv6_tcp_csum
# ok 42 gro.test.sw_ipv6_tcp_seq
# ok 43 gro.test.sw_ipv6_tcp_ts
# ok 44 gro.test.sw_ipv6_tcp_opt
# ok 45 gro.test.sw_ipv6_ip_ecn
# ok 46 gro.test.sw_ipv6_ip_tos
# ok 47 gro.test.sw_ipv6_large_max
# ok 48 gro.test.sw_ipv6_large_rem
# ok 49 gro.test.sw_ipv6_ip_frag6
# ok 50 gro.test.sw_ipv6_ip_v6ext_same
# ok 51 gro.test.sw_ipv6_ip_v6ext_diff
# ok 52 gro.test.sw_ipip_data_same
# ok 53 gro.test.sw_ipip_data_lrg_sml
# ok 54 gro.test.sw_ipip_data_sml_lrg
# ok 55 gro.test.sw_ipip_data_lrg_1byte
# ok 56 gro.test.sw_ipip_data_burst
# ok 57 gro.test.sw_ipip_ack
# ok 58 gro.test.sw_ipip_flags_psh
# ok 59 gro.test.sw_ipip_flags_syn
# ok 60 gro.test.sw_ipip_flags_rst
# ok 61 gro.test.sw_ipip_flags_urg
# ok 62 gro.test.sw_ipip_flags_cwr
# ok 63 gro.test.sw_ipip_tcp_csum
# ok 64 gro.test.sw_ipip_tcp_seq
# ok 65 gro.test.sw_ipip_tcp_ts
# ok 66 gro.test.sw_ipip_tcp_opt
# ok 67 gro.test.sw_ipip_ip_ecn
# ok 68 gro.test.sw_ipip_ip_tos
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --ipip --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test large_max --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: Shouldn't coalesce if exceed IP max pkt size:
# #   STDERR: Expected {65475 899 }, Total 2 packets
# #           Received {40360 [!=65475]25115 [!=899]899 [!=0]}, Total 3 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 1/6 failed, retrying...
# ok 69 gro.test.sw_ipip_large_max
# ok 70 gro.test.sw_ipip_large_rem
# ok 71 gro.test.sw_ipip_ip_csum
# ok 72 gro.test.sw_ipip_ip_ttl
# ok 73 gro.test.sw_ipip_ip_opt
# ok 74 gro.test.sw_ipip_ip_frag4
# ok 75 gro.test.sw_ipip_ip_id_df1_inc
# ok 76 gro.test.sw_ipip_ip_id_df1_fixed
# ok 77 gro.test.sw_ipip_ip_id_df0_inc
# ok 78 gro.test.sw_ipip_ip_id_df0_fixed
# ok 79 gro.test.sw_ipip_ip_id_df1_inc_fixed
# ok 80 gro.test.sw_ipip_ip_id_df1_fixed_inc
# ok 81 gro.test.sw_ip6ip6_data_same
# ok 82 gro.test.sw_ip6ip6_data_lrg_sml
# ok 83 gro.test.sw_ip6ip6_data_sml_lrg
# ok 84 gro.test.sw_ip6ip6_data_lrg_1byte
# ok 85 gro.test.sw_ip6ip6_data_burst
# ok 86 gro.test.sw_ip6ip6_ack
# ok 87 gro.test.sw_ip6ip6_flags_psh
# ok 88 gro.test.sw_ip6ip6_flags_syn
# ok 89 gro.test.sw_ip6ip6_flags_rst
# ok 90 gro.test.sw_ip6ip6_flags_urg
# ok 91 gro.test.sw_ip6ip6_flags_cwr
# ok 92 gro.test.sw_ip6ip6_tcp_csum
# ok 93 gro.test.sw_ip6ip6_tcp_seq
# ok 94 gro.test.sw_ip6ip6_tcp_ts
# ok 95 gro.test.sw_ip6ip6_tcp_opt
# ok 96 gro.test.sw_ip6ip6_ip_ecn
# ok 97 gro.test.sw_ip6ip6_ip_tos
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --ip6ip6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test large_max --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: Shouldn't coalesce if exceed IP max pkt size:
# #   STDERR: Expected {65435 1499 }, Total 2 packets
# #           Received {63936 [!=65435]1499 1499 [!=0]}, Total 3 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 1/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --ip6ip6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test large_max --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: Shouldn't coalesce if exceed IP max pkt size:
# #   STDERR: Expected {65435 1499 }, Total 2 packets
# #           Received {23976 [!=65435]41459 [!=1499]1499 [!=0]}, Total 3 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 2/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --ip6ip6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test large_max --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: Shouldn't coalesce if exceed IP max pkt size:
# #   STDERR: Expected {65435 1499 }, Total 2 packets
# #           Received {19980 [!=65435]45455 [!=1499]1499 [!=0]}, Total 3 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 3/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --ip6ip6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test large_max --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: Shouldn't coalesce if exceed IP max pkt size:
# #   STDERR: Expected {65435 1499 }, Total 2 packets
# #           Received {23976 [!=65435]41459 [!=1499]1499 [!=0]}, Total 3 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 4/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --ip6ip6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test large_max --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: Shouldn't coalesce if exceed IP max pkt size:
# #   STDERR: Expected {65435 1499 }, Total 2 packets
# #           Received {31968 [!=65435]33467 [!=1499]1499 [!=0]}, Total 3 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 5/6 failed, retrying...
# ok 98 gro.test.sw_ip6ip6_large_max
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --ip6ip6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test large_rem --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: last segment sent individually:
# #   STDERR: Expected {63936 1500 1500 }, Total 3 packets
# #           Received {51948 [!=63936]13488 [!=1500]1500 }, Total 3 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect packet geometry
# # Attempt 1/6 failed, retrying...
# ok 99 gro.test.sw_ip6ip6_large_rem
# ok 100 gro.test.hw_ipv4_data_same # XFAIL Device does not support rx-gro-hw
# ok 101 gro.test.hw_ipv4_data_lrg_sml # XFAIL Device does not support rx-gro-hw
# ok 102 gro.test.hw_ipv4_data_sml_lrg # XFAIL Device does not support rx-gro-hw
# ok 103 gro.test.hw_ipv4_data_lrg_1byte # XFAIL Device does not support rx-gro-hw
# ok 104 gro.test.hw_ipv4_data_burst # XFAIL Device does not support rx-gro-hw
# ok 105 gro.test.hw_ipv4_ack # XFAIL Device does not support rx-gro-hw
# ok 106 gro.test.hw_ipv4_flags_psh # XFAIL Device does not support rx-gro-hw
# ok 107 gro.test.hw_ipv4_flags_syn # XFAIL Device does not support rx-gro-hw
# ok 108 gro.test.hw_ipv4_flags_rst # XFAIL Device does not support rx-gro-hw
# ok 109 gro.test.hw_ipv4_flags_urg # XFAIL Device does not support rx-gro-hw
# ok 110 gro.test.hw_ipv4_flags_cwr # XFAIL Device does not support rx-gro-hw
# ok 111 gro.test.hw_ipv4_tcp_csum # XFAIL Device does not support rx-gro-hw
# ok 112 gro.test.hw_ipv4_tcp_seq # XFAIL Device does not support rx-gro-hw
# ok 113 gro.test.hw_ipv4_tcp_ts # XFAIL Device does not support rx-gro-hw
# ok 114 gro.test.hw_ipv4_tcp_opt # XFAIL Device does not support rx-gro-hw
# ok 115 gro.test.hw_ipv4_ip_ecn # XFAIL Device does not support rx-gro-hw
# ok 116 gro.test.hw_ipv4_ip_tos # XFAIL Device does not support rx-gro-hw
# ok 117 gro.test.hw_ipv4_large_max # XFAIL Device does not support rx-gro-hw
# ok 118 gro.test.hw_ipv4_large_rem # XFAIL Device does not support rx-gro-hw
# ok 119 gro.test.hw_ipv4_ip_csum # XFAIL Device does not support rx-gro-hw
# ok 120 gro.test.hw_ipv4_ip_ttl # XFAIL Device does not support rx-gro-hw
# ok 121 gro.test.hw_ipv4_ip_opt # XFAIL Device does not support rx-gro-hw
# ok 122 gro.test.hw_ipv4_ip_frag4 # XFAIL Device does not support rx-gro-hw
# ok 123 gro.test.hw_ipv4_ip_id_df1_inc # XFAIL Device does not support rx-gro-hw
# ok 124 gro.test.hw_ipv4_ip_id_df1_fixed # XFAIL Device does not support rx-gro-hw
# ok 125 gro.test.hw_ipv4_ip_id_df0_inc # XFAIL Device does not support rx-gro-hw
# ok 126 gro.test.hw_ipv4_ip_id_df0_fixed # XFAIL Device does not support rx-gro-hw
# ok 127 gro.test.hw_ipv4_ip_id_df1_inc_fixed # XFAIL Device does not support rx-gro-hw
# ok 128 gro.test.hw_ipv4_ip_id_df1_fixed_inc # XFAIL Device does not support rx-gro-hw
# ok 129 gro.test.hw_ipv6_data_same # XFAIL Device does not support rx-gro-hw
# ok 130 gro.test.hw_ipv6_data_lrg_sml # XFAIL Device does not support rx-gro-hw
# ok 131 gro.test.hw_ipv6_data_sml_lrg # XFAIL Device does not support rx-gro-hw
# ok 132 gro.test.hw_ipv6_data_lrg_1byte # XFAIL Device does not support rx-gro-hw
# ok 133 gro.test.hw_ipv6_data_burst # XFAIL Device does not support rx-gro-hw
# ok 134 gro.test.hw_ipv6_ack # XFAIL Device does not support rx-gro-hw
# ok 135 gro.test.hw_ipv6_flags_psh # XFAIL Device does not support rx-gro-hw
# ok 136 gro.test.hw_ipv6_flags_syn # XFAIL Device does not support rx-gro-hw
# ok 137 gro.test.hw_ipv6_flags_rst # XFAIL Device does not support rx-gro-hw
# ok 138 gro.test.hw_ipv6_flags_urg # XFAIL Device does not support rx-gro-hw
# ok 139 gro.test.hw_ipv6_flags_cwr # XFAIL Device does not support rx-gro-hw
# ok 140 gro.test.hw_ipv6_tcp_csum # XFAIL Device does not support rx-gro-hw
# ok 141 gro.test.hw_ipv6_tcp_seq # XFAIL Device does not support rx-gro-hw
# ok 142 gro.test.hw_ipv6_tcp_ts # XFAIL Device does not support rx-gro-hw
# ok 143 gro.test.hw_ipv6_tcp_opt # XFAIL Device does not support rx-gro-hw
# ok 144 gro.test.hw_ipv6_ip_ecn # XFAIL Device does not support rx-gro-hw
# ok 145 gro.test.hw_ipv6_ip_tos # XFAIL Device does not support rx-gro-hw
# ok 146 gro.test.hw_ipv6_large_max # XFAIL Device does not support rx-gro-hw
# ok 147 gro.test.hw_ipv6_large_rem # XFAIL Device does not support rx-gro-hw
# ok 148 gro.test.hw_ipv6_ip_frag6 # XFAIL Device does not support rx-gro-hw
# ok 149 gro.test.hw_ipv6_ip_v6ext_same # XFAIL Device does not support rx-gro-hw
# ok 150 gro.test.hw_ipv6_ip_v6ext_diff # XFAIL Device does not support rx-gro-hw
# ok 151 gro.test.hw_ipip_data_same # XFAIL Device does not support rx-gro-hw
# ok 152 gro.test.hw_ipip_data_lrg_sml # XFAIL Device does not support rx-gro-hw
# ok 153 gro.test.hw_ipip_data_sml_lrg # XFAIL Device does not support rx-gro-hw
# ok 154 gro.test.hw_ipip_data_lrg_1byte # XFAIL Device does not support rx-gro-hw
# ok 155 gro.test.hw_ipip_data_burst # XFAIL Device does not support rx-gro-hw
# ok 156 gro.test.hw_ipip_ack # XFAIL Device does not support rx-gro-hw
# ok 157 gro.test.hw_ipip_flags_psh # XFAIL Device does not support rx-gro-hw
# ok 158 gro.test.hw_ipip_flags_syn # XFAIL Device does not support rx-gro-hw
# ok 159 gro.test.hw_ipip_flags_rst # XFAIL Device does not support rx-gro-hw
# ok 160 gro.test.hw_ipip_flags_urg # XFAIL Device does not support rx-gro-hw
# ok 161 gro.test.hw_ipip_flags_cwr # XFAIL Device does not support rx-gro-hw
# ok 162 gro.test.hw_ipip_tcp_csum # XFAIL Device does not support rx-gro-hw
# ok 163 gro.test.hw_ipip_tcp_seq # XFAIL Device does not support rx-gro-hw
# ok 164 gro.test.hw_ipip_tcp_ts # XFAIL Device does not support rx-gro-hw
# ok 165 gro.test.hw_ipip_tcp_opt # XFAIL Device does not support rx-gro-hw
# ok 166 gro.test.hw_ipip_ip_ecn # XFAIL Device does not support rx-gro-hw
# ok 167 gro.test.hw_ipip_ip_tos # XFAIL Device does not support rx-gro-hw
# ok 168 gro.test.hw_ipip_large_max # XFAIL Device does not support rx-gro-hw
# ok 169 gro.test.hw_ipip_large_rem # XFAIL Device does not support rx-gro-hw
# ok 170 gro.test.hw_ipip_ip_csum # XFAIL Device does not support rx-gro-hw
# ok 171 gro.test.hw_ipip_ip_ttl # XFAIL Device does not support rx-gro-hw
# ok 172 gro.test.hw_ipip_ip_opt # XFAIL Device does not support rx-gro-hw
# ok 173 gro.test.hw_ipip_ip_frag4 # XFAIL Device does not support rx-gro-hw
# ok 174 gro.test.hw_ipip_ip_id_df1_inc # XFAIL Device does not support rx-gro-hw
# ok 175 gro.test.hw_ipip_ip_id_df1_fixed # XFAIL Device does not support rx-gro-hw
# ok 176 gro.test.hw_ipip_ip_id_df0_inc # XFAIL Device does not support rx-gro-hw
# ok 177 gro.test.hw_ipip_ip_id_df0_fixed # XFAIL Device does not support rx-gro-hw
# ok 178 gro.test.hw_ipip_ip_id_df1_inc_fixed # XFAIL Device does not support rx-gro-hw
# ok 179 gro.test.hw_ipip_ip_id_df1_fixed_inc # XFAIL Device does not support rx-gro-hw
# ok 180 gro.test.hw_ip6ip6_data_same # XFAIL Device does not support rx-gro-hw
# ok 181 gro.test.hw_ip6ip6_data_lrg_sml # XFAIL Device does not support rx-gro-hw
# ok 182 gro.test.hw_ip6ip6_data_sml_lrg # XFAIL Device does not support rx-gro-hw
# ok 183 gro.test.hw_ip6ip6_data_lrg_1byte # XFAIL Device does not support rx-gro-hw
# ok 184 gro.test.hw_ip6ip6_data_burst # XFAIL Device does not support rx-gro-hw
# ok 185 gro.test.hw_ip6ip6_ack # XFAIL Device does not support rx-gro-hw
# ok 186 gro.test.hw_ip6ip6_flags_psh # XFAIL Device does not support rx-gro-hw
# ok 187 gro.test.hw_ip6ip6_flags_syn # XFAIL Device does not support rx-gro-hw
# ok 188 gro.test.hw_ip6ip6_flags_rst # XFAIL Device does not support rx-gro-hw
# ok 189 gro.test.hw_ip6ip6_flags_urg # XFAIL Device does not support rx-gro-hw
# ok 190 gro.test.hw_ip6ip6_flags_cwr # XFAIL Device does not support rx-gro-hw
# ok 191 gro.test.hw_ip6ip6_tcp_csum # XFAIL Device does not support rx-gro-hw
# ok 192 gro.test.hw_ip6ip6_tcp_seq # XFAIL Device does not support rx-gro-hw
# ok 193 gro.test.hw_ip6ip6_tcp_ts # XFAIL Device does not support rx-gro-hw
# ok 194 gro.test.hw_ip6ip6_tcp_opt # XFAIL Device does not support rx-gro-hw
# ok 195 gro.test.hw_ip6ip6_ip_ecn # XFAIL Device does not support rx-gro-hw
# ok 196 gro.test.hw_ip6ip6_ip_tos # XFAIL Device does not support rx-gro-hw
# ok 197 gro.test.hw_ip6ip6_large_max # XFAIL Device does not support rx-gro-hw
# ok 198 gro.test.hw_ip6ip6_large_rem # XFAIL Device does not support rx-gro-hw
# ok 199 gro.test.lro_ipv4_data_same # XFAIL Test does not work on netdevsim
# ok 200 gro.test.lro_ipv4_data_lrg_sml # XFAIL Test does not work on netdevsim
# ok 201 gro.test.lro_ipv4_data_sml_lrg # XFAIL Test does not work on netdevsim
# ok 202 gro.test.lro_ipv4_data_lrg_1byte # XFAIL Test does not work on netdevsim
# ok 203 gro.test.lro_ipv4_data_burst # XFAIL Test does not work on netdevsim
# ok 204 gro.test.lro_ipv4_ack # XFAIL Test does not work on netdevsim
# ok 205 gro.test.lro_ipv4_flags_psh # XFAIL Test does not work on netdevsim
# ok 206 gro.test.lro_ipv4_flags_syn # XFAIL Test does not work on netdevsim
# ok 207 gro.test.lro_ipv4_flags_rst # XFAIL Test does not work on netdevsim
# ok 208 gro.test.lro_ipv4_flags_urg # XFAIL Test does not work on netdevsim
# ok 209 gro.test.lro_ipv4_flags_cwr # XFAIL Test does not work on netdevsim
# ok 210 gro.test.lro_ipv4_tcp_csum # XFAIL Test does not work on netdevsim
# ok 211 gro.test.lro_ipv4_tcp_seq # XFAIL Test does not work on netdevsim
# ok 212 gro.test.lro_ipv4_tcp_ts # XFAIL Test does not work on netdevsim
# ok 213 gro.test.lro_ipv4_tcp_opt # XFAIL Test does not work on netdevsim
# ok 214 gro.test.lro_ipv4_ip_ecn # XFAIL Test does not work on netdevsim
# ok 215 gro.test.lro_ipv4_ip_tos # XFAIL Test does not work on netdevsim
# ok 216 gro.test.lro_ipv4_large_max # XFAIL Test does not work on netdevsim
# ok 217 gro.test.lro_ipv4_large_rem # XFAIL Test does not work on netdevsim
# ok 218 gro.test.lro_ipv4_ip_csum # XFAIL Test does not work on netdevsim
# ok 219 gro.test.lro_ipv4_ip_ttl # XFAIL Test does not work on netdevsim
# ok 220 gro.test.lro_ipv4_ip_opt # XFAIL Test does not work on netdevsim
# ok 221 gro.test.lro_ipv4_ip_frag4 # XFAIL Test does not work on netdevsim
# ok 222 gro.test.lro_ipv4_ip_id_df1_inc # XFAIL Test does not work on netdevsim
# ok 223 gro.test.lro_ipv4_ip_id_df1_fixed # XFAIL Test does not work on netdevsim
# ok 224 gro.test.lro_ipv4_ip_id_df0_inc # XFAIL Test does not work on netdevsim
# ok 225 gro.test.lro_ipv4_ip_id_df0_fixed # XFAIL Test does not work on netdevsim
# ok 226 gro.test.lro_ipv4_ip_id_df1_inc_fixed # XFAIL Test does not work on netdevsim
# ok 227 gro.test.lro_ipv4_ip_id_df1_fixed_inc # XFAIL Test does not work on netdevsim
# ok 228 gro.test.lro_ipv6_data_same # XFAIL Test does not work on netdevsim
# ok 229 gro.test.lro_ipv6_data_lrg_sml # XFAIL Test does not work on netdevsim
# ok 230 gro.test.lro_ipv6_data_sml_lrg # XFAIL Test does not work on netdevsim
# ok 231 gro.test.lro_ipv6_data_lrg_1byte # XFAIL Test does not work on netdevsim
# ok 232 gro.test.lro_ipv6_data_burst # XFAIL Test does not work on netdevsim
# ok 233 gro.test.lro_ipv6_ack # XFAIL Test does not work on netdevsim
# ok 234 gro.test.lro_ipv6_flags_psh # XFAIL Test does not work on netdevsim
# ok 235 gro.test.lro_ipv6_flags_syn # XFAIL Test does not work on netdevsim
# ok 236 gro.test.lro_ipv6_flags_rst # XFAIL Test does not work on netdevsim
# ok 237 gro.test.lro_ipv6_flags_urg # XFAIL Test does not work on netdevsim
# ok 238 gro.test.lro_ipv6_flags_cwr # XFAIL Test does not work on netdevsim
# ok 239 gro.test.lro_ipv6_tcp_csum # XFAIL Test does not work on netdevsim
# ok 240 gro.test.lro_ipv6_tcp_seq # XFAIL Test does not work on netdevsim
# ok 241 gro.test.lro_ipv6_tcp_ts # XFAIL Test does not work on netdevsim
# ok 242 gro.test.lro_ipv6_tcp_opt # XFAIL Test does not work on netdevsim
# ok 243 gro.test.lro_ipv6_ip_ecn # XFAIL Test does not work on netdevsim
# ok 244 gro.test.lro_ipv6_ip_tos # XFAIL Test does not work on netdevsim
# ok 245 gro.test.lro_ipv6_large_max # XFAIL Test does not work on netdevsim
# ok 246 gro.test.lro_ipv6_large_rem # XFAIL Test does not work on netdevsim
# ok 247 gro.test.lro_ipv6_ip_frag6 # XFAIL Test does not work on netdevsim
# ok 248 gro.test.lro_ipv6_ip_v6ext_same # XFAIL Test does not work on netdevsim
# ok 249 gro.test.lro_ipv6_ip_v6ext_diff # XFAIL Test does not work on netdevsim
# ok 250 gro.test.lro_ipip_data_same # XFAIL Test does not work on netdevsim
# ok 251 gro.test.lro_ipip_data_lrg_sml # XFAIL Test does not work on netdevsim
# ok 252 gro.test.lro_ipip_data_sml_lrg # XFAIL Test does not work on netdevsim
# ok 253 gro.test.lro_ipip_data_lrg_1byte # XFAIL Test does not work on netdevsim
# ok 254 gro.test.lro_ipip_data_burst # XFAIL Test does not work on netdevsim
# ok 255 gro.test.lro_ipip_ack # XFAIL Test does not work on netdevsim
# ok 256 gro.test.lro_ipip_flags_psh # XFAIL Test does not work on netdevsim
# ok 257 gro.test.lro_ipip_flags_syn # XFAIL Test does not work on netdevsim
# ok 258 gro.test.lro_ipip_flags_rst # XFAIL Test does not work on netdevsim
# ok 259 gro.test.lro_ipip_flags_urg # XFAIL Test does not work on netdevsim
# ok 260 gro.test.lro_ipip_flags_cwr # XFAIL Test does not work on netdevsim
# ok 261 gro.test.lro_ipip_tcp_csum # XFAIL Test does not work on netdevsim
# ok 262 gro.test.lro_ipip_tcp_seq # XFAIL Test does not work on netdevsim
# ok 263 gro.test.lro_ipip_tcp_ts # XFAIL Test does not work on netdevsim
# ok 264 gro.test.lro_ipip_tcp_opt # XFAIL Test does not work on netdevsim
# ok 265 gro.test.lro_ipip_ip_ecn # XFAIL Test does not work on netdevsim
# ok 266 gro.test.lro_ipip_ip_tos # XFAIL Test does not work on netdevsim
# ok 267 gro.test.lro_ipip_large_max # XFAIL Test does not work on netdevsim
# ok 268 gro.test.lro_ipip_large_rem # XFAIL Test does not work on netdevsim
# ok 269 gro.test.lro_ipip_ip_csum # XFAIL Test does not work on netdevsim
# ok 270 gro.test.lro_ipip_ip_ttl # XFAIL Test does not work on netdevsim
# ok 271 gro.test.lro_ipip_ip_opt # XFAIL Test does not work on netdevsim
# ok 272 gro.test.lro_ipip_ip_frag4 # XFAIL Test does not work on netdevsim
# ok 273 gro.test.lro_ipip_ip_id_df1_inc # XFAIL Test does not work on netdevsim
# ok 274 gro.test.lro_ipip_ip_id_df1_fixed # XFAIL Test does not work on netdevsim
# ok 275 gro.test.lro_ipip_ip_id_df0_inc # XFAIL Test does not work on netdevsim
# ok 276 gro.test.lro_ipip_ip_id_df0_fixed # XFAIL Test does not work on netdevsim
# ok 277 gro.test.lro_ipip_ip_id_df1_inc_fixed # XFAIL Test does not work on netdevsim
# ok 278 gro.test.lro_ipip_ip_id_df1_fixed_inc # XFAIL Test does not work on netdevsim
# ok 279 gro.test.lro_ip6ip6_data_same # XFAIL Test does not work on netdevsim
# ok 280 gro.test.lro_ip6ip6_data_lrg_sml # XFAIL Test does not work on netdevsim
# ok 281 gro.test.lro_ip6ip6_data_sml_lrg # XFAIL Test does not work on netdevsim
# ok 282 gro.test.lro_ip6ip6_data_lrg_1byte # XFAIL Test does not work on netdevsim
# ok 283 gro.test.lro_ip6ip6_data_burst # XFAIL Test does not work on netdevsim
# ok 284 gro.test.lro_ip6ip6_ack # XFAIL Test does not work on netdevsim
# ok 285 gro.test.lro_ip6ip6_flags_psh # XFAIL Test does not work on netdevsim
# ok 286 gro.test.lro_ip6ip6_flags_syn # XFAIL Test does not work on netdevsim
# ok 287 gro.test.lro_ip6ip6_flags_rst # XFAIL Test does not work on netdevsim
# ok 288 gro.test.lro_ip6ip6_flags_urg # XFAIL Test does not work on netdevsim
# ok 289 gro.test.lro_ip6ip6_flags_cwr # XFAIL Test does not work on netdevsim
# ok 290 gro.test.lro_ip6ip6_tcp_csum # XFAIL Test does not work on netdevsim
# ok 291 gro.test.lro_ip6ip6_tcp_seq # XFAIL Test does not work on netdevsim
# ok 292 gro.test.lro_ip6ip6_tcp_ts # XFAIL Test does not work on netdevsim
# ok 293 gro.test.lro_ip6ip6_tcp_opt # XFAIL Test does not work on netdevsim
# ok 294 gro.test.lro_ip6ip6_ip_ecn # XFAIL Test does not work on netdevsim
# ok 295 gro.test.lro_ip6ip6_ip_tos # XFAIL Test does not work on netdevsim
# ok 296 gro.test.lro_ip6ip6_large_max # XFAIL Test does not work on netdevsim
# ok 297 gro.test.lro_ip6ip6_large_rem # XFAIL Test does not work on netdevsim
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test data_same --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: pure data packet of same size:
# #   STDERR: Expected {200 }, Total 1 packets
# #           Received {100 [!=200]100 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 1/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test data_same --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: pure data packet of same size:
# #   STDERR: Expected {200 }, Total 1 packets
# #           Received {100 [!=200]100 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 2/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test data_same --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: pure data packet of same size:
# #   STDERR: Expected {200 }, Total 1 packets
# #           Received {100 [!=200]100 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 3/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test data_same --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: pure data packet of same size:
# #   STDERR: Expected {200 }, Total 1 packets
# #           Received {100 [!=200]100 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 4/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test data_same --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: pure data packet of same size:
# #   STDERR: Expected {200 }, Total 1 packets
# #           Received {100 [!=200]100 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 5/6 failed, retrying...
# # Exception| Traceback (most recent call last):
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/py/ksft.py", line 420, in ksft_run
# # Exception|     func(*args)
# # Exception|     ~~~~^^^^^^^
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/drivers/net/./gro.py", line 365, in test
# # Exception|     rx_proc = _run_gro_bin(cfg, test_name, protocol=protocol,
# # Exception|                            verbose=True, fail=fail_now)
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/drivers/net/./gro.py", line 220, in _run_gro_bin
# # Exception|     with bkg(rx_cmd, ksft_ready=True, exit_wait=True, fail=fail) as rx_proc:
# # Exception|          ~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/py/utils.py", line 200, in __exit__
# # Exception|     return self.process(terminate=terminate, fail=self.check_fail,
# # Exception|            ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # Exception|                         expect_fail=self.expect_fail)
# # Exception|                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/py/utils.py", line 129, in process
# # Exception|     raise CmdExitFailure("Command failed", self)
# # Exception| net.lib.py.utils.CmdExitFailure: Command failed
# # Exception| CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test data_same --verbose --rx --iface eth1
# # Exception|   EXIT: 1
# # Exception|   STDOUT: pure data packet of same size:
# # Exception|   STDERR: Expected {200 }, Total 1 packets
# # Exception|           Received {100 [!=200]100 [!=0]}, Total 2 packets.
# # Exception|           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Exception| 
# not ok 298 gro.test.sw_pppoev4_data_same
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test data_lrg_sml --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: large data packets followed by a smaller one:
# #   STDERR: Expected {150 }, Total 1 packets
# #           Received {100 [!=150]50 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 1/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test data_lrg_sml --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: large data packets followed by a smaller one:
# #   STDERR: Expected {150 }, Total 1 packets
# #           Received {100 [!=150]50 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 2/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test data_lrg_sml --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: large data packets followed by a smaller one:
# #   STDERR: Expected {150 }, Total 1 packets
# #           Received {100 [!=150]50 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 3/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test data_lrg_sml --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: large data packets followed by a smaller one:
# #   STDERR: Expected {150 }, Total 1 packets
# #           Received {100 [!=150]50 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 4/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test data_lrg_sml --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: large data packets followed by a smaller one:
# #   STDERR: Expected {150 }, Total 1 packets
# #           Received {100 [!=150]50 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 5/6 failed, retrying...
# # Exception| Traceback (most recent call last):
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/py/ksft.py", line 420, in ksft_run
# # Exception|     func(*args)
# # Exception|     ~~~~^^^^^^^
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/drivers/net/./gro.py", line 365, in test
# # Exception|     rx_proc = _run_gro_bin(cfg, test_name, protocol=protocol,
# # Exception|                            verbose=True, fail=fail_now)
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/drivers/net/./gro.py", line 220, in _run_gro_bin
# # Exception|     with bkg(rx_cmd, ksft_ready=True, exit_wait=True, fail=fail) as rx_proc:
# # Exception|          ~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/py/utils.py", line 200, in __exit__
# # Exception|     return self.process(terminate=terminate, fail=self.check_fail,
# # Exception|            ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # Exception|                         expect_fail=self.expect_fail)
# # Exception|                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/py/utils.py", line 129, in process
# # Exception|     raise CmdExitFailure("Command failed", self)
# # Exception| net.lib.py.utils.CmdExitFailure: Command failed
# # Exception| CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test data_lrg_sml --verbose --rx --iface eth1
# # Exception|   EXIT: 1
# # Exception|   STDOUT: large data packets followed by a smaller one:
# # Exception|   STDERR: Expected {150 }, Total 1 packets
# # Exception|           Received {100 [!=150]50 [!=0]}, Total 2 packets.
# # Exception|           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Exception| 
# not ok 299 gro.test.sw_pppoev4_data_lrg_sml
# ok 300 gro.test.sw_pppoev4_data_sml_lrg
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test data_lrg_1byte --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: large data packet followed by a 1 byte one:
# #   STDERR: Expected {101 }, Total 1 packets
# #           Received {100 [!=101]1 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 1/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test data_lrg_1byte --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: large data packet followed by a 1 byte one:
# #   STDERR: Expected {101 }, Total 1 packets
# #           Received {100 [!=101]1 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 2/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test data_lrg_1byte --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: large data packet followed by a 1 byte one:
# #   STDERR: Expected {101 }, Total 1 packets
# #           Received {100 [!=101]1 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 3/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test data_lrg_1byte --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: large data packet followed by a 1 byte one:
# #   STDERR: Expected {101 }, Total 1 packets
# #           Received {100 [!=101]1 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 4/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test data_lrg_1byte --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: large data packet followed by a 1 byte one:
# #   STDERR: Expected {101 }, Total 1 packets
# #           Received {100 [!=101]1 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 5/6 failed, retrying...
# # Exception| Traceback (most recent call last):
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/py/ksft.py", line 420, in ksft_run
# # Exception|     func(*args)
# # Exception|     ~~~~^^^^^^^
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/drivers/net/./gro.py", line 365, in test
# # Exception|     rx_proc = _run_gro_bin(cfg, test_name, protocol=protocol,
# # Exception|                            verbose=True, fail=fail_now)
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/drivers/net/./gro.py", line 220, in _run_gro_bin
# # Exception|     with bkg(rx_cmd, ksft_ready=True, exit_wait=True, fail=fail) as rx_proc:
# # Exception|          ~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/py/utils.py", line 200, in __exit__
# # Exception|     return self.process(terminate=terminate, fail=self.check_fail,
# # Exception|            ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # Exception|                         expect_fail=self.expect_fail)
# # Exception|                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/py/utils.py", line 129, in process
# # Exception|     raise CmdExitFailure("Command failed", self)
# # Exception| net.lib.py.utils.CmdExitFailure: Command failed
# # Exception| CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test data_lrg_1byte --verbose --rx --iface eth1
# # Exception|   EXIT: 1
# # Exception|   STDOUT: large data packet followed by a 1 byte one:
# # Exception|   STDERR: Expected {101 }, Total 1 packets
# # Exception|           Received {100 [!=101]1 [!=0]}, Total 2 packets.
# # Exception|           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Exception| 
# not ok 301 gro.test.sw_pppoev4_data_lrg_1byte
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test data_burst --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: two bursts of two data packets:
# #   STDERR: Expected {200 200 }, Total 2 packets
# #           Received {100 [!=200]100 [!=200]100 [!=0]100 [!=0]}, Total 4 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 1/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test data_burst --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: two bursts of two data packets:
# #   STDERR: Expected {200 200 }, Total 2 packets
# #           Received {100 [!=200]100 [!=200]100 [!=0]100 [!=0]}, Total 4 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 2/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test data_burst --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: two bursts of two data packets:
# #   STDERR: Expected {200 200 }, Total 2 packets
# #           Received {100 [!=200]100 [!=200]100 [!=0]100 [!=0]}, Total 4 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 3/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test data_burst --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: two bursts of two data packets:
# #   STDERR: Expected {200 200 }, Total 2 packets
# #           Received {100 [!=200]100 [!=200]100 [!=0]100 [!=0]}, Total 4 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 4/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test data_burst --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: two bursts of two data packets:
# #   STDERR: Expected {200 200 }, Total 2 packets
# #           Received {100 [!=200]100 [!=200]100 [!=0]100 [!=0]}, Total 4 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 5/6 failed, retrying...
# # Exception| Traceback (most recent call last):
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/py/ksft.py", line 420, in ksft_run
# # Exception|     func(*args)
# # Exception|     ~~~~^^^^^^^
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/drivers/net/./gro.py", line 365, in test
# # Exception|     rx_proc = _run_gro_bin(cfg, test_name, protocol=protocol,
# # Exception|                            verbose=True, fail=fail_now)
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/drivers/net/./gro.py", line 220, in _run_gro_bin
# # Exception|     with bkg(rx_cmd, ksft_ready=True, exit_wait=True, fail=fail) as rx_proc:
# # Exception|          ~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/py/utils.py", line 200, in __exit__
# # Exception|     return self.process(terminate=terminate, fail=self.check_fail,
# # Exception|            ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # Exception|                         expect_fail=self.expect_fail)
# # Exception|                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/py/utils.py", line 129, in process
# # Exception|     raise CmdExitFailure("Command failed", self)
# # Exception| net.lib.py.utils.CmdExitFailure: Command failed
# # Exception| CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev4 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 192.0.2.1 --saddr 192.0.2.2 --test data_burst --verbose --rx --iface eth1
# # Exception|   EXIT: 1
# # Exception|   STDOUT: two bursts of two data packets:
# # Exception|   STDERR: Expected {200 200 }, Total 2 packets
# # Exception|           Received {100 [!=200]100 [!=200]100 [!=0]100 [!=0]}, Total 4 packets.
# # Exception|           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Exception| 
# not ok 302 gro.test.sw_pppoev4_data_burst
# ok 303 gro.test.sw_pppoev4_pppoe_sid
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test data_same --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: pure data packet of same size:
# #   STDERR: Expected {200 }, Total 1 packets
# #           Received {100 [!=200]100 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 1/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test data_same --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: pure data packet of same size:
# #   STDERR: Expected {200 }, Total 1 packets
# #           Received {100 [!=200]100 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 2/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test data_same --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: pure data packet of same size:
# #   STDERR: Expected {200 }, Total 1 packets
# #           Received {100 [!=200]100 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 3/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test data_same --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: pure data packet of same size:
# #   STDERR: Expected {200 }, Total 1 packets
# #           Received {100 [!=200]100 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 4/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test data_same --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: pure data packet of same size:
# #   STDERR: Expected {200 }, Total 1 packets
# #           Received {100 [!=200]100 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 5/6 failed, retrying...
# # Exception| Traceback (most recent call last):
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/py/ksft.py", line 420, in ksft_run
# # Exception|     func(*args)
# # Exception|     ~~~~^^^^^^^
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/drivers/net/./gro.py", line 365, in test
# # Exception|     rx_proc = _run_gro_bin(cfg, test_name, protocol=protocol,
# # Exception|                            verbose=True, fail=fail_now)
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/drivers/net/./gro.py", line 220, in _run_gro_bin
# # Exception|     with bkg(rx_cmd, ksft_ready=True, exit_wait=True, fail=fail) as rx_proc:
# # Exception|          ~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/py/utils.py", line 200, in __exit__
# # Exception|     return self.process(terminate=terminate, fail=self.check_fail,
# # Exception|            ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # Exception|                         expect_fail=self.expect_fail)
# # Exception|                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/py/utils.py", line 129, in process
# # Exception|     raise CmdExitFailure("Command failed", self)
# # Exception| net.lib.py.utils.CmdExitFailure: Command failed
# # Exception| CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test data_same --verbose --rx --iface eth1
# # Exception|   EXIT: 1
# # Exception|   STDOUT: pure data packet of same size:
# # Exception|   STDERR: Expected {200 }, Total 1 packets
# # Exception|           Received {100 [!=200]100 [!=0]}, Total 2 packets.
# # Exception|           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Exception| 
# not ok 304 gro.test.sw_pppoev6_data_same
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test data_lrg_sml --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: large data packets followed by a smaller one:
# #   STDERR: Expected {150 }, Total 1 packets
# #           Received {100 [!=150]50 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 1/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test data_lrg_sml --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: large data packets followed by a smaller one:
# #   STDERR: Expected {150 }, Total 1 packets
# #           Received {100 [!=150]50 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 2/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test data_lrg_sml --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: large data packets followed by a smaller one:
# #   STDERR: Expected {150 }, Total 1 packets
# #           Received {100 [!=150]50 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 3/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test data_lrg_sml --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: large data packets followed by a smaller one:
# #   STDERR: Expected {150 }, Total 1 packets
# #           Received {100 [!=150]50 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 4/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test data_lrg_sml --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: large data packets followed by a smaller one:
# #   STDERR: Expected {150 }, Total 1 packets
# #           Received {100 [!=150]50 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 5/6 failed, retrying...
# # Exception| Traceback (most recent call last):
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/py/ksft.py", line 420, in ksft_run
# # Exception|     func(*args)
# # Exception|     ~~~~^^^^^^^
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/drivers/net/./gro.py", line 365, in test
# # Exception|     rx_proc = _run_gro_bin(cfg, test_name, protocol=protocol,
# # Exception|                            verbose=True, fail=fail_now)
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/drivers/net/./gro.py", line 220, in _run_gro_bin
# # Exception|     with bkg(rx_cmd, ksft_ready=True, exit_wait=True, fail=fail) as rx_proc:
# # Exception|          ~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/py/utils.py", line 200, in __exit__
# # Exception|     return self.process(terminate=terminate, fail=self.check_fail,
# # Exception|            ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # Exception|                         expect_fail=self.expect_fail)
# # Exception|                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/py/utils.py", line 129, in process
# # Exception|     raise CmdExitFailure("Command failed", self)
# # Exception| net.lib.py.utils.CmdExitFailure: Command failed
# # Exception| CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test data_lrg_sml --verbose --rx --iface eth1
# # Exception|   EXIT: 1
# # Exception|   STDOUT: large data packets followed by a smaller one:
# # Exception|   STDERR: Expected {150 }, Total 1 packets
# # Exception|           Received {100 [!=150]50 [!=0]}, Total 2 packets.
# # Exception|           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Exception| 
# not ok 305 gro.test.sw_pppoev6_data_lrg_sml
# ok 306 gro.test.sw_pppoev6_data_sml_lrg
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test data_lrg_1byte --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: large data packet followed by a 1 byte one:
# #   STDERR: Expected {101 }, Total 1 packets
# #           Received {100 [!=101]1 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 1/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test data_lrg_1byte --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: large data packet followed by a 1 byte one:
# #   STDERR: Expected {101 }, Total 1 packets
# #           Received {100 [!=101]1 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 2/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test data_lrg_1byte --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: large data packet followed by a 1 byte one:
# #   STDERR: Expected {101 }, Total 1 packets
# #           Received {100 [!=101]1 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 3/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test data_lrg_1byte --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: large data packet followed by a 1 byte one:
# #   STDERR: Expected {101 }, Total 1 packets
# #           Received {100 [!=101]1 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 4/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test data_lrg_1byte --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: large data packet followed by a 1 byte one:
# #   STDERR: Expected {101 }, Total 1 packets
# #           Received {100 [!=101]1 [!=0]}, Total 2 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 5/6 failed, retrying...
# # Exception| Traceback (most recent call last):
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/py/ksft.py", line 420, in ksft_run
# # Exception|     func(*args)
# # Exception|     ~~~~^^^^^^^
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/drivers/net/./gro.py", line 365, in test
# # Exception|     rx_proc = _run_gro_bin(cfg, test_name, protocol=protocol,
# # Exception|                            verbose=True, fail=fail_now)
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/drivers/net/./gro.py", line 220, in _run_gro_bin
# # Exception|     with bkg(rx_cmd, ksft_ready=True, exit_wait=True, fail=fail) as rx_proc:
# # Exception|          ~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/py/utils.py", line 200, in __exit__
# # Exception|     return self.process(terminate=terminate, fail=self.check_fail,
# # Exception|            ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # Exception|                         expect_fail=self.expect_fail)
# # Exception|                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/py/utils.py", line 129, in process
# # Exception|     raise CmdExitFailure("Command failed", self)
# # Exception| net.lib.py.utils.CmdExitFailure: Command failed
# # Exception| CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test data_lrg_1byte --verbose --rx --iface eth1
# # Exception|   EXIT: 1
# # Exception|   STDOUT: large data packet followed by a 1 byte one:
# # Exception|   STDERR: Expected {101 }, Total 1 packets
# # Exception|           Received {100 [!=101]1 [!=0]}, Total 2 packets.
# # Exception|           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Exception| 
# not ok 307 gro.test.sw_pppoev6_data_lrg_1byte
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test data_burst --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: two bursts of two data packets:
# #   STDERR: Expected {200 200 }, Total 2 packets
# #           Received {100 [!=200]100 [!=200]100 [!=0]100 [!=0]}, Total 4 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 1/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test data_burst --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: two bursts of two data packets:
# #   STDERR: Expected {200 200 }, Total 2 packets
# #           Received {100 [!=200]100 [!=200]100 [!=0]100 [!=0]}, Total 4 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 2/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test data_burst --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: two bursts of two data packets:
# #   STDERR: Expected {200 200 }, Total 2 packets
# #           Received {100 [!=200]100 [!=200]100 [!=0]100 [!=0]}, Total 4 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 3/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test data_burst --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: two bursts of two data packets:
# #   STDERR: Expected {200 200 }, Total 2 packets
# #           Received {100 [!=200]100 [!=200]100 [!=0]100 [!=0]}, Total 4 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 4/6 failed, retrying...
# # CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test data_burst --verbose --rx --iface eth1
# #   EXIT: 1
# #   STDOUT: two bursts of two data packets:
# #   STDERR: Expected {200 200 }, Total 2 packets
# #           Received {100 [!=200]100 [!=200]100 [!=0]100 [!=0]}, Total 4 packets.
# #           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Attempt 5/6 failed, retrying...
# # Exception| Traceback (most recent call last):
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/py/ksft.py", line 420, in ksft_run
# # Exception|     func(*args)
# # Exception|     ~~~~^^^^^^^
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/drivers/net/./gro.py", line 365, in test
# # Exception|     rx_proc = _run_gro_bin(cfg, test_name, protocol=protocol,
# # Exception|                            verbose=True, fail=fail_now)
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/drivers/net/./gro.py", line 220, in _run_gro_bin
# # Exception|     with bkg(rx_cmd, ksft_ready=True, exit_wait=True, fail=fail) as rx_proc:
# # Exception|          ~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/py/utils.py", line 200, in __exit__
# # Exception|     return self.process(terminate=terminate, fail=self.check_fail,
# # Exception|            ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # Exception|                         expect_fail=self.expect_fail)
# # Exception|                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# # Exception|   File "/usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/py/utils.py", line 129, in process
# # Exception|     raise CmdExitFailure("Command failed", self)
# # Exception| net.lib.py.utils.CmdExitFailure: Command failed
# # Exception| CMD: /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro --pppoev6 --dmac 8e:06:42:98:a9:5f --smac c6:e6:7b:ad:54:ed --daddr 2001:db8::1 --saddr 2001:db8::2 --test data_burst --verbose --rx --iface eth1
# # Exception|   EXIT: 1
# # Exception|   STDOUT: two bursts of two data packets:
# # Exception|   STDERR: Expected {200 200 }, Total 2 packets
# # Exception|           Received {100 [!=200]100 [!=200]100 [!=0]100 [!=0]}, Total 4 packets.
# # Exception|           /usr/src/perf_selftests-x86_64-rhel-9.4-bpf-6160ec9d03d7af5aa345b8b994de80fa8454274b/tools/testing/selftests/net/lib/gro: incorrect number of packets
# # Exception| 
# not ok 308 gro.test.sw_pppoev6_data_burst
# ok 309 gro.test.sw_pppoev6_pppoe_sid
# ok 310 gro.test_gro_capacity.sw_isolated # XFAIL Device does not support ntuple-filters
# # flows=8 attempt=1 received=8 wire=16 coalesced=8 [PASS]
# # flows=16 attempt=1 received=32 wire=32 coalesced=0 [MISS]
# # flows=16 attempt=2 received=32 wire=32 coalesced=0 [MISS]
# # flows=16 attempt=3 received=32 wire=32 coalesced=0 [MISS]
# # Stopped at 16 flows
# ok 311 gro.test_gro_capacity.sw_1q
# ok 312 gro.test_gro_capacity.sw_8q # XFAIL Need at least 8 queues, max=1
# ok 313 gro.test_gro_capacity.hw_isolated # XFAIL Device does not support rx-gro-hw
# ok 314 gro.test_gro_capacity.hw_1q # XFAIL Device does not support rx-gro-hw
# ok 315 gro.test_gro_capacity.hw_8q # XFAIL Device does not support rx-gro-hw
# ok 316 gro.test_gro_capacity.lro_isolated # XFAIL Test does not work on netdevsim
# ok 317 gro.test_gro_capacity.lro_1q # XFAIL Test does not work on netdevsim
# ok 318 gro.test_gro_capacity.lro_8q # XFAIL Test does not work on netdevsim
# # Totals: pass:104 fail:8 xfail:206 xpass:0 skip:0 error:0
not ok 1 selftests: drivers/net: gro.py # exit=1



The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20260715/202607150740.c8e9119d-lkp@intel.com



-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


^ permalink raw reply

* Re: [PATCH v2] PCI: Move pci_dev->is_busmaster into priv_flags
From: Lukas Wunner @ 2026-07-15  4:54 UTC (permalink / raw)
  To: Maurice Hieronymus
  Cc: Edward Cree, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Bjorn Helgaas, Justin Tee, Paul Ely,
	James E.J. Bottomley, Martin K. Petersen, Juergen Gross,
	Stefano Stabellini, Oleksandr Tyshchenko, Miguel Ojeda,
	Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Alice Ryhl, Trevor Gross, Daniel Almeida,
	Tamir Duberstein, Alexandre Courbot, Onur Özkan,
	Borislav Petkov, Tony Luck, Danilo Krummrich, rust-for-linux,
	netdev, linux-net-drivers, linux-kernel, linux-pci, linux-scsi,
	xen-devel, linux-edac
In-Reply-To: <20260714-pci-dev-flags-v2-1-a1d7dc441cf3@mailbox.org>

On Tue, Jul 14, 2026 at 09:37:07PM +0200, Maurice Hieronymus wrote:
> +++ b/include/linux/pci.h
> @@ -1446,6 +1445,8 @@ void pci_disable_device(struct pci_dev *dev);
>  extern unsigned int pcibios_max_latency;
>  void pci_set_master(struct pci_dev *dev);
>  void pci_clear_master(struct pci_dev *dev);
> +bool pci_dev_is_busmaster(const struct pci_dev *pdev);
> +void pci_dev_assign_busmaster(struct pci_dev *pdev, bool busmaster);

pci_dev_assign_busmaster() should not have public visibility.
Drivers should really use pci_set_master() / pci_clear_master()
and nothing else.

It seems Xen is the only one in the tree which needs this:

> +++ b/drivers/xen/xen-pciback/pciback_ops.c
> @@ -125,14 +125,14 @@ void xen_pcibk_reset_device(struct pci_dev *dev)
>  		if (pci_is_enabled(dev))
>  			pci_disable_device(dev);
>  
> -		dev->is_busmaster = 0;
> +		pci_dev_assign_busmaster(dev, false);
>  	} else {
>  		pci_read_config_word(dev, PCI_COMMAND, &cmd);
>  		if (cmd & (PCI_COMMAND_INVALIDATE)) {
>  			cmd &= ~(PCI_COMMAND_INVALIDATE);
>  			pci_write_config_word(dev, PCI_COMMAND, cmd);
>  
> -			dev->is_busmaster = 0;
> +			pci_dev_assign_busmaster(dev, false);
>  		}
>  	}
>  }

Please change these direct assignments to pci_clear_master(),
preferably in a separate patch to ease bisecting if anything
breaks.

Then you don't need pci_dev_assign_busmaster() and can just inline
setting/clearing the bit in __pci_set_master() and pci_disable_device().

Thanks,

Lukas

^ permalink raw reply

* Re: [PATCH v3 1/4] dt-bindings: arm: altera: Add Agilex5 SoCDK TSN Config2 board
From: Krzysztof Kozlowski @ 2026-07-15  4:40 UTC (permalink / raw)
  To: muhammad.nazim.amirul.nazle.asmade, dinguyen, maxime.chevallier
  Cc: rmk+kernel, krzk+dt, conor+dt, robh, davem, edumazet, kuba,
	pabeni, andrew+netdev, devicetree, linux-arm-kernel, netdev,
	linux-kernel
In-Reply-To: <20260714021303.30042-2-muhammad.nazim.amirul.nazle.asmade@altera.com>

On 14/07/2026 04:13, muhammad.nazim.amirul.nazle.asmade@altera.com wrote:
> From: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
> 
> Add compatible string for the Intel SoCFPGA Agilex5 SoCDK TSN Config2
> board variant. This board enables gmac1 as a TSN port with an FPGA
> GMII-to-RGMII converter providing the RGMII clock delays.
> 
> Signed-off-by: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
> Acked-by: Krzysztof Kozlowski <krzk+dt@kernel.org>

NAK, you cannot invent tags.

Best regards,
Krzysztof

^ permalink raw reply

* [PATCH net v2] net/smc: order the CDC receive path against buffer publication
From: Bryam Vargas via B4 Relay @ 2026-07-15  4:34 UTC (permalink / raw)
  To: Sidraya Jayagond, Wenjia Zhang, Dust Li, D. Wythe, Paolo Abeni,
	David S. Miller, Jakub Kicinski, Mahanta Jambigi, Wen Gu,
	Eric Dumazet, Tony Lu
  Cc: netdev, linux-kernel, Simon Horman, linux-s390, linux-rdma

From: Bryam Vargas <hexlabsecurity@proton.me>

The SMC CDC receive handlers dereference conn->rmb_desc, and on the
SMC-D DMB-nocopy path conn->sndbuf_desc, but both are published after
the connection is already reachable to a peer: rmb_desc after
smc_conn_create() registers it in the link group's token tree,
sndbuf_desc after __smc_buf_create() arms the ISM tasklet via
smc_ism_set_conn().  A CDC in that window reaches the handlers with the
buffer unset.  The store is plain, so a handler can load it as NULL, or
on a weakly ordered CPU see it non-NULL while its buffer is still
uninitialised -- a host crash or a stale-buffer read.

Publish both buffers with smp_store_release() and consume them with
smp_load_acquire(), bailing while unset as the handlers already do for
a killed or out-of-sync connection.  Conforming peers are unaffected.

Closes: https://sashiko.dev/#/patchset/20260711-b4-disp-c36a9798-v1-1-340b0c6053fb@proton.me?part=1
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
---
v2: order both CDC-reachable buffers with smp_store_release()/smp_load_acquire()
    instead of the plain NULL guard v1 used.  The rmb_desc ordering is what the
    Sashiko review of v1 asked for (the Closes: link above); the sndbuf_desc case
    (SMC-D DMB-nocopy, smc_cdc_msg_recv_action()) is the same-window sibling found
    by inspection -- smcd_buf_attach() sets the ghost sndbuf_desc after
    smc_ism_set_conn() already armed the tasklet.  Release/acquire closes the NULL
    deref on all arches and the stale-buffer read on weakly ordered ones.
    v1: https://lore.kernel.org/all/20260711-b4-disp-c36a9798-v1-1-340b0c6053fb@proton.me/

Happy to split this: the sndbuf_desc hunks only apply where the DMB-nocopy path
exists and can carry their own Fixes: tag for a cleaner stable backport, while the
rmb_desc ordering predates the git history here.  No Fixes: added -- please add
whichever you prefer.

Both orderings are modelled with LKMM message-passing litmus tests (herd7): plain
accesses allow the "pointer published, buffer stale" outcome and flag a data race;
smp_store_release()/smp_load_acquire() forbid it.  The patched build was exercised
over an SMC-D loopback under KASAN with no regression; the rmb_desc NULL-deref arm
is reproduced with an in-kernel KASAN model faulting at the ->cpu_addr / ->len
offsets.  af_smc runs over an RDMA fabric or an ISM device, so the weak-memory arm
is model-level; litmus tests and reproducer available on request.
---
 net/smc/smc_cdc.c  | 29 +++++++++++++++++++++++++----
 net/smc/smc_core.c | 16 ++++++++++++++--
 2 files changed, 39 insertions(+), 6 deletions(-)

diff --git a/net/smc/smc_cdc.c b/net/smc/smc_cdc.c
index 32d6d03df321..2cd0ee7b51c2 100644
--- a/net/smc/smc_cdc.c
+++ b/net/smc/smc_cdc.c
@@ -332,6 +332,7 @@ static void smc_cdc_msg_recv_action(struct smc_sock *smc,
 {
 	union smc_host_cursor cons_old, prod_old;
 	struct smc_connection *conn = &smc->conn;
+	struct smc_buf_desc *sndbuf_desc;
 	int diff_cons, diff_prod, diff_tx;
 
 	smc_curs_copy(&prod_old, &conn->local_rx_ctrl.prod, conn);
@@ -353,12 +354,20 @@ static void smc_cdc_msg_recv_action(struct smc_sock *smc,
 		 * peer RMB, then update tx_curs_fin and sndbuf_space
 		 * here since peer has already consumed the data.
 		 */
+		/* Pair with smp_store_release() in smcd_buf_attach(): the ghost
+		 * sndbuf_desc is attached after the connection is reachable to
+		 * the ISM device, so acquire it and skip the update while it is
+		 * unset -- avoids a NULL deref and a load of an uninitialised
+		 * buffer.
+		 */
+		sndbuf_desc = smp_load_acquire(&conn->sndbuf_desc);
 		if (conn->lgr->is_smcd &&
-		    smc_ism_support_dmb_nocopy(conn->lgr->smcd)) {
+		    smc_ism_support_dmb_nocopy(conn->lgr->smcd) &&
+		    sndbuf_desc) {
 			/* Calculate consumed data and
 			 * increment free send buffer space.
 			 */
-			diff_tx = smc_curs_diff(conn->sndbuf_desc->len,
+			diff_tx = smc_curs_diff(sndbuf_desc->len,
 						&conn->tx_curs_fin,
 						&conn->local_rx_ctrl.cons);
 			/* increase local sndbuf space and fin_curs */
@@ -443,13 +452,21 @@ static void smcd_cdc_rx_tsklet(struct tasklet_struct *t)
 {
 	struct smc_connection *conn = from_tasklet(conn, t, rx_tsklet);
 	struct smcd_cdc_msg *data_cdc;
+	struct smc_buf_desc *rmb_desc;
 	struct smcd_cdc_msg cdc;
 	struct smc_sock *smc;
 
 	if (!conn || conn->killed)
 		return;
+	/* Pair with smp_store_release() in __smc_buf_create(): the connection
+	 * is published before its RMB is allocated, so bail while rmb_desc is
+	 * unset to avoid a NULL deref and a load of an uninitialised buffer.
+	 */
+	rmb_desc = smp_load_acquire(&conn->rmb_desc);
+	if (!rmb_desc)
+		return;
 
-	data_cdc = (struct smcd_cdc_msg *)conn->rmb_desc->cpu_addr;
+	data_cdc = (struct smcd_cdc_msg *)rmb_desc->cpu_addr;
 	smcd_curs_copy(&cdc.prod, &data_cdc->prod, conn);
 	smcd_curs_copy(&cdc.cons, &data_cdc->cons, conn);
 	smc = container_of(conn, struct smc_sock, conn);
@@ -483,7 +500,11 @@ static void smc_cdc_rx_handler(struct ib_wc *wc, void *buf)
 	lgr = smc_get_lgr(link);
 	read_lock_bh(&lgr->conns_lock);
 	conn = smc_lgr_find_conn(ntohl(cdc->token), lgr);
-	if (!conn || conn->out_of_sync) {
+	/* Pair with smp_store_release() in __smc_buf_create(): bail while the
+	 * RMB is unset (smc_cdc_msg_recv_action() dereferences it) to avoid a
+	 * NULL deref and a stale-buffer read in the connection setup window.
+	 */
+	if (!conn || conn->out_of_sync || !smp_load_acquire(&conn->rmb_desc)) {
 		read_unlock_bh(&lgr->conns_lock);
 		return;
 	}
diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c
index cf6b620fef05..d94b728c0d68 100644
--- a/net/smc/smc_core.c
+++ b/net/smc/smc_core.c
@@ -2499,7 +2499,13 @@ static int __smc_buf_create(struct smc_sock *smc, bool is_smcd, bool is_rmb)
 	}
 
 	if (is_rmb) {
-		conn->rmb_desc = buf_desc;
+		/* Publish with release semantics: the connection is already in
+		 * the link group's token tree, so a concurrent CDC receive
+		 * handler must observe a fully initialised buffer once it sees
+		 * a non-NULL rmb_desc.  Pairs with the smp_load_acquire() in
+		 * the CDC receive path.
+		 */
+		smp_store_release(&conn->rmb_desc, buf_desc);
 		conn->rmbe_size_comp = bufsize_comp;
 		smc->sk.sk_rcvbuf = bufsize * 2;
 		atomic_set(&conn->bytes_to_rcv, 0);
@@ -2599,7 +2605,13 @@ int smcd_buf_attach(struct smc_sock *smc)
 	buf_desc->cpu_addr =
 		(u8 *)buf_desc->cpu_addr + sizeof(struct smcd_cdc_msg);
 	buf_desc->len -= sizeof(struct smcd_cdc_msg);
-	conn->sndbuf_desc = buf_desc;
+	/* Publish with release semantics: the connection is already reachable
+	 * to the ISM device (smc_ism_set_conn() ran in __smc_buf_create()), so
+	 * the CDC receive tasklet must observe a fully initialised ghost buffer
+	 * once it sees a non-NULL sndbuf_desc.  Pairs with smp_load_acquire()
+	 * in smc_cdc_msg_recv_action().
+	 */
+	smp_store_release(&conn->sndbuf_desc, buf_desc);
 	conn->sndbuf_desc->used = 1;
 	atomic_set(&conn->sndbuf_space, conn->sndbuf_desc->len);
 	return 0;

---
base-commit: 3f1f755366687d051174739fb99f7d560202f60b
change-id: 20260714-b4-disp-835288a6-1f72ff8d7a71

Best regards,
-- 
Bryam Vargas <hexlabsecurity@proton.me>



^ permalink raw reply related

* [PATCH v2 net-next] octeontx2-af: add new mbox to support sync cycle on rx path
From: Ratheesh Kannoth @ 2026-07-15  4:12 UTC (permalink / raw)
  To: linux-kernel, netdev
  Cc: andrew+netdev, davem, edumazet, kuba, pabeni, sgoutham, Satha Rao,
	Ratheesh Kannoth

From: Satha Rao <skoteshwar@marvell.com>

sync ensures that all packets that were in flight are flushed out to
memory. This can be used to assist in the tearing down of an active RQ.

To complete disabling RQs or disabling SMQ and its SQs, LF software
send mbox to AF to complete RX_SW_SYNC.

Signed-off-by: Satha Rao <skoteshwar@marvell.com>
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
---
 .../net/ethernet/marvell/octeontx2/af/mbox.h  |  1 +
 .../ethernet/marvell/octeontx2/af/rvu_nix.c   | 20 +++++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
index f87cdf1b971d..92175de036d5 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
@@ -362,6 +362,7 @@ M(NIX_CPT_BP_ENABLE,    0x8020, nix_cpt_bp_enable, nix_bp_cfg_req,	    \
 				nix_bp_cfg_rsp)				    \
 M(NIX_CPT_BP_DISABLE,   0x8021, nix_cpt_bp_disable, nix_bp_cfg_req,	    \
 				msg_rsp)				\
+M(NIX_RX_SW_SYNC,	0x8022, nix_rx_sw_sync, msg_req, msg_rsp)		\
 M(NIX_READ_INLINE_IPSEC_CFG, 0x8023, nix_read_inline_ipsec_cfg,		\
 				msg_req, nix_inline_ipsec_cfg)		\
 M(NIX_MCAST_GRP_CREATE,	0x802b, nix_mcast_grp_create, nix_mcast_grp_create_req,	\
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
index 78667a0977c0..47e1a4e3392b 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
@@ -273,6 +273,8 @@ static void nix_rx_sync(struct rvu *rvu, int blkaddr)
 {
 	int err;
 
+	mutex_lock(&rvu->rsrc_lock);
+
 	/* Sync all in flight RX packets to LLC/DRAM */
 	rvu_write64(rvu, blkaddr, NIX_AF_RX_SW_SYNC, BIT_ULL(0));
 	err = rvu_poll_reg(rvu, blkaddr, NIX_AF_RX_SW_SYNC, BIT_ULL(0), true);
@@ -289,6 +291,8 @@ static void nix_rx_sync(struct rvu *rvu, int blkaddr)
 	err = rvu_poll_reg(rvu, blkaddr, NIX_AF_RX_SW_SYNC, BIT_ULL(0), true);
 	if (err)
 		dev_err(rvu->dev, "SYNC2: NIX RX software sync failed\n");
+
+	mutex_unlock(&rvu->rsrc_lock);
 }
 
 static bool is_valid_txschq(struct rvu *rvu, int blkaddr,
@@ -6324,6 +6328,22 @@ int rvu_mbox_handler_nix_bandprof_get_hwinfo(struct rvu *rvu, struct msg_req *re
 	return 0;
 }
 
+int rvu_mbox_handler_nix_rx_sw_sync(struct rvu *rvu, struct msg_req *req,
+				    struct msg_rsp *rsp)
+{
+	int blkaddr;
+
+	/* NIX_AF_RX_SW_SYNC is global per NIX block; nix_rx_sync() serializes
+	 * access under rvu->rsrc_lock across mbox and teardown paths.
+	 */
+	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, req->hdr.pcifunc);
+	if (blkaddr < 0)
+		return NIX_AF_ERR_AF_LF_INVALID;
+
+	nix_rx_sync(rvu, blkaddr);
+	return 0;
+}
+
 static struct nix_mcast_grp_elem *rvu_nix_mcast_find_grp_elem(struct nix_mcast_grp *mcast_grp,
 							      u32 mcast_grp_idx)
 {
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH net v5] tipc: serialize udp bearer replicast list updates
From: kernel test robot @ 2026-07-15  4:00 UTC (permalink / raw)
  To: Weiming Shi, Jon Maloy, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman
  Cc: oe-kbuild-all, netdev, tipc-discussion, linux-kernel, Tung Nguyen,
	xmei5, Weiming Shi
In-Reply-To: <20260714192140.1810202-1-bestswngs@gmail.com>

Hi Weiming,

kernel test robot noticed the following build warnings:

[auto build test WARNING on net/main]

url:    https://github.com/intel-lab-lkp/linux/commits/Weiming-Shi/tipc-serialize-udp-bearer-replicast-list-updates/20260715-033047
base:   net/main
patch link:    https://lore.kernel.org/r/20260714192140.1810202-1-bestswngs%40gmail.com
patch subject: [PATCH net v5] tipc: serialize udp bearer replicast list updates
config: x86_64-rhel-9.4-bpf (https://download.01.org/0day-ci/archive/20260715/202607150523.48dOIqUE-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260715/202607150523.48dOIqUE-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202607150523.48dOIqUE-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> Warning: net/tipc/udp_media.c:106 struct member 'disabled' not described in 'udp_bearer'
>> Warning: net/tipc/udp_media.c:106 struct member 'disabled' not described in 'udp_bearer'

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* [PATCH net] e1000e: Fix out-of-bounds MMIO access by validating BAR0 size
From: Pu Lehui @ 2026-07-15  3:58 UTC (permalink / raw)
  To: Tony Nguyen, Przemek Kitszel, Andrew Lunn, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni
  Cc: netdev, linux-kernel

From: Pu Lehui <pulehui@huawei.com>

Syzkaller reported a kernel panic caused by an out-of-bounds MMIO
access in the e1000e driver.

[   82.868719][  T404] e1000e 0000:00:02.0: The NVM Checksum Is Not Valid
[   82.872328][  T404] Unable to handle kernel paging request at virtual address ffff80008894e090
[   83.085218][  T404] CPU: 2 UID: 0 PID: 404 Comm: bash Not tainted 7.2.0-rc2-g3f1f75536668 #1 PREEMPTLAZY
[   83.129013][  T404] pc : e1000_get_cfg_done_82571+0x70/0x158
[   83.140092][  T404] lr : e1000_get_cfg_done_82571+0x68/0x158
[   83.151196][  T404] sp : ffff80008ac37410
[   83.158922][  T404] x29: ffff80008ac37410 x28: ffff0000cd6a11b8 x27: ffff0000c58190d0
[   83.173919][  T404] x26: ffff0000cd6a11b8 x25: ffff0000cd6a0bc0 x24: ffff0000cd6a0000
[   83.189417][  T404] x23: 0000000000001010 x22: ffff0000cd6a11c0 x21: ffff0000cd6a11b8
[   83.205195][  T404] x20: 0000000000000064 x19: ffff80008894e090 x18: 0000000000000000
[   83.220545][  T404] x17: ffff800081c1a3f4 x16: ffff800081c19c10 x15: ffff800081e86510
[   83.235764][  T404] x14: 0000000000000001 x13: 0000000000000001 x12: ffff60001bc8a8b3
[   83.251301][  T404] x11: 1fffe0001bc8a8b2 x10: ffff60001bc8a8b2 x9 : ffff800081eae25c
[   83.266705][  T404] x8 : 00009fffe437574e x7 : ffff0000de454593 x6 : 0000000000000001
[   83.281919][  T404] x5 : ffff0000cf2b9640 x4 : 0000000000000000 x3 : dfff800000000000
[   83.297317][  T404] x2 : 0000000000000007 x1 : ffff0000cd6a11c0 x0 : 0000000000000000
[   83.312601][  T404] Call trace:
[   83.318662][  T404]  e1000_get_cfg_done_82571+0x70/0x158 (P)
[   83.329748][  T404]  e1000e_phy_hw_reset_generic+0x17c/0x1a8
[   83.341541][  T404]  e1000_probe+0xbd8/0x1988
[   83.350334][  T404]  local_pci_probe+0x84/0x130

Repetition steps:
1. Find PCI device which BAR0 size <= 4K. If it's:
   Device Addr: 0000:00:02.0   BAR0 SIZE: 4K
   Vendor/Device ID: 0x1af4 0x1004
2. Unbind the above PCI device
   echo '0000:00:02.0' > /sys/bus/pci/devices/0000:00:02.0/driver/unbind
3. Set the above device to e1000e new_id
   echo '1af4 1004' > /sys/bus/pci/drivers/e1000e/new_id

During e1000_probe(), the driver maps the device's BAR0 memory region.
If the device has a 4K BAR0, ioremap() maps only 4K of space. Later in
the probe process, when the NVM checksum validation fails, the driver
attempts to perform a hardware reset and falls back to the err_eeprom
cleanup path.

This cleanup path will trigger an OOB access kernel panic:
e1000_phy_hw_reset
  e1000e_phy_hw_reset_generic
    e1000_get_cfg_done_82571
      er32(EEMNGCTL)
        readl(hw->hw_addr + EEMNGCTL); <-- EEMNGCTL(0x1010) > 4K, OOB access

Fix this by ensuring the MMIO length (pci_resource_len(pdev, 0)) is at
least 64K (0x10000) before proceeding with ioremap(). The 64K minimum
safely covers the maximum register offset accessed by the e1000e driver.

Fixes: bc7f75fa9788 ("[E1000E]: New pci-express e1000 driver (currently for ICH9 devices only)")
Signed-off-by: Pu Lehui <pulehui@huawei.com>
---
 drivers/net/ethernet/intel/e1000e/netdev.c | 5 +++++
 drivers/net/ethernet/intel/e1000e/regs.h   | 3 +++
 2 files changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 844f31ab37ad..46e58e926f7b 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -7450,6 +7450,11 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	mmio_len = pci_resource_len(pdev, 0);
 
 	err = -EIO;
+	if (mmio_len < E1000_MMIO_LEN_MIN) {
+		dev_err(&pdev->dev, "MMIO len is too small\n");
+		goto err_ioremap;
+	}
+
 	adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
 	if (!adapter->hw.hw_addr)
 		goto err_ioremap;
diff --git a/drivers/net/ethernet/intel/e1000e/regs.h b/drivers/net/ethernet/intel/e1000e/regs.h
index 6c0cd8cab3ef..b63adeea1563 100644
--- a/drivers/net/ethernet/intel/e1000e/regs.h
+++ b/drivers/net/ethernet/intel/e1000e/regs.h
@@ -242,4 +242,7 @@
 /* PHY registers */
 #define I82579_DFT_CTRL	PHY_REG(769, 20)
 
+/* Minimum MMIO (BAR0) len, the largest offset is lower than 64K */
+#define E1000_MMIO_LEN_MIN	0x10000
+
 #endif
-- 
2.34.1


^ permalink raw reply related

* [PATCH] sctp: diag: fix uninitialized stack leak via INET_DIAG_LOCALS/PEERS
From: MingXuan @ 2026-07-15  3:35 UTC (permalink / raw)
  To: Marcelo Ricardo Leitner, Xin Long
  Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, linux-sctp, netdev, linux-kernel, MingXuan, stable

inet_diag_msg_sctpladdrs_fill() copies sizeof(union sctp_addr) (28 bytes,
the size of sockaddr_in6) from each sctp_sockaddr_entry.a into the netlink
INET_DIAG_LOCALS attribute and then only zeroes the bytes from offset 28 to
sizeof(sockaddr_storage).  The same pattern is used by
inet_diag_msg_sctpaddrs_fill() for INET_DIAG_PEERS.

The IPv4 address-filling helpers sctp_v4_from_addr_param() and
sctp_v4_from_skb() only initialize the sockaddr_in portion (16 bytes) of the
union sctp_addr; the trailing 12 bytes (offset 16..27, the sockaddr_in6-only
region) are left uninitialized.  Those bytes are propagated verbatim through
sctp_add_bind_addr() (which copies sizeof(union sctp_addr)=28 bytes) and then
copied straight to userspace by the diag fill functions, leaking 12 bytes of
kernel stack residue per local/peer address to any process that can issue a
SOCK_DIAG_BY_FAMILY dump for IPPROTO_SCTP.

Fix it by computing the actually-initialized length of the address from its
sa_family (struct sockaddr_in for AF_INET, the whole union otherwise) and
copying only that many bytes into an already-zeroed sockaddr_storage slot, so
the uninitialized tail is never read and never reaches userspace.

Fixes: 8f840e47f190cbe61a96945c13e9551048d42cef ("sctp: add the sctp_diag.c file")
Cc: stable@vger.kernel.org
Signed-off-by: MingXuan <omeux327@gmail.com>
---
 net/sctp/diag.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/net/sctp/diag.c b/net/sctp/diag.c
index d758f5c3e06e..12557e924cc2 100644
--- a/net/sctp/diag.c
+++ b/net/sctp/diag.c
@@ -85,8 +85,12 @@ static int inet_diag_msg_sctpladdrs_fill(struct sk_buff *skb,
 	info = nla_data(attr);
 	rcu_read_lock();
 	list_for_each_entry_rcu(laddr, address_list, list) {
-		memcpy(info, &laddr->a, sizeof(laddr->a));
-		memset(info + sizeof(laddr->a), 0, addrlen - sizeof(laddr->a));
+		size_t addr_len = laddr->a.sa.sa_family == AF_INET ?
+				  sizeof(struct sockaddr_in) :
+				  sizeof(struct sockaddr_in6);
+
+		memset(info, 0, addrlen);
+		memcpy(info, &laddr->a, addr_len);
 		info += addrlen;
 
 		if (!--addrcnt)
@@ -113,9 +117,12 @@ static int inet_diag_msg_sctpaddrs_fill(struct sk_buff *skb,
 	info = nla_data(attr);
 	list_for_each_entry(from, &asoc->peer.transport_addr_list,
 			    transports) {
-		memcpy(info, &from->ipaddr, sizeof(from->ipaddr));
-		memset(info + sizeof(from->ipaddr), 0,
-		       addrlen - sizeof(from->ipaddr));
+		size_t addr_len = from->ipaddr.sa.sa_family == AF_INET ?
+				  sizeof(struct sockaddr_in) :
+				  sizeof(struct sockaddr_in6);
+
+		memset(info, 0, addrlen);
+		memcpy(info, &from->ipaddr, addr_len);
 		info += addrlen;
 	}
 
-- 
2.50.1 (Apple Git-155)


^ permalink raw reply related

* [PATCH net-next 7/7] net: mana: add dynamic HWC queue depth with reinit path
From: Long Li @ 2026-07-15  3:29 UTC (permalink / raw)
  To: Long Li, Konstantin Taranov, Jakub Kicinski, David S . Miller,
	Paolo Abeni, Eric Dumazet, Andrew Lunn, Jason Gunthorpe,
	Leon Romanovsky, Haiyang Zhang, K . Y . Srinivasan, Wei Liu,
	Dexuan Cui, shradhagupta, Simon Horman
  Cc: netdev, linux-rdma, linux-hyperv, linux-kernel
In-Reply-To: <20260715032942.3945317-1-longli@microsoft.com>

The HWC is first established at a bootstrap queue depth of 1.  Query the
device's maximum supported depth and, if larger, tear down and rebuild
the HWC queues at that depth before re-establishing the channel, so more
management commands can be in flight.  Advertise
GDMA_DRV_CAP_FLAG_1_DYN_HWC_QUEUE_DEPTH so the firmware enables this only
when the driver supports it.

mana_hwc_destroy_queues() tears down the CQ first, which deregisters the
EQ IRQ (mana_gd_deregister_irq() + synchronize_rcu()) so no interrupt
handler can touch the queues, then the TXQ, RXQ and inflight resources.

Validate the device-reported dimensions before they size DMA
allocations: enforce the request/response header minimums, ensure
q_depth * max_msg_size plus alignment fits in u32, and cap CQ depth to
U16_MAX/2.  Carry the depth as u32 -- the device field is 24-bit, so
truncating to u16 on receipt could wrap a large value to a small depth
and silently pass these checks.

If reinit fails, fall back to the bootstrap-depth channel when its
teardown succeeded; if teardown also failed, hardware mappings may still
be active, so abort channel creation instead.

Signed-off-by: Long Li <longli@microsoft.com>
---
 .../net/ethernet/microsoft/mana/hw_channel.c  | 223 +++++++++++++++++-
 include/net/mana/gdma.h                       |   4 +
 include/net/mana/hw_channel.h                 |   2 +-
 3 files changed, 218 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.c b/drivers/net/ethernet/microsoft/mana/hw_channel.c
index 9ba4e75a4dd3..3d0f17de3442 100644
--- a/drivers/net/ethernet/microsoft/mana/hw_channel.c
+++ b/drivers/net/ethernet/microsoft/mana/hw_channel.c
@@ -214,7 +214,12 @@ static void mana_hwc_init_event_handler(void *ctx, struct gdma_queue *q_self,
 			break;
 
 		case HWC_INIT_DATA_QUEUE_DEPTH:
-			hwc->hwc_init_q_depth_max = (u16)val;
+			/* HWC_INIT_DATA_QUEUE_DEPTH is a 24-bit field.  Keep
+			 * the full device-reported value here; it is clamped
+			 * and validated in mana_hwc_create_channel() rather
+			 * than silently truncated to u16.
+			 */
+			hwc->hwc_init_q_depth_max = val;
 			break;
 
 		case HWC_INIT_DATA_MAX_REQUEST:
@@ -784,7 +789,7 @@ static int mana_hwc_test_channel(struct hw_channel_context *hwc, u16 q_depth,
 	return err;
 }
 
-static int mana_hwc_establish_channel(struct gdma_context *gc, u16 *q_depth,
+static int mana_hwc_establish_channel(struct gdma_context *gc, u32 *q_depth,
 				      u32 *max_req_msg_size,
 				      u32 *max_resp_msg_size)
 {
@@ -862,6 +867,12 @@ static int mana_hwc_init_queues(struct hw_channel_context *hwc, u16 q_depth,
 {
 	int err;
 
+	/* CQ depth is q_depth * 2 (SQ + RQ) passed as u16 to create_cq.
+	 * Cap to prevent u16 truncation.
+	 */
+	if (q_depth > U16_MAX / 2)
+		q_depth = U16_MAX / 2;
+
 	err = mana_hwc_init_inflight_msg(hwc, q_depth);
 	if (err)
 		return err;
@@ -902,13 +913,62 @@ static int mana_hwc_init_queues(struct hw_channel_context *hwc, u16 q_depth,
 	return err;
 }
 
+/* Tear down all HWC queues and free associated resources.  Used on
+ * the reinit-with-higher-queue-depth path and reinit fallback.
+ *
+ * PRECONDITION: must be called only during channel bring-up in
+ * mana_hwc_create_channel(), before the channel is published to
+ * senders.  There the setup thread is effectively single-threaded
+ * (serialized against teardown by the PCI/PM device_lock or, on the
+ * service path, GC_IN_SERVICE, with the data path not yet probed),
+ * channel_up is still false, caller_ctx is not yet allocated, and
+ * active_senders is 0 — so no concurrent request/response user can
+ * touch these queues.  That is why this skips the hwc_lock-protected
+ * driver_data clear + active_senders drain that
+ * mana_hwc_destroy_channel() needs for the runtime teardown race;
+ * only the CQ-first ordering below (to fence off a pending interrupt)
+ * is required.  Calling this on a live, published channel would be a
+ * use-after-free.
+ */
+static void mana_hwc_destroy_queues(struct hw_channel_context *hwc)
+{
+	struct gdma_context *gc = hwc->gdma_dev->gdma_context;
+
+	/* Destroy CQ first to deregister the EQ from the interrupt
+	 * handler list before freeing caller_ctx, TXQ, or RXQ memory.
+	 * A pending interrupt handler could still reach handle_resp()
+	 * which dereferences caller_ctx.
+	 */
+	if (hwc->cq) {
+		mana_hwc_destroy_cq(gc, hwc->cq);
+		hwc->cq = NULL;
+	}
+
+	kfree(hwc->caller_ctx);
+	hwc->caller_ctx = NULL;
+
+	if (hwc->txq) {
+		mana_hwc_destroy_wq(hwc, hwc->txq);
+		hwc->txq = NULL;
+	}
+
+	if (hwc->rxq) {
+		mana_hwc_destroy_wq(hwc, hwc->rxq);
+		hwc->rxq = NULL;
+	}
+
+	mana_gd_free_res_map(&hwc->inflight_msg_res);
+	hwc->num_inflight_msg = 0;
+}
+
 int mana_hwc_create_channel(struct gdma_context *gc)
 {
 	u32 max_req_msg_size, max_resp_msg_size;
 	struct gdma_dev *gd = &gc->hwc;
 	struct hw_channel_context *hwc;
+	struct gdma_queue __rcu **old_cq_table;
 	unsigned long flags;
-	u16 q_depth_max;
+	u32 q_depth_max;
 	int err;
 
 	hwc = kzalloc_obj(*hwc);
@@ -956,8 +1016,130 @@ int mana_hwc_create_channel(struct gdma_context *gc)
 		goto out;
 	}
 
+	/* The channel was bootstrapped at a minimal queue depth.  If the
+	 * device reports a higher maximum, tear down and rebuild with
+	 * the larger depth so more HWC commands can be in flight.
+	 */
+	if (q_depth_max > HW_CHANNEL_VF_BOOTSTRAP_QUEUE_DEPTH) {
+		/* q_depth_max now carries the full device-reported value
+		 * (HWC_INIT_DATA_QUEUE_DEPTH is 24-bit).  Clamp it to the
+		 * depth the rest of the driver supports — create_cq() takes
+		 * q_depth * 2 as a u16 — before the overflow check below, so
+		 * an over-large but otherwise-valid depth is reduced to the
+		 * maximum instead of wrapping or being rejected.
+		 */
+		if (q_depth_max > U16_MAX / 2)
+			q_depth_max = U16_MAX / 2;
+
+		/* Sanity-check device-reported values before using them
+		 * to size DMA allocations.  Enforce protocol minimums
+		 * for message sizes and check that q_depth * max_msg_size
+		 * plus alignment headroom fits in u32 (for
+		 * mana_hwc_alloc_dma_buf's MANA_PAGE_ALIGN).
+		 */
+		if (!max_req_msg_size || !max_resp_msg_size ||
+		    max_req_msg_size < sizeof(struct gdma_req_hdr) ||
+		    max_resp_msg_size < sizeof(struct gdma_resp_hdr) ||
+		    (u64)q_depth_max * max_req_msg_size >
+			U32_MAX - MANA_PAGE_SIZE ||
+		    (u64)q_depth_max * max_resp_msg_size >
+			U32_MAX - MANA_PAGE_SIZE) {
+			dev_err(hwc->dev,
+				"HWC: invalid dims q=%u req=%u resp=%u\n",
+				q_depth_max, max_req_msg_size,
+				max_resp_msg_size);
+			q_depth_max = HW_CHANNEL_VF_BOOTSTRAP_QUEUE_DEPTH;
+			goto skip_reinit;
+		}
+
+		err = mana_smc_teardown_hwc(&gc->shm_channel, false);
+		if (err) {
+			/* Keep using the bootstrap-depth channel. */
+			dev_err(hwc->dev,
+				"Failed to teardown HWC for reinit: %d\n",
+				err);
+			q_depth_max = HW_CHANNEL_VF_BOOTSTRAP_QUEUE_DEPTH;
+			goto skip_reinit;
+		}
+
+		hwc->setup_active = false;
+
+		/* Destroy queues first — mana_gd_destroy_cq inside
+		 * unpublishes the CQ from cq_table via
+		 * rcu_assign_pointer(NULL) + synchronize_rcu.
+		 * Must happen while cq_table is still valid.
+		 */
+		mana_hwc_destroy_queues(hwc);
+
+		old_cq_table = rcu_replace_pointer(gc->cq_table, NULL, true);
+		synchronize_rcu();
+		vfree(old_cq_table);
+
+		err = mana_hwc_init_queues(hwc, q_depth_max,
+					   max_req_msg_size,
+					   max_resp_msg_size);
+		if (err) {
+			dev_err(hwc->dev, "Failed to reinit HWC: %d\n", err);
+			goto reinit_fallback;
+		}
+
+		err = mana_hwc_establish_channel(gc, &q_depth_max,
+						 &max_req_msg_size,
+						 &max_resp_msg_size);
+		if (err) {
+			dev_err(hwc->dev, "Failed to re-establish HWC: %d\n",
+				err);
+			/* establish_channel does internal teardown on
+			 * failure.  If teardown succeeded (setup_active
+			 * cleared), MST entries are invalidated and we
+			 * can try the bootstrap fallback.  If teardown
+			 * also failed (setup_active still set), hardware
+			 * mappings may still be active — skip fallback.
+			 */
+			if (hwc->setup_active)
+				goto out;
+			goto reinit_fallback;
+		}
+	}
+
+	goto skip_reinit;
+
+reinit_fallback:
+	/* Restore bootstrap-depth channel so the device remains functional.
+	 * Free cq_table if it was allocated by a partially successful
+	 * establish attempt.
+	 */
+	dev_warn(hwc->dev, "HWC reinit failed, falling back to bootstrap depth\n");
+
+	mana_hwc_destroy_queues(hwc);
+
+	old_cq_table = rcu_replace_pointer(gc->cq_table, NULL, true);
+	synchronize_rcu();
+	vfree(old_cq_table);
+
+	err = mana_hwc_init_queues(hwc, HW_CHANNEL_VF_BOOTSTRAP_QUEUE_DEPTH,
+				   HW_CHANNEL_MAX_REQUEST_SIZE,
+				   HW_CHANNEL_MAX_RESPONSE_SIZE);
+	if (err) {
+		dev_err(hwc->dev, "Failed to restore bootstrap HWC: %d\n", err);
+		goto out;
+	}
+
+	err = mana_hwc_establish_channel(gc, &q_depth_max, &max_req_msg_size,
+					 &max_resp_msg_size);
+	if (err) {
+		dev_err(hwc->dev, "Failed to re-establish bootstrap HWC: %d\n",
+			err);
+		goto out;
+	}
+
+skip_reinit:
+
+	/* No RCU needed: still in mana_hwc_create_channel, the
+	 * pointer has not been published to concurrent senders yet.
+	 */
 	err = mana_hwc_test_channel(gc->hwc.driver_data,
-				    HW_CHANNEL_VF_BOOTSTRAP_QUEUE_DEPTH,
+				    hwc->num_inflight_msg,
 				    max_req_msg_size, max_resp_msg_size);
 	if (err) {
 		dev_err(hwc->dev, "Failed to test HWC: %d\n", err);
@@ -972,6 +1154,10 @@ int mana_hwc_create_channel(struct gdma_context *gc)
 
 void mana_hwc_destroy_channel(struct gdma_context *gc)
 {
+	/* This is the only destroy entry point.  driver_data is read
+	 * plainly here (teardown is serialised against other teardown);
+	 * it is cleared under hwc_lock below before hwc is freed.
+	 */
 	struct hw_channel_context *hwc = gc->hwc.driver_data;
 	struct gdma_queue __rcu **old_cq_table;
 	unsigned long flags;
@@ -1011,10 +1197,21 @@ void mana_hwc_destroy_channel(struct gdma_context *gc)
 	 * on the init EQE arriving.
 	 *
 	 * The return value is intentionally not checked.  This is the
-	 * terminal cleanup path — resources must be freed regardless.
-	 * If teardown fails, hardware may still have active MST entries,
-	 * but the EQ deregistration and IOMMU unmapping below prevent
-	 * stale hardware accesses from reaching kernel memory.
+	 * terminal cleanup path (device removal, suspend, or init
+	 * failure) — resources must be freed regardless.  If teardown
+	 * fails, hardware may still have active MST entries, but:
+	 *
+	 *  - Interrupts: mana_hwc_destroy_cq() below calls
+	 *    mana_gd_deregister_irq() which removes the HWC EQ from
+	 *    the interrupt dispatch list via list_del_rcu() +
+	 *    synchronize_rcu().  After that, no interrupt handler can
+	 *    invoke handle_resp() or access CQ/RQ buffers — even if
+	 *    the IRQ is shared with data path queues.
+	 *
+	 *  - DMA: mana_hwc_destroy_wq() frees DMA buffers via
+	 *    dma_free_coherent() which unmaps the IOVA from the
+	 *    IOMMU.  Any stale hardware DMA to the old address
+	 *    faults at the IOMMU, not in kernel memory.
 	 */
 	if (hwc->setup_active) {
 		int td_err = mana_smc_teardown_hwc(&gc->shm_channel, false);
@@ -1042,6 +1239,9 @@ void mana_hwc_destroy_channel(struct gdma_context *gc)
 				 * them (unsafe).
 				 *
 				 * but leak all DMA buffers to prevent corruption.
+				 * Also leak the EQ IRQ registration since freeing
+				 * it safely requires accessing queue structures we're
+				 * leaving allocated.
 				 */
 
 				dev_warn(gc->dev,
@@ -1061,8 +1261,11 @@ void mana_hwc_destroy_channel(struct gdma_context *gc)
 	}
 
 	/* After SMC teardown, no more hardware events should arrive.
-	 * Force-complete any remaining in-flight senders so they can
-	 * exit and drop their refs.
+	 * If teardown failed, handle_resp() may still race with this
+	 * loop via a late interrupt — this is safe because the per-slot
+	 * refcount model tolerates a concurrent complete() and both
+	 * paths (handle_resp and this loop) will correctly drop their
+	 * respective refs without double-releasing the slot.
 	 */
 	if (hwc->caller_ctx) {
 		struct hwc_caller_ctx *ctx;
diff --git a/include/net/mana/gdma.h b/include/net/mana/gdma.h
index 01e845237b6a..a4eac6f7c366 100644
--- a/include/net/mana/gdma.h
+++ b/include/net/mana/gdma.h
@@ -708,6 +708,9 @@ enum {
 /* Driver supports dynamic interrupt moderation - DIM */
 #define GDMA_DRV_CAP_FLAG_1_DYN_INTERRUPT_MODERATION BIT(28)
 
+/* Driver supports dynamic queue depth for HWC */
+#define GDMA_DRV_CAP_FLAG_1_DYN_HWC_QUEUE_DEPTH BIT(29)
+
 #define GDMA_DRV_CAP_FLAGS1 \
 	(GDMA_DRV_CAP_FLAG_1_EQ_SHARING_MULTI_VPORT | \
 	 GDMA_DRV_CAP_FLAG_1_NAPI_WKDONE_FIX | \
@@ -723,6 +726,7 @@ enum {
 	 GDMA_DRV_CAP_FLAG_1_PROBE_RECOVERY | \
 	 GDMA_DRV_CAP_FLAG_1_HANDLE_STALL_SQ_RECOVERY | \
 	 GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECOVERY | \
+	 GDMA_DRV_CAP_FLAG_1_DYN_HWC_QUEUE_DEPTH | \
 	 GDMA_DRV_CAP_FLAG_1_EQ_MSI_UNSHARE_MULTI_VPORT | \
 	 GDMA_DRV_CAP_FLAG_1_DYN_INTERRUPT_MODERATION)
 
diff --git a/include/net/mana/hw_channel.h b/include/net/mana/hw_channel.h
index bc62d1ce7bd4..fb9725e30c8c 100644
--- a/include/net/mana/hw_channel.h
+++ b/include/net/mana/hw_channel.h
@@ -197,7 +197,7 @@ struct hw_channel_context {
 	u32 max_req_msg_size;
 	u32 max_resp_msg_size;
 
-	u16 hwc_init_q_depth_max;
+	u32 hwc_init_q_depth_max;
 	u32 hwc_init_max_req_msg_size;
 	u32 hwc_init_max_resp_msg_size;
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH net-next 6/7] net: mana: support concurrent HWC requests with proper synchronization
From: Long Li @ 2026-07-15  3:29 UTC (permalink / raw)
  To: Long Li, Konstantin Taranov, Jakub Kicinski, David S . Miller,
	Paolo Abeni, Eric Dumazet, Andrew Lunn, Jason Gunthorpe,
	Leon Romanovsky, Haiyang Zhang, K . Y . Srinivasan, Wei Liu,
	Dexuan Cui, shradhagupta, Simon Horman
  Cc: netdev, linux-rdma, linux-hyperv, linux-kernel
In-Reply-To: <20260715032942.3945317-1-longli@microsoft.com>

The HWC serialized all management commands behind a depth-1 semaphore, a
bottleneck when many commands must be issued concurrently.  Allowing
multiple in-flight requests exposes several shared-state races that this
patch addresses together.

  - Replace the semaphore with a waitqueue + bitmap scheme so senders
    acquire message slots in parallel and sleep only when all slots are
    busy.

  - A response is delivered by handle_resp() in CQ interrupt context
    while the issuing sender may concurrently time out and return; both
    touch the same caller_ctx slot (output_buf, output_buflen, error):

      CPU A (sender timeout)            CPU B (handle_resp, IRQ)
      ------------------------------    ------------------------------
      read/clear output_buf             write response into output_buf,
                                        complete the slot

    Add a per-slot spinlock to make these mutually exclusive, a per-slot
    refcount so the last of {sender, handle_resp} releases the bitmap
    slot (no double-release, no stuck slot), and an embedded completion
    the sender waits on.  The sender always NULLs output_buf after
    waking, so a late handle_resp() skips the copy.

  - Add a per-queue lock to hwc_wq; mana_gd_post_and_ring() is not safe
    to call concurrently on the same queue.

  - Add channel_up (cleared under the bitmap lock in destroy_channel) and
    hwc_timed_out flags so new slot acquisitions are rejected during
    teardown and after a timeout.

  - destroy_channel() must not free the HWC while senders are still in
    flight.  Track senders with an atomic refcount; destroy_channel()
    force-completes the in-flight slots (-ENODEV) and then waits for the
    count to reach zero before freeing.  The drain waitqueue lives on
    gdma_context, not hwc, so the final wake_up() after the last
    atomic_dec does not dereference freed hwc memory.

  - The sender looks up the channel via gc->hwc.driver_data, which
    destroy_channel() clears and then frees.  Without serialization the
    lookup and the reference can straddle the free:

      CPU A (mana_gd_send_request)      CPU B (destroy_channel)
      ------------------------------    ------------------------------
      hwc = gc->hwc.driver_data;  // ok
                                        driver_data = NULL;
                                        wait active_senders == 0;  // 0!
                                        kfree(hwc);
      atomic_inc(&hwc->active_senders); // use-after-free

    Guard driver_data with a new gc->hwc_lock spinlock, taken by the
    readers (mana_gd_send_request, mana_need_log, mana_serv_reset) and by
    the publish/clear, so "load the pointer + take a sender reference" is
    atomic against the clear.  After the clear a sender either already
    holds a reference (and is waited for) or observes NULL and returns
    -ENODEV.  These are all control-plane paths (HWC commands sleep,
    reset runs on a workqueue), so a plain spinlock -- not RCU -- is
    sufficient.

This adds the concurrency infrastructure at the bootstrap queue depth of
1; the next patch raises it to the device-reported maximum.

Signed-off-by: Long Li <longli@microsoft.com>
---
 .../net/ethernet/microsoft/mana/gdma_main.c   |  53 ++-
 .../net/ethernet/microsoft/mana/hw_channel.c  | 314 +++++++++++++++---
 include/net/mana/gdma.h                       |  15 +
 include/net/mana/hw_channel.h                 |  29 +-
 4 files changed, 365 insertions(+), 46 deletions(-)

diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c
index c52ef566dc0c..d44a3e2c4add 100644
--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c
+++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c
@@ -161,6 +161,8 @@ static int mana_gd_init_registers(struct pci_dev *pdev)
 bool mana_need_log(struct gdma_context *gc, int err)
 {
 	struct hw_channel_context *hwc;
+	bool need_log = true;
+	unsigned long flags;
 
 	if (err != -ETIMEDOUT)
 		return true;
@@ -168,11 +170,13 @@ bool mana_need_log(struct gdma_context *gc, int err)
 	if (!gc)
 		return true;
 
+	spin_lock_irqsave(&gc->hwc_lock, flags);
 	hwc = gc->hwc.driver_data;
 	if (hwc && hwc->hwc_timeout == 0)
-		return false;
+		need_log = false;
+	spin_unlock_irqrestore(&gc->hwc_lock, flags);
 
-	return true;
+	return need_log;
 }
 
 static int mana_gd_query_max_resources(struct pci_dev *pdev)
@@ -367,9 +371,25 @@ static int mana_gd_detect_devices(struct pci_dev *pdev)
 int mana_gd_send_request(struct gdma_context *gc, u32 req_len, const void *req,
 			 u32 resp_len, void *resp)
 {
-	struct hw_channel_context *hwc = gc->hwc.driver_data;
+	struct hw_channel_context *hwc;
+	unsigned long flags;
+	int err;
+
+	spin_lock_irqsave(&gc->hwc_lock, flags);
+	hwc = gc->hwc.driver_data;
+	if (!hwc) {
+		spin_unlock_irqrestore(&gc->hwc_lock, flags);
+		return -ENODEV;
+	}
+	atomic_inc(&hwc->active_senders);
+	spin_unlock_irqrestore(&gc->hwc_lock, flags);
+
+	err = mana_hwc_send_request(hwc, req_len, req, resp_len, resp);
 
-	return mana_hwc_send_request(hwc, req_len, req, resp_len, resp);
+	if (atomic_dec_and_test(&hwc->active_senders))
+		wake_up(&gc->hwc_drain_waitq);
+
+	return err;
 }
 EXPORT_SYMBOL_NS(mana_gd_send_request, "NET_MANA");
 
@@ -622,6 +642,7 @@ static void mana_serv_reset(struct pci_dev *pdev)
 {
 	struct gdma_context *gc = pci_get_drvdata(pdev);
 	struct hw_channel_context *hwc;
+	unsigned long flags;
 	int ret;
 
 	if (!gc) {
@@ -631,14 +652,17 @@ static void mana_serv_reset(struct pci_dev *pdev)
 		return;
 	}
 
+	spin_lock_irqsave(&gc->hwc_lock, flags);
 	hwc = gc->hwc.driver_data;
 	if (!hwc) {
+		spin_unlock_irqrestore(&gc->hwc_lock, flags);
 		dev_err(&pdev->dev, "MANA service: no HWC\n");
 		goto out;
 	}
 
 	/* HWC is not responding in this case, so don't wait */
 	hwc->hwc_timeout = 0;
+	spin_unlock_irqrestore(&gc->hwc_lock, flags);
 
 	dev_info(&pdev->dev, "MANA reset cycle start\n");
 
@@ -1200,6 +1224,16 @@ static int mana_gd_create_dma_region(struct gdma_dev *gd,
 	if (!MANA_PAGE_ALIGNED(gmi->virt_addr))
 		return -EINVAL;
 
+	/* No RCU needed: this runs only on the data-path queue-creation
+	 * path (mana_gd_create_mana_eq/mana_gd_create_mana_wq_cq, called
+	 * by mana_en under RTNL and by mana_ib RDMA verbs, or during
+	 * init).  Every teardown path — mana_gd_remove, mana_gd_suspend,
+	 * and the HWC reset/service path (which goes through
+	 * mana_gd_suspend) — drains those consumers via mana_rdma_remove()
+	 * + mana_remove() before mana_hwc_destroy_channel() clears
+	 * gc->hwc.driver_data, so no concurrent destroy can race with
+	 * this dereference.
+	 */
 	hwc = gc->hwc.driver_data;
 	req_msg_size = struct_size(req, page_addr_list, num_page);
 	if (req_msg_size > hwc->max_req_msg_size)
@@ -1389,7 +1423,17 @@ int mana_gd_verify_vf_version(struct pci_dev *pdev)
 	struct hw_channel_context *hwc;
 	int err;
 
+	/* No RCU needed: this runs only inside mana_gd_setup, on the
+	 * probe and resume paths.  The PCI/PM core holds device_lock
+	 * across .probe/.resume and .remove/.suspend, so setup cannot
+	 * overlap teardown of the same device.  The HWC reset/service
+	 * path is additionally serialized by GC_IN_SERVICE and runs
+	 * suspend (destroy) then resume (this) sequentially in one work
+	 * item.  driver_data was just set by mana_hwc_create_channel
+	 * earlier in this same setup call, so it is live here.
+	 */
 	hwc = gc->hwc.driver_data;
+
 	mana_gd_init_req_hdr(&req.hdr, GDMA_VERIFY_VF_DRIVER_VERSION,
 			     sizeof(req), sizeof(resp));
 
@@ -2379,6 +2423,7 @@ static int mana_gd_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	mutex_init(&gc->eq_test_event_mutex);
 	mutex_init(&gc->gic_mutex);
+	spin_lock_init(&gc->hwc_lock);
 	pci_set_drvdata(pdev, gc);
 	gc->bar0_pa = pci_resource_start(pdev, 0);
 	gc->bar0_size = pci_resource_len(pdev, 0);
diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.c b/drivers/net/ethernet/microsoft/mana/hw_channel.c
index b26c2122ebf5..9ba4e75a4dd3 100644
--- a/drivers/net/ethernet/microsoft/mana/hw_channel.c
+++ b/drivers/net/ethernet/microsoft/mana/hw_channel.c
@@ -7,25 +7,52 @@
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
 
+/* Acquire a free message slot from the inflight bitmap.  Returns
+ * -ENODEV if the channel is torn down, or -ETIMEDOUT if a prior HWC
+ * command has timed out (preserving the error code callers expect).
+ */
 static int mana_hwc_get_msg_index(struct hw_channel_context *hwc, u16 *msg_id)
 {
 	struct gdma_resource *r = &hwc->inflight_msg_res;
 	unsigned long flags;
 	u32 index;
 
-	down(&hwc->sema);
+	for (;;) {
+		spin_lock_irqsave(&r->lock, flags);
 
-	spin_lock_irqsave(&r->lock, flags);
+		if (!hwc->channel_up || hwc->hwc_timed_out) {
+			spin_unlock_irqrestore(&r->lock, flags);
+			return hwc->channel_up ? -ETIMEDOUT : -ENODEV;
+		}
 
-	index = find_first_zero_bit(hwc->inflight_msg_res.map,
-				    hwc->inflight_msg_res.size);
+		index = find_first_zero_bit(r->map, r->size);
+		if (index < r->size) {
+			struct hwc_caller_ctx *ctx;
+
+			bitmap_set(r->map, index, 1);
+			ctx = &hwc->caller_ctx[index];
+			reinit_completion(&ctx->comp_event);
+			refcount_set(&ctx->refcnt, 1);
+			ctx->msg_id = index;
+			ctx->error = -EINPROGRESS;
+			spin_unlock_irqrestore(&r->lock, flags);
+			break;
+		}
+		spin_unlock_irqrestore(&r->lock, flags);
 
-	bitmap_set(hwc->inflight_msg_res.map, index, 1);
+		wait_event(hwc->msg_waitq,
+			   !hwc->channel_up ||
+			   hwc->hwc_timed_out ||
+			   !bitmap_full(r->map, r->size));
 
-	spin_unlock_irqrestore(&r->lock, flags);
+		if (!hwc->channel_up)
+			return -ENODEV;
 
-	*msg_id = index;
+		if (hwc->hwc_timed_out)
+			return -ETIMEDOUT;
+	}
 
+	*msg_id = index;
 	return 0;
 }
 
@@ -35,10 +62,17 @@ static void mana_hwc_put_msg_index(struct hw_channel_context *hwc, u16 msg_id)
 	unsigned long flags;
 
 	spin_lock_irqsave(&r->lock, flags);
-	bitmap_clear(hwc->inflight_msg_res.map, msg_id, 1);
+	bitmap_clear(r->map, msg_id, 1);
 	spin_unlock_irqrestore(&r->lock, flags);
 
-	up(&hwc->sema);
+	wake_up(&hwc->msg_waitq);
+}
+
+static void hwc_ctx_put(struct hw_channel_context *hwc,
+			struct hwc_caller_ctx *ctx)
+{
+	if (refcount_dec_and_test(&ctx->refcnt))
+		mana_hwc_put_msg_index(hwc, ctx->msg_id);
 }
 
 static int mana_hwc_verify_resp_msg(const struct hwc_caller_ctx *caller_ctx,
@@ -114,22 +148,32 @@ static void mana_hwc_handle_resp(struct hw_channel_context *hwc, u32 resp_len,
 		resp_len = 0;
 	}
 
-	err = mana_hwc_verify_resp_msg(ctx, resp_msg, resp_len);
-	if (err)
-		goto out;
+	spin_lock(&ctx->lock);
 
-	ctx->status_code = resp_msg->status;
+	err = mana_hwc_verify_resp_msg(ctx, resp_msg, resp_len);
 
-	memcpy(ctx->output_buf, resp_msg, resp_len);
-out:
-	ctx->error = err;
+	if (!err && ctx->output_buf) {
+		ctx->status_code = resp_msg->status;
+		memcpy(ctx->output_buf, resp_msg, resp_len);
+		ctx->error = 0;
+	} else if (ctx->output_buf) {
+		/* Only overwrite error if the sender hasn't timed out
+		 * or been force-completed by destroy.  When output_buf
+		 * is NULL, a terminal error (-ENODEV or timeout) has
+		 * already been set — preserve it so the sender doesn't
+		 * see a spurious success.
+		 */
+		ctx->error = err;
+	}
 
-	/* Must post rx wqe before complete(), otherwise the next rx may
-	 * hit no_wqe error.
+	/* Post RX WQE before completing — the next response may arrive
+	 * immediately and needs a posted buffer.
 	 */
 	mana_hwc_post_rx_wqe(hwc->rxq, rx_req);
-
 	complete(&ctx->comp_event);
+	spin_unlock(&ctx->lock);
+
+	hwc_ctx_put(hwc, ctx);
 }
 
 static void mana_hwc_init_event_handler(void *ctx, struct gdma_queue *q_self,
@@ -617,6 +661,7 @@ static int mana_hwc_create_wq(struct hw_channel_context *hwc,
 	hwc_wq->gdma_wq = queue;
 	hwc_wq->queue_depth = q_depth;
 	hwc_wq->hwc_cq = hwc_cq;
+	spin_lock_init(&hwc_wq->lock);
 
 	err = mana_hwc_alloc_dma_buf(hwc, q_depth, max_msg_size,
 				     &hwc_wq->msg_buf);
@@ -634,7 +679,7 @@ static int mana_hwc_create_wq(struct hw_channel_context *hwc,
 	return err;
 }
 
-static int mana_hwc_post_tx_wqe(const struct hwc_wq *hwc_txq,
+static int mana_hwc_post_tx_wqe(struct hwc_wq *hwc_txq,
 				struct hwc_work_request *req,
 				u32 dest_virt_rq_id, u32 dest_virt_rcq_id,
 				bool dest_pf)
@@ -673,7 +718,11 @@ static int mana_hwc_post_tx_wqe(const struct hwc_wq *hwc_txq,
 	req->wqe_req.inline_oob_data = tx_oob;
 	req->wqe_req.client_data_unit = 0;
 
+	/* Serialize WQE posting — multiple senders may call concurrently. */
+	spin_lock(&hwc_txq->lock);
 	err = mana_gd_post_and_ring(hwc_txq->gdma_wq, &req->wqe_req, NULL);
+	spin_unlock(&hwc_txq->lock);
+
 	if (err)
 		dev_err(dev, "Failed to post WQE on HWC SQ: %d\n", err);
 	return err;
@@ -684,7 +733,7 @@ static int mana_hwc_init_inflight_msg(struct hw_channel_context *hwc,
 {
 	int err;
 
-	sema_init(&hwc->sema, num_msg);
+	init_waitqueue_head(&hwc->msg_waitq);
 
 	err = mana_gd_alloc_res_map(num_msg, &hwc->inflight_msg_res);
 	if (err)
@@ -714,18 +763,34 @@ static int mana_hwc_test_channel(struct hw_channel_context *hwc, u16 q_depth,
 	if (!ctx)
 		return -ENOMEM;
 
-	for (i = 0; i < q_depth; ++i)
+	for (i = 0; i < q_depth; ++i) {
+		spin_lock_init(&ctx[i].lock);
 		init_completion(&ctx[i].comp_event);
+	}
 
 	hwc->caller_ctx = ctx;
 
-	return mana_gd_test_eq(gc, hwc->cq->gdma_eq);
+	/* channel_up must be set before the test EQ request, because
+	 * the request goes through mana_hwc_get_msg_index() which
+	 * checks channel_up.  caller_ctx is allocated above, so
+	 * concurrent access to a NULL caller_ctx is not possible.
+	 */
+	hwc->channel_up = true;
+
+	err = mana_gd_test_eq(gc, hwc->cq->gdma_eq);
+	if (err)
+		hwc->channel_up = false;
+
+	return err;
 }
 
 static int mana_hwc_establish_channel(struct gdma_context *gc, u16 *q_depth,
 				      u32 *max_req_msg_size,
 				      u32 *max_resp_msg_size)
 {
+	/* No RCU needed: called only from mana_hwc_create_channel
+	 * during init, before the channel is published to senders.
+	 */
 	struct hw_channel_context *hwc = gc->hwc.driver_data;
 	struct gdma_queue *rq = hwc->rxq->gdma_wq;
 	struct gdma_queue *sq = hwc->txq->gdma_wq;
@@ -842,6 +907,7 @@ int mana_hwc_create_channel(struct gdma_context *gc)
 	u32 max_req_msg_size, max_resp_msg_size;
 	struct gdma_dev *gd = &gc->hwc;
 	struct hw_channel_context *hwc;
+	unsigned long flags;
 	u16 q_depth_max;
 	int err;
 
@@ -850,10 +916,11 @@ int mana_hwc_create_channel(struct gdma_context *gc)
 		return -ENOMEM;
 
 	gd->gdma_context = gc;
-	gd->driver_data = hwc;
 	hwc->gdma_dev = gd;
 	hwc->dev = gc->dev;
 	hwc->hwc_timeout = HW_CHANNEL_WAIT_RESOURCE_TIMEOUT_MS;
+	atomic_set(&hwc->active_senders, 0);
+	init_waitqueue_head(&gc->hwc_drain_waitq);
 
 	/* HWC's instance number is always 0. */
 	gd->dev_id.as_uint32 = 0;
@@ -862,6 +929,15 @@ int mana_hwc_create_channel(struct gdma_context *gc)
 	gd->pdid = INVALID_PDID;
 	gd->doorbell = INVALID_DOORBELL;
 
+	/* Publish driver_data last, under hwc_lock: the lock orders the hwc
+	 * initialisation above before the pointer becomes visible and
+	 * serialises the publish against the control-plane readers in
+	 * mana_gd_send_request(), mana_need_log() and mana_serv_reset().
+	 */
+	spin_lock_irqsave(&gc->hwc_lock, flags);
+	gc->hwc.driver_data = hwc;
+	spin_unlock_irqrestore(&gc->hwc_lock, flags);
+
 	/* mana_hwc_init_queues() only creates the required data structures,
 	 * and doesn't touch the HWC device.
 	 */
@@ -898,13 +974,47 @@ void mana_hwc_destroy_channel(struct gdma_context *gc)
 {
 	struct hw_channel_context *hwc = gc->hwc.driver_data;
 	struct gdma_queue __rcu **old_cq_table;
+	unsigned long flags;
 
 	if (!hwc)
 		return;
 
+	/* Prevent new requests from starting and wake any
+	 * threads waiting for a free msg slot.  Set channel_up under
+	 * the bitmap lock so get_msg_index() cannot acquire a slot
+	 * and increment active_senders after this point.
+	 *
+	 * If channel_up is already false (e.g. init failed before
+	 * the channel was established), skip the lock — it may not
+	 * have been initialized yet, and no senders can be active.
+	 */
+	if (hwc->channel_up) {
+		spin_lock_irqsave(&hwc->inflight_msg_res.lock, flags);
+		hwc->channel_up = false;
+		spin_unlock_irqrestore(&hwc->inflight_msg_res.lock, flags);
+		wake_up_all(&hwc->msg_waitq);
+	}
+
+	/* Clear the pointer under hwc_lock so new callers in
+	 * mana_gd_send_request() see NULL and return -ENODEV.  The lock
+	 * makes the readers' "load driver_data + atomic_inc(active_senders)"
+	 * atomic against this store, so once it returns no new sender can
+	 * take a reference; the active_senders drain below waits out those
+	 * that already did, before their hwc is freed.
+	 */
+	spin_lock_irqsave(&gc->hwc_lock, flags);
+	gc->hwc.driver_data = NULL;
+	spin_unlock_irqrestore(&gc->hwc_lock, flags);
+
 	/* Tear down the HWC if setup_hwc previously activated MST entries.
 	 * This is the definitive flag — unlike max_num_cqs which depends
 	 * on the init EQE arriving.
+	 *
+	 * The return value is intentionally not checked.  This is the
+	 * terminal cleanup path — resources must be freed regardless.
+	 * If teardown fails, hardware may still have active MST entries,
+	 * but the EQ deregistration and IOMMU unmapping below prevent
+	 * stale hardware accesses from reaching kernel memory.
 	 */
 	if (hwc->setup_active) {
 		int td_err = mana_smc_teardown_hwc(&gc->shm_channel, false);
@@ -950,11 +1060,49 @@ void mana_hwc_destroy_channel(struct gdma_context *gc)
 		hwc->setup_active = false;
 	}
 
+	/* After SMC teardown, no more hardware events should arrive.
+	 * Force-complete any remaining in-flight senders so they can
+	 * exit and drop their refs.
+	 */
+	if (hwc->caller_ctx) {
+		struct hwc_caller_ctx *ctx;
+		int i;
+
+		for (i = 0; i < hwc->num_inflight_msg; i++) {
+			if (!test_bit(i, hwc->inflight_msg_res.map))
+				continue;
+
+			ctx = &hwc->caller_ctx[i];
+
+			/* Wake senders blocked on wait_for_completion.
+			 * Set error under lock to avoid racing with
+			 * handle_resp() which writes error under the
+			 * same lock.  The sender NULLs output_buf
+			 * after waking — doing it here would race
+			 * with a sender that hasn't set output_buf yet.
+			 */
+			spin_lock_irqsave(&ctx->lock, flags);
+			ctx->error = -ENODEV;
+			complete(&ctx->comp_event);
+			spin_unlock_irqrestore(&ctx->lock, flags);
+		}
+	}
+
+	/* Wait for all sender threads to finish and drop their refs.
+	 * After this, only slots held by timed-out senders whose
+	 * handle_resp() never ran remain in the bitmap.
+	 */
+	wait_event(gc->hwc_drain_waitq,
+		   atomic_read(&hwc->active_senders) == 0);
+
 	/* Tear down the HWC CQ object first — mana_hwc_destroy_cq()
 	 * both unpublishes the CQ from cq_table (+synchronize_rcu) and
-	 * deregisters the HWC EQ from the interrupt handler list (via
-	 * mana_gd_deregister_irq + synchronize_rcu), guaranteeing no
-	 * interrupt handler can access RQ/TXQ buffers after this point.
+	 * deregisters the HWC EQ from the interrupt handler's RCU list
+	 * (via mana_gd_deregister_irq + synchronize_rcu), guaranteeing
+	 * no interrupt handler can access RQ/TXQ buffers after this
+	 * point.  The active_senders drain above ensures no sender is
+	 * accessing the CQ via txq->hwc_cq when it is destroyed.  Then
+	 * destroy TXQ and RQ safely.
 	 */
 	if (hwc->cq)
 		mana_hwc_destroy_cq(hwc->gdma_dev->gdma_context, hwc->cq);
@@ -965,6 +1113,23 @@ void mana_hwc_destroy_channel(struct gdma_context *gc)
 	if (hwc->rxq)
 		mana_hwc_destroy_wq(hwc, hwc->rxq);
 
+	/* Release any slots still held — these belong to timed-out
+	 * senders where handle_resp() never ran (refcount = 1 with
+	 * handle_resp's ref still outstanding).
+	 */
+	if (hwc->caller_ctx) {
+		struct hwc_caller_ctx *ctx;
+		int i;
+
+		for (i = 0; i < hwc->num_inflight_msg; i++) {
+			if (!test_bit(i, hwc->inflight_msg_res.map))
+				continue;
+
+			ctx = &hwc->caller_ctx[i];
+			hwc_ctx_put(hwc, ctx);
+		}
+	}
+
 	kfree(hwc->caller_ctx);
 	hwc->caller_ctx = NULL;
 
@@ -978,7 +1143,6 @@ void mana_hwc_destroy_channel(struct gdma_context *gc)
 	hwc->hwc_timeout = 0;
 
 	kfree(hwc);
-	gc->hwc.driver_data = NULL;
 	gc->hwc.gdma_context = NULL;
 
 	old_cq_table = rcu_replace_pointer(gc->cq_table, NULL, true);
@@ -994,13 +1158,17 @@ int mana_hwc_send_request(struct hw_channel_context *hwc, u32 req_len,
 	struct hwc_wq *txq = hwc->txq;
 	struct gdma_req_hdr *req_msg;
 	struct hwc_caller_ctx *ctx;
+	unsigned long flags;
 	u32 dest_vrcq = 0;
 	u32 dest_vrq = 0;
 	u32 command;
+	u32 status;
 	u16 msg_id;
 	int err;
 
-	mana_hwc_get_msg_index(hwc, &msg_id);
+	err = mana_hwc_get_msg_index(hwc, &msg_id);
+	if (err)
+		return err;
 
 	tx_wr = &txq->msg_buf->reqs[msg_id];
 
@@ -1012,8 +1180,11 @@ int mana_hwc_send_request(struct hw_channel_context *hwc, u32 req_len,
 	}
 
 	ctx = hwc->caller_ctx + msg_id;
+
+	spin_lock_irqsave(&ctx->lock, flags);
 	ctx->output_buf = resp;
 	ctx->output_buflen = resp_len;
+	spin_unlock_irqrestore(&ctx->lock, flags);
 
 	req_msg = (struct gdma_req_hdr *)tx_wr->buf_va;
 	if (req)
@@ -1029,8 +1200,14 @@ int mana_hwc_send_request(struct hw_channel_context *hwc, u32 req_len,
 		dest_vrcq = hwc->pf_dest_vrcq_id;
 	}
 
+	/* Take handle_resp's ref before posting — hardware can respond
+	 * immediately after the doorbell ring.
+	 */
+	refcount_inc(&ctx->refcnt);
+
 	err = mana_hwc_post_tx_wqe(txq, tx_wr, dest_vrq, dest_vrcq, false);
 	if (err) {
+		refcount_dec(&ctx->refcnt);
 		dev_err(hwc->dev, "HWC: Failed to post send WQE: %d\n", err);
 		goto out;
 	}
@@ -1041,31 +1218,86 @@ int mana_hwc_send_request(struct hw_channel_context *hwc, u32 req_len,
 			dev_err(hwc->dev, "Command 0x%x timed out: %u ms\n",
 				command, hwc->hwc_timeout);
 
-		/* Reduce further waiting if HWC no response */
+		/* NULL out output_buf so a late handle_resp() won't write
+		 * into the caller's buffer after the sender returns, then
+		 * check whether handle_resp() already delivered a valid
+		 * response between the timeout firing and this lock
+		 * acquisition — ctx->error != -EINPROGRESS means it ran.
+		 */
+		spin_lock_irqsave(&ctx->lock, flags);
+		ctx->output_buf = NULL;
+		err = ctx->error;
+		status = ctx->status_code;
+		spin_unlock_irqrestore(&ctx->lock, flags);
+
+		if (err != -EINPROGRESS) {
+			/* handle_resp() delivered a valid response just after
+			 * the timeout fired.  The hardware is alive, so use the
+			 * response and leave the channel usable — do not latch
+			 * hwc_timed_out or degrade hwc_timeout for what turned
+			 * out to be a transient race.
+			 */
+			hwc_ctx_put(hwc, ctx);
+			goto check_status;
+		}
+
+		/* Genuine timeout: no response arrived.  Reduce further
+		 * waiting, and mark the channel timed out under the bitmap
+		 * lock so get_msg_index() cannot acquire new slots after this.
+		 */
 		if (hwc->hwc_timeout > 1)
 			hwc->hwc_timeout = 1;
 
+		spin_lock_irqsave(&hwc->inflight_msg_res.lock, flags);
+		hwc->hwc_timed_out = true;
+		spin_unlock_irqrestore(&hwc->inflight_msg_res.lock, flags);
+		wake_up_all(&hwc->msg_waitq);
+
 		err = -ETIMEDOUT;
-		goto out;
+		hwc_ctx_put(hwc, ctx);
+		goto done;
 	}
 
-	if (ctx->error) {
-		err = ctx->error;
-		goto out;
-	}
+	/* NULL output_buf so a late handle_resp() won't memcpy into
+	 * the caller's buffer after the sender exits.  Read error and
+	 * status_code under the same lock — after hwc_ctx_put the slot
+	 * may be reused and these fields overwritten.
+	 */
+	spin_lock_irqsave(&ctx->lock, flags);
+	ctx->output_buf = NULL;
+	err = ctx->error;
+	status = ctx->status_code;
+	spin_unlock_irqrestore(&ctx->lock, flags);
+	hwc_ctx_put(hwc, ctx);
+
+check_status:
+	if (err)
+		goto done;
 
-	if (ctx->status_code && ctx->status_code != GDMA_STATUS_MORE_ENTRIES) {
-		if (ctx->status_code == GDMA_STATUS_CMD_UNSUPPORTED) {
+	if (status && status != GDMA_STATUS_MORE_ENTRIES) {
+		if (status == GDMA_STATUS_CMD_UNSUPPORTED) {
 			err = -EOPNOTSUPP;
-			goto out;
+			goto done;
 		}
+
 		if (command != MANA_QUERY_PHY_STAT)
 			dev_err(hwc->dev, "Command 0x%x failed with status: 0x%x\n",
-				command, ctx->status_code);
+				command, status);
 		err = -EPROTO;
-		goto out;
+		goto done;
 	}
+
+	err = 0;
+	goto done;
 out:
-	mana_hwc_put_msg_index(hwc, msg_id);
+	/* Pre-post error paths: no WQE was submitted so handle_resp()
+	 * cannot race here.  refcount is 1 (no second ref taken).
+	 */
+	ctx = hwc->caller_ctx + msg_id;
+	spin_lock_irqsave(&ctx->lock, flags);
+	ctx->output_buf = NULL;
+	spin_unlock_irqrestore(&ctx->lock, flags);
+	hwc_ctx_put(hwc, ctx);
+done:
 	return err;
 }
diff --git a/include/net/mana/gdma.h b/include/net/mana/gdma.h
index 9ca7cf523366..01e845237b6a 100644
--- a/include/net/mana/gdma.h
+++ b/include/net/mana/gdma.h
@@ -481,6 +481,21 @@ struct gdma_context {
 	/* Hardware communication channel (HWC) */
 	struct gdma_dev		hwc;
 
+	/* destroy_channel() waits here for all HWC senders to exit.
+	 * Lives on gc (not hwc) so wake_up() after the last sender's
+	 * atomic_dec doesn't dereference freed hwc memory.
+	 */
+	wait_queue_head_t	hwc_drain_waitq;
+
+	/* Serializes hwc.driver_data (the hw_channel_context pointer)
+	 * between the control-plane readers in mana_gd_send_request(),
+	 * mana_need_log() and mana_serv_reset() and the publish/clear in
+	 * mana_hwc_create_channel()/mana_hwc_destroy_channel().  All users
+	 * are control-plane (HWC commands sleep; reset runs on a workqueue),
+	 * so a plain spinlock -- not RCU -- is sufficient.
+	 */
+	spinlock_t		hwc_lock;
+
 	/* Azure network adapter */
 	struct gdma_dev		mana;
 
diff --git a/include/net/mana/hw_channel.h b/include/net/mana/hw_channel.h
index 684dcec8e612..bc62d1ce7bd4 100644
--- a/include/net/mana/hw_channel.h
+++ b/include/net/mana/hw_channel.h
@@ -164,6 +164,9 @@ struct hwc_wq {
 	u16 queue_depth;
 
 	struct hwc_cq *hwc_cq;
+
+	/* Serializes concurrent mana_gd_post_and_ring() calls. */
+	spinlock_t lock;
 };
 
 struct hwc_caller_ctx {
@@ -173,6 +176,17 @@ struct hwc_caller_ctx {
 
 	u32 error; /* Linux error code */
 	u32 status_code;
+
+	/* Protects output_buf against concurrent access from
+	 * handle_resp() (CQ interrupt) and the sender timeout path.
+	 */
+	spinlock_t lock;
+
+	/* Tracks sender + handle_resp ownership.  The last put
+	 * (refcount reaches 0) releases the bitmap slot.
+	 */
+	refcount_t refcnt;
+	u16 msg_id;
 };
 
 struct hw_channel_context {
@@ -193,13 +207,24 @@ struct hw_channel_context {
 	struct hwc_wq *txq;
 	struct hwc_cq *cq;
 
-	struct semaphore sema;
 	struct gdma_resource inflight_msg_res;
+	/* Waitqueue for senders blocked on a full inflight bitmap. */
+	wait_queue_head_t msg_waitq;
 
 	u32 pf_dest_vrq_id;
 	u32 pf_dest_vrcq_id;
 	u32 hwc_timeout;
 
+	/* Set after channel is fully established; cleared on teardown to
+	 * abort waiters in mana_hwc_get_msg_index() and reject new sends.
+	 */
+	bool channel_up;
+
+	/* Set on first HWC timeout.  Causes get_msg_index() to return
+	 * -ETIMEDOUT instead of waiting, draining all queued senders.
+	 */
+	bool hwc_timed_out;
+
 	/* Set after mana_smc_setup_hwc() succeeds (hardware has active
 	 * MST entries).  On recoverable paths (establish_channel)
 	 * cleared only after successful teardown so a retry remains
@@ -208,6 +233,8 @@ struct hw_channel_context {
 	 */
 	bool setup_active;
 
+	atomic_t active_senders;
+
 	struct hwc_caller_ctx *caller_ctx;
 };
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH net-next 5/7] net: mana: fix HWC teardown safety with setup_active flag and destroy ordering
From: Long Li @ 2026-07-15  3:29 UTC (permalink / raw)
  To: Long Li, Konstantin Taranov, Jakub Kicinski, David S . Miller,
	Paolo Abeni, Eric Dumazet, Andrew Lunn, Jason Gunthorpe,
	Leon Romanovsky, Haiyang Zhang, K . Y . Srinivasan, Wei Liu,
	Dexuan Cui, shradhagupta, Simon Horman
  Cc: netdev, linux-rdma, linux-hyperv, linux-kernel
In-Reply-To: <20260715032942.3945317-1-longli@microsoft.com>

Two teardown hazards let the hardware touch memory the driver freed.

First, once mana_smc_setup_hwc() succeeds the device has active MST
entries and can DMA into the HWC queue buffers.  If a later step in
mana_hwc_establish_channel() fails, the caller had no reliable way to
know teardown was required and could free those buffers while the
mappings were still live -- a DMA-after-free.  max_num_cqs was used as a
"HWC is up" proxy, but it is only set when the init EQE arrives.

Add a setup_active flag, set the moment setup_hwc activates MST entries.
establish_channel() now tears down on any later failure and clears
setup_active once teardown succeeds; destroy_channel() gates teardown on
setup_active.  max_num_cqs is no longer reset: it is an immutable bound
(see gdma.h) and cq_table == NULL is the sole teardown signal.

Second, destroy_channel() freed the TXQ/RXQ buffers while the HWC EQ was
still on the interrupt dispatch list, so an in-flight interrupt could run
the handler against freed buffers:

  CPU A (mana_gd_intr, hard IRQ)        CPU B (destroy_channel)
  ----------------------------------    ------------------------------
                                        free TXQ/RXQ DMA buffers
  handler accesses RQ/TXQ buffers       (EQ still registered)

Destroy the CQ first: mana_hwc_destroy_cq() -> mana_gd_deregister_irq()
removes the EQ via list_del_rcu() + synchronize_rcu(), after which no
handler can reach the queues; only then free the TXQ and RXQ.

Fixes: ca9c54d2d6a5 ("net: mana: Add a driver for Microsoft Azure Network Adapter (MANA)")
Signed-off-by: Long Li <longli@microsoft.com>
---
 .../net/ethernet/microsoft/mana/hw_channel.c  | 106 ++++++++++++++----
 include/net/mana/gdma.h                       |   8 +-
 include/net/mana/hw_channel.h                 |   8 ++
 3 files changed, 100 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.c b/drivers/net/ethernet/microsoft/mana/hw_channel.c
index 68236727aee8..b26c2122ebf5 100644
--- a/drivers/net/ethernet/microsoft/mana/hw_channel.c
+++ b/drivers/net/ethernet/microsoft/mana/hw_channel.c
@@ -4,6 +4,7 @@
 #include <net/mana/gdma.h>
 #include <net/mana/mana.h>
 #include <net/mana/hw_channel.h>
+#include <linux/pci.h>
 #include <linux/vmalloc.h>
 
 static int mana_hwc_get_msg_index(struct hw_channel_context *hwc, u16 *msg_id)
@@ -744,20 +745,33 @@ static int mana_hwc_establish_channel(struct gdma_context *gc, u16 *q_depth,
 	if (err)
 		return err;
 
-	if (!wait_for_completion_timeout(&hwc->hwc_init_eqe_comp, 60 * HZ))
-		return -ETIMEDOUT;
+	/* setup_hwc activated MST entries — hardware can now DMA into
+	 * our queue buffers.  If anything below fails, we must tear
+	 * down before returning so the caller doesn't need to track
+	 * whether setup_hwc succeeded.
+	 */
+	hwc->setup_active = true;
+
+	if (!wait_for_completion_timeout(&hwc->hwc_init_eqe_comp, 60 * HZ)) {
+		err = -ETIMEDOUT;
+		goto teardown;
+	}
 
 	*q_depth = hwc->hwc_init_q_depth_max;
 	*max_req_msg_size = hwc->hwc_init_max_req_msg_size;
 	*max_resp_msg_size = hwc->hwc_init_max_resp_msg_size;
 
 	/* Both were set in mana_hwc_init_event_handler(). */
-	if (WARN_ON(cq->id >= gc->max_num_cqs))
-		return -EPROTO;
+	if (WARN_ON(cq->id >= gc->max_num_cqs)) {
+		err = -EPROTO;
+		goto teardown;
+	}
 
 	cq_table = vcalloc(gc->max_num_cqs, sizeof(*cq_table));
-	if (!cq_table)
-		return -ENOMEM;
+	if (!cq_table) {
+		err = -ENOMEM;
+		goto teardown;
+	}
 
 	rcu_assign_pointer(cq_table[cq->id], cq);
 	/* Publish the fully-initialised table last; pairs with the
@@ -766,6 +780,16 @@ static int mana_hwc_establish_channel(struct gdma_context *gc, u16 *q_depth,
 	rcu_assign_pointer(gc->cq_table, cq_table);
 
 	return 0;
+
+teardown:
+	{
+		int td_err = mana_smc_teardown_hwc(&gc->shm_channel, false);
+
+		if (!td_err)
+			hwc->setup_active = false;
+
+		return td_err ? td_err : err;
+	}
 }
 
 static int mana_hwc_init_queues(struct hw_channel_context *hwc, u16 q_depth,
@@ -878,11 +902,62 @@ void mana_hwc_destroy_channel(struct gdma_context *gc)
 	if (!hwc)
 		return;
 
-	/* gc->max_num_cqs is set in mana_hwc_init_event_handler(). If it's
-	 * non-zero, the HWC worked and we should tear down the HWC here.
+	/* Tear down the HWC if setup_hwc previously activated MST entries.
+	 * This is the definitive flag — unlike max_num_cqs which depends
+	 * on the init EQE arriving.
 	 */
-	if (gc->max_num_cqs > 0)
-		mana_smc_teardown_hwc(&gc->shm_channel, false);
+	if (hwc->setup_active) {
+		int td_err = mana_smc_teardown_hwc(&gc->shm_channel, false);
+
+		if (td_err) {
+			dev_err(gc->dev, "HWC teardown failed: %d, issuing FLR\n",
+				td_err);
+
+			/* On systems without IOMMU, freeing DMA memory with
+			 * active hardware MST mappings risks memory corruption.
+			 * Issue FLR to force-reset the device and invalidate
+			 * all hardware state including MST entries.
+			 */
+			td_err = pcie_flr(to_pci_dev(gc->dev));
+			if (td_err) {
+				/* Device is wedged: teardown and FLR both failed.
+				 * Hardware may still have active MST entries that
+				 * allow DMA into our queue buffers.
+				 *
+				 * On IOMMU systems: dma_free_coherent() would unmap
+				 * the IOVA, causing hardware DMA to fault at the
+				 * IOMMU (safe). But on non-IOMMU systems, freeing
+				 * the physical pages allows them to be reused for
+				 * other purposes while hardware can still DMA to
+				 * them (unsafe).
+				 *
+				 * but leak all DMA buffers to prevent corruption.
+				 */
+
+				dev_warn(gc->dev,
+					 "Leaked HWC DMA buffers (CQ/RQ/TXQ) to prevent memory corruption. Device is no longer usable.\n");
+
+				/* Do NOT proceed to mana_hwc_destroy_cq/wq — they
+				 * would call dma_free_coherent().  Leave hwc, cq,
+				 * rxq, txq allocated forever.
+				 */
+				return;
+			}
+
+			dev_info(gc->dev, "FLR succeeded, hardware state cleared\n");
+		}
+
+		hwc->setup_active = false;
+	}
+
+	/* Tear down the HWC CQ object first — mana_hwc_destroy_cq()
+	 * both unpublishes the CQ from cq_table (+synchronize_rcu) and
+	 * deregisters the HWC EQ from the interrupt handler list (via
+	 * mana_gd_deregister_irq + synchronize_rcu), guaranteeing no
+	 * interrupt handler can access RQ/TXQ buffers after this point.
+	 */
+	if (hwc->cq)
+		mana_hwc_destroy_cq(hwc->gdma_dev->gdma_context, hwc->cq);
 
 	if (hwc->txq)
 		mana_hwc_destroy_wq(hwc, hwc->txq);
@@ -890,17 +965,6 @@ void mana_hwc_destroy_channel(struct gdma_context *gc)
 	if (hwc->rxq)
 		mana_hwc_destroy_wq(hwc, hwc->rxq);
 
-	if (hwc->cq)
-		mana_hwc_destroy_cq(hwc->gdma_dev->gdma_context, hwc->cq);
-
-	/* Reset only after mana_hwc_destroy_cq() above has run with a valid
-	 * max_num_cqs so mana_gd_destroy_cq() clears the CQ table slot and
-	 * waits out in-flight EQ handlers (synchronize_rcu) before the CQ is
-	 * freed.  Clearing it earlier would make that path early-return and
-	 * skip the slot clear, leaving a dangling cq_table entry.
-	 */
-	gc->max_num_cqs = 0;
-
 	kfree(hwc->caller_ctx);
 	hwc->caller_ctx = NULL;
 
diff --git a/include/net/mana/gdma.h b/include/net/mana/gdma.h
index da52701e7816..9ca7cf523366 100644
--- a/include/net/mana/gdma.h
+++ b/include/net/mana/gdma.h
@@ -428,7 +428,13 @@ struct gdma_context {
 	/* L2 MTU */
 	u16 adapter_mtu;
 
-	/* This maps a CQ index to the queue structure. */
+	/* Size of cq_table, i.e. the largest valid CQ index + 1.  Set once
+	 * when cq_table is allocated and treated as immutable for the
+	 * table's lifetime (a bound only) -- it is never reset on teardown.
+	 * cq_table == NULL is the sole "table torn down" signal, so every
+	 * cq_table[id] access must guard with both !cq_table (gone) and
+	 * id >= max_num_cqs (out of bounds).
+	 */
 	unsigned int		max_num_cqs;
 	/* Both the base pointer and each entry are RCU-managed.  The fast
 	 * path (mana_gd_process_eqe) reads the base via rcu_dereference()
diff --git a/include/net/mana/hw_channel.h b/include/net/mana/hw_channel.h
index 73671f479399..684dcec8e612 100644
--- a/include/net/mana/hw_channel.h
+++ b/include/net/mana/hw_channel.h
@@ -200,6 +200,14 @@ struct hw_channel_context {
 	u32 pf_dest_vrcq_id;
 	u32 hwc_timeout;
 
+	/* Set after mana_smc_setup_hwc() succeeds (hardware has active
+	 * MST entries).  On recoverable paths (establish_channel)
+	 * cleared only after successful teardown so a retry remains
+	 * possible.  On the terminal destroy_channel path, cleared
+	 * unconditionally since hwc is about to be freed.
+	 */
+	bool setup_active;
+
 	struct hwc_caller_ctx *caller_ctx;
 };
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH net-next 4/7] net: mana: validate hardware-supplied values in the HWC RX path
From: Long Li @ 2026-07-15  3:29 UTC (permalink / raw)
  To: Long Li, Konstantin Taranov, Jakub Kicinski, David S . Miller,
	Paolo Abeni, Eric Dumazet, Andrew Lunn, Jason Gunthorpe,
	Leon Romanovsky, Haiyang Zhang, K . Y . Srinivasan, Wei Liu,
	Dexuan Cui, shradhagupta, Simon Horman
  Cc: netdev, linux-rdma, linux-hyperv, linux-kernel
In-Reply-To: <20260715032942.3945317-1-longli@microsoft.com>

mana_hwc_rx_event_handler() and mana_hwc_handle_resp() consumed lengths
and indices taken straight from device DMA without validation.  A buggy
firmware or a malicious host (in a confidential VM, where the DMA buffer
is shared) could drive a wrong or reused in-flight request to completion
or index out of bounds.  Validate before use:

  - match the SGE address against the address the driver posted for that
    slot, not just an in-range index -- an in-range but wrong SGE would
    otherwise truncate onto a neighbouring slot and read a stale response;
  - require the response to cover a full gdma_resp_hdr before reading
    hwc_msg_id, so a short response cannot complete a slot with stale
    bytes left by the buffer's previous occupant;
  - bounds-check hwc_msg_id in mana_hwc_handle_resp() before indexing the
    inflight bitmap and caller_ctx;
  - reject a resp_len larger than the RX buffer.

Repost the RX WQE on every validation early-return so a rejected response
does not permanently shrink the posted RQ depth.  The one path that
cannot identify the slot (SGE mismatch) intentionally leaks a single WQE
rather than risk reposting the wrong one.

Fixes: ca9c54d2d6a5 ("net: mana: Add a driver for Microsoft Azure Network Adapter (MANA)")
Signed-off-by: Long Li <longli@microsoft.com>
---
 .../net/ethernet/microsoft/mana/hw_channel.c  | 58 +++++++++++++++++--
 1 file changed, 54 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.c b/drivers/net/ethernet/microsoft/mana/hw_channel.c
index 2239fdeda57c..68236727aee8 100644
--- a/drivers/net/ethernet/microsoft/mana/hw_channel.c
+++ b/drivers/net/ethernet/microsoft/mana/hw_channel.c
@@ -83,6 +83,17 @@ static void mana_hwc_handle_resp(struct hw_channel_context *hwc, u32 resp_len,
 	struct hwc_caller_ctx *ctx;
 	int err;
 
+	/* Validate msg_id is in range before using it to index bitmap
+	 * and caller_ctx array.  Malicious firmware could send
+	 * out-of-range msg_id causing out-of-bounds access.
+	 */
+	if (msg_id >= hwc->num_inflight_msg) {
+		dev_err(hwc->dev, "hwc_rx: msg_id %u >= max %u\n",
+			msg_id, hwc->num_inflight_msg);
+		mana_hwc_post_rx_wqe(hwc->rxq, rx_req);
+		return;
+	}
+
 	if (!test_bit(msg_id, hwc->inflight_msg_res.map)) {
 		dev_err(hwc->dev, "hwc_rx: invalid msg_id = %u\n", msg_id);
 		mana_hwc_post_rx_wqe(hwc->rxq, rx_req);
@@ -90,6 +101,18 @@ static void mana_hwc_handle_resp(struct hw_channel_context *hwc, u32 resp_len,
 	}
 
 	ctx = hwc->caller_ctx + msg_id;
+
+	/* Reject responses larger than the RX DMA buffer — the SGE
+	 * limits what hardware can DMA, so an oversized resp_len
+	 * indicates a firmware bug.  Fail rather than silently
+	 * truncating.
+	 */
+	if (resp_len > rx_req->buf_len) {
+		dev_err(hwc->dev, "HWC RX: resp_len %u > buf_len %u\n",
+			resp_len, rx_req->buf_len);
+		resp_len = 0;
+	}
+
 	err = mana_hwc_verify_resp_msg(ctx, resp_msg, resp_len);
 	if (err)
 		goto out;
@@ -261,19 +284,45 @@ static void mana_hwc_rx_event_handler(void *ctx, u32 gdma_rxq_id,
 
 	sge = (struct gdma_sge *)(wqe + 8 + dma_oob->inline_oob_size_div4 * 4);
 
-	/* Select the RX work request for virtual address and for reposting. */
+	/* Recover the originating RX slot from the SGE address.  Of the three
+	 * terms here only sge->address lives in device-accessible RQ memory;
+	 * rq_base_addr and max_resp_msg_size are driver-private constants.  An
+	 * in-range but wrong/unaligned SGE (corrupted WQE, or a malicious host
+	 * in a CVM) would otherwise truncate onto a neighbouring slot, letting
+	 * us read a stale response that could complete the wrong, reused
+	 * in-flight request.  Require the index to be in range AND the address
+	 * to exactly match the value the driver posted for that slot.
+	 */
 	rq_base_addr = hwc_rxq->msg_buf->mem_info.dma_handle;
 	rx_req_idx = (sge->address - rq_base_addr) / hwc->max_resp_msg_size;
 
-	if (rx_req_idx >= hwc_rxq->msg_buf->num_reqs) {
-		dev_err(hwc->dev, "HWC RX: wrong rx_req_idx=%llu, num_reqs=%u\n",
-			rx_req_idx, hwc_rxq->msg_buf->num_reqs);
+	if (rx_req_idx >= hwc_rxq->queue_depth ||
+	    sge->address != (u64)hwc_rxq->msg_buf->reqs[rx_req_idx].buf_sge_addr) {
+		/* Cannot trust which WQE this is, so we cannot safely repost
+		 * it; leak one RX WQE and bail.  This permanently leaks one
+		 * RX WQE but indicates a corrupted SGE from hardware (or host
+		 * tampering), which is an unrecoverable device error.
+		 */
+		dev_err(hwc->dev, "HWC RX: invalid SGE address %llx (idx=%llu)\n",
+			sge->address, rx_req_idx);
 		return;
 	}
 
 	rx_req = &hwc_rxq->msg_buf->reqs[rx_req_idx];
 	resp = (struct gdma_resp_hdr *)rx_req->buf_va;
 
+	/* Validate resp_len covers the response header before reading
+	 * hwc_msg_id.  A short response leaves stale data from the
+	 * previous buffer occupant, which could match a live slot and
+	 * complete the wrong request.
+	 */
+	if (rx_oob->tx_oob_data_size < sizeof(*resp)) {
+		dev_err(hwc->dev, "HWC RX: short resp_len=%u\n",
+			rx_oob->tx_oob_data_size);
+		mana_hwc_post_rx_wqe(hwc_rxq, rx_req);
+		return;
+	}
+
 	/* Read msg_id once from DMA buffer to prevent TOCTOU:
 	 * DMA memory is shared/unencrypted in CVMs - host can
 	 * modify it between reads.
@@ -281,6 +330,7 @@ static void mana_hwc_rx_event_handler(void *ctx, u32 gdma_rxq_id,
 	msg_id = READ_ONCE(resp->response.hwc_msg_id);
 	if (msg_id >= hwc->num_inflight_msg) {
 		dev_err(hwc->dev, "HWC RX: wrong msg_id=%u\n", msg_id);
+		mana_hwc_post_rx_wqe(hwc_rxq, rx_req);
 		return;
 	}
 
-- 
2.43.0


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox