Netdev List
 help / color / mirror / Atom feed
* RE: [PATCH bpf-next v4 2/6] net: veth: Add xmo_rx_checksum callback to veth driver
From: Loktionov, Aleksandr @ 2026-07-10 10:09 UTC (permalink / raw)
  To: Vladimir Vdovin, Lorenzo Bianconi, Donald Hunter, Jakub Kicinski,
	David S . Miller, Eric Dumazet, Paolo Abeni, Simon Horman,
	Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer,
	John Fastabend, Stanislav Fomichev, Andrew Lunn,
	Nguyen, Anthony L, Kitszel, Przemyslaw, Lobakin, Aleksander,
	Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman, Song Liu,
	Yonghong Song, KP Singh, Hao Luo, Jiri Olsa, Shuah Khan,
	Fijalkowski, Maciej
  Cc: Jakub Sitnicki, netdev@vger.kernel.org, bpf@vger.kernel.org,
	intel-wired-lan@lists.osuosl.org, linux-kselftest@vger.kernel.org
In-Reply-To: <20260708203410.45121-3-deliran@verdict.gg>



> -----Original Message-----
> From: Vladimir Vdovin <deliran@verdict.gg>
> Sent: Wednesday, July 8, 2026 10:34 PM
> To: Lorenzo Bianconi <lorenzo@kernel.org>; Donald Hunter
> <donald.hunter@gmail.com>; Jakub Kicinski <kuba@kernel.org>; David S .
> Miller <davem@davemloft.net>; Eric Dumazet <edumazet@google.com>;
> Paolo Abeni <pabeni@redhat.com>; Simon Horman <horms@kernel.org>;
> Alexei Starovoitov <ast@kernel.org>; Daniel Borkmann
> <daniel@iogearbox.net>; Jesper Dangaard Brouer <hawk@kernel.org>; John
> Fastabend <john.fastabend@gmail.com>; Stanislav Fomichev
> <sdf@fomichev.me>; Andrew Lunn <andrew+netdev@lunn.ch>; Nguyen,
> Anthony L <anthony.l.nguyen@intel.com>; Kitszel, Przemyslaw
> <przemyslaw.kitszel@intel.com>; Lobakin, Aleksander
> <aleksander.lobakin@intel.com>; Andrii Nakryiko <andrii@kernel.org>;
> Martin KaFai Lau <martin.lau@linux.dev>; Eduard Zingerman
> <eddyz87@gmail.com>; Song Liu <song@kernel.org>; Yonghong Song
> <yonghong.song@linux.dev>; KP Singh <kpsingh@kernel.org>; Hao Luo
> <haoluo@google.com>; Jiri Olsa <jolsa@kernel.org>; Shuah Khan
> <shuah@kernel.org>; Fijalkowski, Maciej <maciej.fijalkowski@intel.com>
> Cc: Jakub Sitnicki <jakub@cloudflare.com>; Loktionov, Aleksandr
> <aleksandr.loktionov@intel.com>; netdev@vger.kernel.org;
> bpf@vger.kernel.org; intel-wired-lan@lists.osuosl.org; linux-
> kselftest@vger.kernel.org; Vladimir Vdovin <deliran@verdict.gg>
> Subject: [PATCH bpf-next v4 2/6] net: veth: Add xmo_rx_checksum
> callback to veth driver
> 
> From: Lorenzo Bianconi <lorenzo@kernel.org>
> 
> Implement xmo_rx_checksum callback in veth driver to report RX
> checksum result to the eBPF program bounded to the veth device.
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> Signed-off-by: Vladimir Vdovin <deliran@verdict.gg>
> ---
>  drivers/net/veth.c | 32 ++++++++++++++++++++++++++++++++
>  1 file changed, 32 insertions(+)
> 
> diff --git a/drivers/net/veth.c b/drivers/net/veth.c index
> 1c5142149175..498d894d043d 100644
> --- a/drivers/net/veth.c
> +++ b/drivers/net/veth.c
> @@ -1700,6 +1700,37 @@ static int veth_xdp_rx_vlan_tag(const struct
> xdp_md *ctx, __be16 *vlan_proto,
>  	return err;
>  }
> 
> +static int veth_xdp_rx_checksum(const struct xdp_md *ctx,
> +				enum xdp_checksum *ip_summed,
> +				u32 *cksum, u8 *cksum_level)
> +{
> +	const struct veth_xdp_buff *_ctx = (void *)ctx;
> +	const struct sk_buff *skb = _ctx->skb;
> +
> +	if (!skb)
> +		return -ENODATA;
> +
> +	switch (skb->ip_summed) {
> +	case CHECKSUM_COMPLETE:
> +		*ip_summed = XDP_CHECKSUM_COMPLETE;
> +		*cksum = skb->csum;
> +		*cksum_level = 0;
> +		break;
> +	case CHECKSUM_UNNECESSARY:
> +		*ip_summed = XDP_CHECKSUM_UNNECESSARY;
> +		*cksum_level = skb->csum_level;
> +		*cksum = 0;
> +		break;
> +	default:
> +		*ip_summed = XDP_CHECKSUM_NONE;
> +		*cksum_level = 0;
> +		*cksum = 0;
> +		break;
> +	}
> +
> +	return 0;
> +}
> +
>  static const struct net_device_ops veth_netdev_ops = {
>  	.ndo_init            = veth_dev_init,
>  	.ndo_open            = veth_open,
> @@ -1725,6 +1756,7 @@ static const struct xdp_metadata_ops
> veth_xdp_metadata_ops = {
>  	.xmo_rx_timestamp		= veth_xdp_rx_timestamp,
>  	.xmo_rx_hash			= veth_xdp_rx_hash,
>  	.xmo_rx_vlan_tag		= veth_xdp_rx_vlan_tag,
> +	.xmo_rx_checksum		= veth_xdp_rx_checksum,
>  };
> 
>  #define VETH_FEATURES (NETIF_F_SG | NETIF_F_FRAGLIST |
> NETIF_F_HW_CSUM | \
> --
> 2.47.0

Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>

^ permalink raw reply

* RE: [PATCH bpf-next v4 3/6] net: ice: Add xmo_rx_checksum callback
From: Loktionov, Aleksandr @ 2026-07-10 10:10 UTC (permalink / raw)
  To: Vladimir Vdovin, Lorenzo Bianconi, Donald Hunter, Jakub Kicinski,
	David S . Miller, Eric Dumazet, Paolo Abeni, Simon Horman,
	Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer,
	John Fastabend, Stanislav Fomichev, Andrew Lunn,
	Nguyen, Anthony L, Kitszel, Przemyslaw, Lobakin, Aleksander,
	Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman, Song Liu,
	Yonghong Song, KP Singh, Hao Luo, Jiri Olsa, Shuah Khan,
	Fijalkowski, Maciej
  Cc: Jakub Sitnicki, netdev@vger.kernel.org, bpf@vger.kernel.org,
	intel-wired-lan@lists.osuosl.org, linux-kselftest@vger.kernel.org
In-Reply-To: <20260708203410.45121-4-deliran@verdict.gg>



> -----Original Message-----
> From: Vladimir Vdovin <deliran@verdict.gg>
> Sent: Wednesday, July 8, 2026 10:34 PM
> To: Lorenzo Bianconi <lorenzo@kernel.org>; Donald Hunter
> <donald.hunter@gmail.com>; Jakub Kicinski <kuba@kernel.org>; David S .
> Miller <davem@davemloft.net>; Eric Dumazet <edumazet@google.com>;
> Paolo Abeni <pabeni@redhat.com>; Simon Horman <horms@kernel.org>;
> Alexei Starovoitov <ast@kernel.org>; Daniel Borkmann
> <daniel@iogearbox.net>; Jesper Dangaard Brouer <hawk@kernel.org>; John
> Fastabend <john.fastabend@gmail.com>; Stanislav Fomichev
> <sdf@fomichev.me>; Andrew Lunn <andrew+netdev@lunn.ch>; Nguyen,
> Anthony L <anthony.l.nguyen@intel.com>; Kitszel, Przemyslaw
> <przemyslaw.kitszel@intel.com>; Lobakin, Aleksander
> <aleksander.lobakin@intel.com>; Andrii Nakryiko <andrii@kernel.org>;
> Martin KaFai Lau <martin.lau@linux.dev>; Eduard Zingerman
> <eddyz87@gmail.com>; Song Liu <song@kernel.org>; Yonghong Song
> <yonghong.song@linux.dev>; KP Singh <kpsingh@kernel.org>; Hao Luo
> <haoluo@google.com>; Jiri Olsa <jolsa@kernel.org>; Shuah Khan
> <shuah@kernel.org>; Fijalkowski, Maciej <maciej.fijalkowski@intel.com>
> Cc: Jakub Sitnicki <jakub@cloudflare.com>; Loktionov, Aleksandr
> <aleksandr.loktionov@intel.com>; netdev@vger.kernel.org;
> bpf@vger.kernel.org; intel-wired-lan@lists.osuosl.org; linux-
> kselftest@vger.kernel.org; Vladimir Vdovin <deliran@verdict.gg>
> Subject: [PATCH bpf-next v4 3/6] net: ice: Add xmo_rx_checksum
> callback
> 
> From: Lorenzo Bianconi <lorenzo@kernel.org>
> 
> Implement xmo_rx_checksum callback in ice driver to report RX checksum
> result to the eBPF program bounded to the NIC.
> Introduce ice_get_rx_csum utility routine in order to make the rx
> checksum code reusable from ice_rx_csum()
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> Signed-off-by: Vladimir Vdovin <deliran@verdict.gg>
> ---
>  drivers/net/ethernet/intel/ice/ice_txrx_lib.c | 123 ++++++++++++-----
> -
>  1 file changed, 81 insertions(+), 42 deletions(-)
> 
> diff --git a/drivers/net/ethernet/intel/ice/ice_txrx_lib.c
> b/drivers/net/ethernet/intel/ice/ice_txrx_lib.c
> index e695a664e53d..3aa82ff03d9e 100644
> --- a/drivers/net/ethernet/intel/ice/ice_txrx_lib.c
> +++ b/drivers/net/ethernet/intel/ice/ice_txrx_lib.c
> @@ -78,69 +78,48 @@ ice_rx_hash_to_skb(const struct ice_rx_ring
> *rx_ring,
>  		libeth_rx_pt_set_hash(skb, hash, decoded);  }
> 
> -/**
> - * ice_rx_gcs - Set generic checksum in skb
> - * @skb: skb currently being received and modified
> - * @rx_desc: receive descriptor
> - */
> -static void ice_rx_gcs(struct sk_buff *skb,
> -		       const union ice_32b_rx_flex_desc *rx_desc)
> -{
> -	const struct ice_32b_rx_flex_desc_nic *desc;
> -	u16 csum;
> -
> -	desc = (struct ice_32b_rx_flex_desc_nic *)rx_desc;
> -	skb->ip_summed = CHECKSUM_COMPLETE;
> -	csum = (__force u16)desc->raw_csum;
> -	skb->csum = csum_unfold((__force __sum16)swab16(csum));
> -}
> -
> -/**
> - * ice_rx_csum - Indicate in skb if checksum is good
> - * @ring: the ring we care about
> - * @skb: skb currently being received and modified
> - * @rx_desc: the receive descriptor
> - * @ptype: the packet type decoded by hardware
> - *
> - * skb->protocol must be set before this function is called
> - */
>  static void
> -ice_rx_csum(struct ice_rx_ring *ring, struct sk_buff *skb,
> -	    union ice_32b_rx_flex_desc *rx_desc, u16 ptype)
> +ice_get_rx_csum(const union ice_32b_rx_flex_desc *rx_desc, u16 ptype,
> +		struct ice_rx_ring *ring, enum xdp_checksum *ip_summed,
> +		u32 *cksum, u8 *cksum_level)
>  {
> -	struct libeth_rx_pt decoded;
> +	struct libeth_rx_pt decoded = libie_rx_pt_parse(ptype);
>  	u16 rx_status0, rx_status1;
>  	bool ipv4, ipv6;
> 
> -	/* Start with CHECKSUM_NONE and by default csum_level = 0 */
> -	skb->ip_summed = CHECKSUM_NONE;
> -
> -	decoded = libie_rx_pt_parse(ptype);
>  	if (!libeth_rx_pt_has_checksum(ring->netdev, decoded))
> -		return;
> +		goto checksum_none;
> 
>  	rx_status0 = le16_to_cpu(rx_desc->wb.status_error0);
>  	rx_status1 = le16_to_cpu(rx_desc->wb.status_error1);
> -
>  	if ((ring->flags & ICE_RX_FLAGS_RING_GCS) &&
>  	    rx_desc->wb.rxdid == ICE_RXDID_FLEX_NIC &&
>  	    (decoded.inner_prot == LIBETH_RX_PT_INNER_TCP ||
>  	     decoded.inner_prot == LIBETH_RX_PT_INNER_UDP ||
>  	     decoded.inner_prot == LIBETH_RX_PT_INNER_ICMP)) {
> -		ice_rx_gcs(skb, rx_desc);
> +		const struct ice_32b_rx_flex_desc_nic *desc;
> +		__wsum wcsum;
> +		u16 csum;
> +
> +		desc = (struct ice_32b_rx_flex_desc_nic *)rx_desc;
> +		*ip_summed = XDP_CHECKSUM_COMPLETE;
> +		csum = (__force u16)desc->raw_csum;
> +		wcsum = csum_unfold((__force __sum16)swab16(csum));
> +		*cksum = (__force u32)wcsum;
> +		*cksum_level = 0;
>  		return;
>  	}
> 
>  	/* check if HW has decoded the packet and checksum */
>  	if (!(rx_status0 & BIT(ICE_RX_FLEX_DESC_STATUS0_L3L4P_S)))
> -		return;
> +		goto checksum_none;
> 
>  	ipv4 = libeth_rx_pt_get_ip_ver(decoded) ==
> LIBETH_RX_PT_OUTER_IPV4;
>  	ipv6 = libeth_rx_pt_get_ip_ver(decoded) ==
> LIBETH_RX_PT_OUTER_IPV6;
> 
>  	if (ipv4 && (rx_status0 &
> (BIT(ICE_RX_FLEX_DESC_STATUS0_XSUM_EIPE_S)))) {
>  		ring->vsi->back->hw_rx_eipe_error++;
> -		return;
> +		goto checksum_none;
>  	}
> 
>  	if (ipv4 && (rx_status0 &
> (BIT(ICE_RX_FLEX_DESC_STATUS0_XSUM_IPE_S))))
> @@ -164,14 +143,51 @@ ice_rx_csum(struct ice_rx_ring *ring, struct
> sk_buff *skb,
>  	 * we need to bump the checksum level by 1 to reflect the fact
> that
>  	 * we are indicating we validated the inner checksum.
>  	 */
> -	if (decoded.tunnel_type >= LIBETH_RX_PT_TUNNEL_IP_GRENAT)
> -		skb->csum_level = 1;
> -
> -	skb->ip_summed = CHECKSUM_UNNECESSARY;
> +	*cksum_level = decoded.tunnel_type >=
> LIBETH_RX_PT_TUNNEL_IP_GRENAT;
> +	*ip_summed = XDP_CHECKSUM_UNNECESSARY;
> +	*cksum = 0;
>  	return;
> 
>  checksum_fail:
>  	ring->vsi->back->hw_csum_rx_error++;
> +checksum_none:
> +	*ip_summed = XDP_CHECKSUM_NONE;
> +	*cksum_level = 0;
> +	*cksum = 0;
> +}
> +
> +/**
> + * ice_rx_csum - Indicate in skb if checksum is good
> + * @ring: the ring we care about
> + * @skb: skb currently being received and modified
> + * @rx_desc: the receive descriptor
> + * @ptype: the packet type decoded by hardware
> + *
> + * skb->protocol must be set before this function is called  */
> static
> +void ice_rx_csum(struct ice_rx_ring *ring, struct sk_buff *skb,
> +	    union ice_32b_rx_flex_desc *rx_desc, u16 ptype) {
> +	enum xdp_checksum ip_summed;
> +	u8 cksum_level;
> +	u32 cksum;
> +
> +	ice_get_rx_csum(rx_desc, ptype, ring, &ip_summed, &cksum,
> +			&cksum_level);
> +	switch (ip_summed) {
> +	case XDP_CHECKSUM_UNNECESSARY:
> +		skb->ip_summed = CHECKSUM_UNNECESSARY;
> +		skb->csum_level = cksum_level;
> +		break;
> +	case XDP_CHECKSUM_COMPLETE:
> +		skb->ip_summed = CHECKSUM_COMPLETE;
> +		skb->csum = (__force __wsum)cksum;
> +		break;
> +	default:
> +		skb->ip_summed = CHECKSUM_NONE;
> +		break;
> +	}
>  }
> 
>  /**
> @@ -566,6 +582,28 @@ static int ice_xdp_rx_hash(const struct xdp_md
> *ctx, u32 *hash,
>  	return 0;
>  }
> 
> +/**
> + * ice_xdp_rx_checksum - RX checksum XDP hint handler
> + * @ctx: XDP buff pointer
> + * @ip_summed: RX checksum result destination address
> + * @cksum: RX checksum value destination address
> + * @cksum_level: RX checksum level value destination address  */
> static
> +int ice_xdp_rx_checksum(const struct xdp_md *ctx,
> +			       enum xdp_checksum *ip_summed,
> +			       u32 *cksum, u8 *cksum_level)
> +{
> +	const struct libeth_xdp_buff *xdp_ext = (void *)ctx;
> +	const union ice_32b_rx_flex_desc *rx_desc = xdp_ext->desc;
> +	struct ice_rx_ring *ring;
> +
> +	ring = libeth_xdp_buff_to_rq(xdp_ext, typeof(*ring), xdp_rxq);
> +	ice_get_rx_csum(rx_desc, ice_get_ptype(rx_desc), ring,
> ip_summed,
> +			cksum, cksum_level);
> +
> +	return 0;
> +}
> +
>  /**
>   * ice_xdp_rx_vlan_tag - VLAN tag XDP hint handler
>   * @ctx: XDP buff pointer
> @@ -598,4 +636,5 @@ const struct xdp_metadata_ops ice_xdp_md_ops = {
>  	.xmo_rx_timestamp		= ice_xdp_rx_hw_ts,
>  	.xmo_rx_hash			= ice_xdp_rx_hash,
>  	.xmo_rx_vlan_tag		= ice_xdp_rx_vlan_tag,
> +	.xmo_rx_checksum		= ice_xdp_rx_checksum,
>  };
> --
> 2.47.0

Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>

^ permalink raw reply

* RE: [PATCH bpf-next v4 5/6] selftests/bpf: Add bpf_xdp_metadata_rx_checksum support to xdp_hw_metadat prog
From: Loktionov, Aleksandr @ 2026-07-10 10:11 UTC (permalink / raw)
  To: Vladimir Vdovin, Lorenzo Bianconi, Donald Hunter, Jakub Kicinski,
	David S . Miller, Eric Dumazet, Paolo Abeni, Simon Horman,
	Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer,
	John Fastabend, Stanislav Fomichev, Andrew Lunn,
	Nguyen, Anthony L, Kitszel, Przemyslaw, Lobakin, Aleksander,
	Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman, Song Liu,
	Yonghong Song, KP Singh, Hao Luo, Jiri Olsa, Shuah Khan,
	Fijalkowski, Maciej
  Cc: Jakub Sitnicki, netdev@vger.kernel.org, bpf@vger.kernel.org,
	intel-wired-lan@lists.osuosl.org, linux-kselftest@vger.kernel.org
In-Reply-To: <20260708203410.45121-6-deliran@verdict.gg>



> -----Original Message-----
> From: Vladimir Vdovin <deliran@verdict.gg>
> Sent: Wednesday, July 8, 2026 10:34 PM
> To: Lorenzo Bianconi <lorenzo@kernel.org>; Donald Hunter
> <donald.hunter@gmail.com>; Jakub Kicinski <kuba@kernel.org>; David S .
> Miller <davem@davemloft.net>; Eric Dumazet <edumazet@google.com>;
> Paolo Abeni <pabeni@redhat.com>; Simon Horman <horms@kernel.org>;
> Alexei Starovoitov <ast@kernel.org>; Daniel Borkmann
> <daniel@iogearbox.net>; Jesper Dangaard Brouer <hawk@kernel.org>; John
> Fastabend <john.fastabend@gmail.com>; Stanislav Fomichev
> <sdf@fomichev.me>; Andrew Lunn <andrew+netdev@lunn.ch>; Nguyen,
> Anthony L <anthony.l.nguyen@intel.com>; Kitszel, Przemyslaw
> <przemyslaw.kitszel@intel.com>; Lobakin, Aleksander
> <aleksander.lobakin@intel.com>; Andrii Nakryiko <andrii@kernel.org>;
> Martin KaFai Lau <martin.lau@linux.dev>; Eduard Zingerman
> <eddyz87@gmail.com>; Song Liu <song@kernel.org>; Yonghong Song
> <yonghong.song@linux.dev>; KP Singh <kpsingh@kernel.org>; Hao Luo
> <haoluo@google.com>; Jiri Olsa <jolsa@kernel.org>; Shuah Khan
> <shuah@kernel.org>; Fijalkowski, Maciej <maciej.fijalkowski@intel.com>
> Cc: Jakub Sitnicki <jakub@cloudflare.com>; Loktionov, Aleksandr
> <aleksandr.loktionov@intel.com>; netdev@vger.kernel.org;
> bpf@vger.kernel.org; intel-wired-lan@lists.osuosl.org; linux-
> kselftest@vger.kernel.org; Vladimir Vdovin <deliran@verdict.gg>
> Subject: [PATCH bpf-next v4 5/6] selftests/bpf: Add
> bpf_xdp_metadata_rx_checksum support to xdp_hw_metadat prog
> 
> From: Lorenzo Bianconi <lorenzo@kernel.org>
> 
> Introduce the capability to dump HW rx checksum in xdp_hw_metadata
> program via bpf_xdp_metadata_rx_checksum() kfunc.
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> Signed-off-by: Vladimir Vdovin <deliran@verdict.gg>
> ---
>  .../selftests/bpf/progs/xdp_hw_metadata.c     |  7 +++++
>  tools/testing/selftests/bpf/xdp_hw_metadata.c | 31
> +++++++++++++++++++
>  tools/testing/selftests/bpf/xdp_metadata.h    | 12 ++++---
>  3 files changed, 46 insertions(+), 4 deletions(-)
> 
> diff --git a/tools/testing/selftests/bpf/progs/xdp_hw_metadata.c
> b/tools/testing/selftests/bpf/progs/xdp_hw_metadata.c
> index 330ece2eabdb..5eeadb7e27cf 100644
> --- a/tools/testing/selftests/bpf/progs/xdp_hw_metadata.c
> +++ b/tools/testing/selftests/bpf/progs/xdp_hw_metadata.c
> @@ -110,6 +110,13 @@ int rx(struct xdp_md *ctx)
>  	else
>  		meta->hint_valid |= XDP_META_FIELD_VLAN_TAG;
> 
> +	err = bpf_xdp_metadata_rx_checksum(ctx, &meta->ip_summed,
> +					   &meta->cksum, &meta-
> >cksum_level);
> +	if (err)
> +		meta->rx_cksum_err = err;
> +	else
> +		meta->hint_valid |= XDP_META_FIELD_CHECKSUM;
> +
>  	__sync_add_and_fetch(&pkts_redir, 1);
>  	return bpf_redirect_map(&xsk, ctx->rx_queue_index, XDP_PASS);
> } diff --git a/tools/testing/selftests/bpf/xdp_hw_metadata.c
> b/tools/testing/selftests/bpf/xdp_hw_metadata.c
> index 6db3b5555a22..c63a70a54075 100644
> --- a/tools/testing/selftests/bpf/xdp_hw_metadata.c
> +++ b/tools/testing/selftests/bpf/xdp_hw_metadata.c
> @@ -8,6 +8,7 @@
>   * - Metadata verified:
>   *   - rx_timestamp
>   *   - rx_hash
> + *   - rx_checksum
>   *
>   * TX:
>   * - UDP 9091 packets trigger TX reply
> @@ -219,6 +220,30 @@ static void print_vlan_tci(__u16 tag)
>  	printf("PCP=%u, DEI=%d, VID=0x%X\n", pcp, dei, vlan_id);  }
> 
> +static void print_rx_cksum(__u8 ip_summed, __u32 cksum, __u8
> +cksum_level) {
> +	const char *cksum_str;
> +
> +	switch (ip_summed) {
> +	case XDP_CHECKSUM_COMPLETE | XDP_CHECKSUM_UNNECESSARY:
> +		cksum_str = "CHECKSUM_COMPLETE,CHECKSUM_UNNECESSARY";
> +		break;
> +	case XDP_CHECKSUM_UNNECESSARY:
> +		cksum_str = "CHECKSUM_UNNECESSARY";
> +		break;
> +	case XDP_CHECKSUM_COMPLETE:
> +		cksum_str = "CHECKSUM_COMPLETE";
> +		break;
> +	case XDP_CHECKSUM_NONE:
> +	default:
> +		cksum_str = "CHECKSUM_NONE";
> +		break;
> +	}
> +
> +	printf("rx-cksum: %s, csum=0x%x, cksum_level=0x%x\n",
> +	       cksum_str, cksum, cksum_level); }
> +
>  static void verify_xdp_metadata(void *data, clockid_t clock_id)  {
>  	struct xdp_meta *meta;
> @@ -254,6 +279,12 @@ static void verify_xdp_metadata(void *data,
> clockid_t clock_id)
>  		printf("No rx_vlan_tci or rx_vlan_proto, err=%d\n",
>  		       meta->rx_vlan_tag_err);
>  	}
> +
> +	if (meta->hint_valid & XDP_META_FIELD_CHECKSUM)
> +		print_rx_cksum(meta->ip_summed, meta->cksum,
> +			       meta->cksum_level);
> +	else
> +		printf("No rx_cksum, err=%d\n", meta->rx_cksum_err);
>  }
> 
>  static void verify_skb_metadata(int fd) diff --git
> a/tools/testing/selftests/bpf/xdp_metadata.h
> b/tools/testing/selftests/bpf/xdp_metadata.h
> index bca09b94af26..f864d4a8bd8c 100644
> --- a/tools/testing/selftests/bpf/xdp_metadata.h
> +++ b/tools/testing/selftests/bpf/xdp_metadata.h
> @@ -28,6 +28,7 @@ enum xdp_meta_field {
>  	XDP_META_FIELD_TS	= BIT(0),
>  	XDP_META_FIELD_RSS	= BIT(1),
>  	XDP_META_FIELD_VLAN_TAG	= BIT(2),
> +	XDP_META_FIELD_CHECKSUM = BIT(3),
>  };
> 
>  #define XDP_CHECKSUM_NONE		BIT(0)
> @@ -52,10 +53,13 @@ struct xdp_meta {
>  		};
>  		__s32 rx_vlan_tag_err;
>  	};
> -	struct {
> -		__u32 ip_summed;
> -		__u32 cksum;
> -		__u8 cksum_level;
> +	union {
> +		struct {
> +			__u32 ip_summed;
> +			__u32 cksum;
> +			__u8 cksum_level;
> +		};
> +		__s32 rx_cksum_err;
>  	};
>  	enum xdp_meta_field hint_valid;
>  };
> --
> 2.47.0

Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>

^ permalink raw reply

* RE: [PATCH bpf-next v4 6/6] selftests: drv-net: add XDP RX checksum metadata tests
From: Loktionov, Aleksandr @ 2026-07-10 10:12 UTC (permalink / raw)
  To: Vladimir Vdovin, Lorenzo Bianconi, Donald Hunter, Jakub Kicinski,
	David S . Miller, Eric Dumazet, Paolo Abeni, Simon Horman,
	Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer,
	John Fastabend, Stanislav Fomichev, Andrew Lunn,
	Nguyen, Anthony L, Kitszel, Przemyslaw, Lobakin, Aleksander,
	Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman, Song Liu,
	Yonghong Song, KP Singh, Hao Luo, Jiri Olsa, Shuah Khan,
	Fijalkowski, Maciej
  Cc: Jakub Sitnicki, netdev@vger.kernel.org, bpf@vger.kernel.org,
	intel-wired-lan@lists.osuosl.org, linux-kselftest@vger.kernel.org
In-Reply-To: <20260708203410.45121-7-deliran@verdict.gg>



> -----Original Message-----
> From: Vladimir Vdovin <deliran@verdict.gg>
> Sent: Wednesday, July 8, 2026 10:34 PM
> To: Lorenzo Bianconi <lorenzo@kernel.org>; Donald Hunter
> <donald.hunter@gmail.com>; Jakub Kicinski <kuba@kernel.org>; David S .
> Miller <davem@davemloft.net>; Eric Dumazet <edumazet@google.com>;
> Paolo Abeni <pabeni@redhat.com>; Simon Horman <horms@kernel.org>;
> Alexei Starovoitov <ast@kernel.org>; Daniel Borkmann
> <daniel@iogearbox.net>; Jesper Dangaard Brouer <hawk@kernel.org>; John
> Fastabend <john.fastabend@gmail.com>; Stanislav Fomichev
> <sdf@fomichev.me>; Andrew Lunn <andrew+netdev@lunn.ch>; Nguyen,
> Anthony L <anthony.l.nguyen@intel.com>; Kitszel, Przemyslaw
> <przemyslaw.kitszel@intel.com>; Lobakin, Aleksander
> <aleksander.lobakin@intel.com>; Andrii Nakryiko <andrii@kernel.org>;
> Martin KaFai Lau <martin.lau@linux.dev>; Eduard Zingerman
> <eddyz87@gmail.com>; Song Liu <song@kernel.org>; Yonghong Song
> <yonghong.song@linux.dev>; KP Singh <kpsingh@kernel.org>; Hao Luo
> <haoluo@google.com>; Jiri Olsa <jolsa@kernel.org>; Shuah Khan
> <shuah@kernel.org>; Fijalkowski, Maciej <maciej.fijalkowski@intel.com>
> Cc: Jakub Sitnicki <jakub@cloudflare.com>; Loktionov, Aleksandr
> <aleksandr.loktionov@intel.com>; netdev@vger.kernel.org;
> bpf@vger.kernel.org; intel-wired-lan@lists.osuosl.org; linux-
> kselftest@vger.kernel.org; Vladimir Vdovin <deliran@verdict.gg>
> Subject: [PATCH bpf-next v4 6/6] selftests: drv-net: add XDP RX
> checksum metadata tests
> 
> Extend the xdp_metadata.py driver test with coverage for
> bpf_xdp_metadata_rx_checksum().
> 
> Add an xdp_rx_csum program to xdp_metadata.bpf.o that reads the RX
> checksum verdict and stores the ip_summed bitmask, the hw checksum
> value and the checksum level into a map.  The L4 port/protocol filter
> is the same as in the existing xdp_rss_hash program, so move it into a
> common helper.
> 
> The new cases only run on devices whose driver implements the
> xmo_rx_checksum callback, detected through the "checksum" bit of the
> xdp-rx-metadata-features netlink attribute; on other devices they
> report SKIP:
> 
>  - xdp_rx_csum_valid (tcp/udp variants): traffic with a correct
>    checksum sent from the remote endpoint must be reported with a
>    usable verdict, i.e. CHECKSUM_UNNECESSARY and/or CHECKSUM_COMPLETE.
>    CHECKSUM_NONE is a legitimate verdict for a device that does not
>    verify the packets (e.g. veth reports it for locally generated
>    CHECKSUM_PARTIAL traffic), so it results in SKIP rather than in a
>    failure;
> 
>  - xdp_rx_csum_invalid: UDP packets with a corrupted L4 checksum
>    (sent with the net/lib csum tool) must not be reported as
>    CHECKSUM_UNNECESSARY.
> 
> Signed-off-by: Vladimir Vdovin <deliran@verdict.gg>
> ---
>  .../selftests/drivers/net/hw/xdp_metadata.py  | 110 +++++++++++++++++
>  .../selftests/net/lib/xdp_metadata.bpf.c      | 112 ++++++++++++++++-
> -
>  2 files changed, 209 insertions(+), 13 deletions(-)
> 
> diff --git a/tools/testing/selftests/drivers/net/hw/xdp_metadata.py
> b/tools/testing/selftests/drivers/net/hw/xdp_metadata.py
> index 33a1985356d9..1a623771477b 100644
> --- a/tools/testing/selftests/drivers/net/hw/xdp_metadata.py
> +++ b/tools/testing/selftests/drivers/net/hw/xdp_metadata.py
> @@ -8,6 +8,8 @@ These tests load device-bound XDP programs from
> xdp_metadata.bpf.o  that call metadata kfuncs, send traffic, and
> verify the extracted  metadata via BPF maps.
>  """
> +import time
> +
>  from lib.py import ksft_run, ksft_eq, ksft_exit, ksft_ge, ksft_ne,
> ksft_pr  from lib.py import KsftNamedVariant, ksft_variants  from
> lib.py import CmdExitFailure, KsftSkipEx, NetDrvEpEnv @@ -81,8 +83,22
> @@ _RSS_KEY_TYPE = 1  _RSS_KEY_PKT_CNT = 2  _RSS_KEY_ERR_CNT = 3
> 
> +_CSUM_KEY_IP_SUMMED = 0
> +_CSUM_KEY_CKSUM = 1
> +_CSUM_KEY_LEVEL = 2
> +_CSUM_KEY_PKT_CNT = 3
> +_CSUM_KEY_ERR_CNT = 4
> +
>  XDP_RSS_L4 = 0x8  # BIT(3) from enum xdp_rss_hash_type
> 
> +# Mirror of enum xdp_checksum from include/net/xdp.h
> XDP_CHECKSUM_NONE
> += 0x1 XDP_CHECKSUM_UNNECESSARY = 0x2 XDP_CHECKSUM_COMPLETE = 0x4
> +
> +# Fixed destination port of the net/lib csum tool _CSUM_TOOL_PORT =
> +34000
> +
> 
>  @ksft_variants([
>      KsftNamedVariant("tcp", "tcp"),
> @@ -130,6 +146,98 @@ def test_xdp_rss_hash(cfg, proto):
>              f"RSS hash type should include L4 for {proto.upper()}
> traffic")
> 
> 

...

>  char _license[] SEC("license") = "GPL";
> --
> 2.47.0

Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>

^ permalink raw reply

* Re: [PATCH net v2] gve: fix Rx queue stall on alloc failure
From: Maciej Fijalkowski @ 2026-07-10 10:13 UTC (permalink / raw)
  To: Harshitha Ramamurthy
  Cc: netdev, joshwash, andrew+netdev, davem, edumazet, kuba, pabeni,
	willemb, jordanrhee, nktgrg, maolson, thostet, csully, bcf,
	linux-kernel, stable, Eddie Phillips
In-Reply-To: <20260709211906.3322883-1-hramamurthy@google.com>

On Thu, Jul 09, 2026 at 09:19:06PM +0000, Harshitha Ramamurthy wrote:
> From: Eddie Phillips <eddiephillips@google.com>
> 
> When the system is under extreme memory pressure, page allocations can
> fail during the Rx buffer refill loop. If the number of buffers posted
> to hardware falls below a critical low threshold and the refill loop
> exits due to allocation failures, the queue can stall:
> 
> 1. The device drops incoming packets because there are no descriptors.
> 2. Since no packets are processed, no Rx completions are generated.
> 3. Because no completions occur, NAPI is never scheduled, preventing
>    the refill loop from running again even after memory is freed.
> 
> This results in a permanent queue stall.
> 
> Resolve this by introducing a starvation recovery timer for each Rx queue.
> If the number of buffers posted to hardware falls below a critical low
> threshold, start a timer to periodically reschedule NAPI. Once NAPI runs
> and successfully refills the queue above the threshold, the timer is
> not rescheduled.
> 
> The threshold is set to 32 because a single maximum-sized Receive Segment
> Coalescing (RSC) packet can consume up to 19 descriptors in the Rx path.
> Lower thresholds (such as 8 or 16) would be insufficient to process a
> complete maximum-sized RSC packet, risking packet drops or unexpected
> hardware behavior under memory pressure. Setting the threshold to 32
> guarantees a safe margin to handle at least one full RSC packet.
> 
> Cc: stable@vger.kernel.org
> Fixes: 9b8dd5e5ea48 ("gve: DQO: Add RX path")
> Reviewed-by: Jordan Rhee <jordanrhee@google.com>
> Signed-off-by: Eddie Phillips <eddiephillips@google.com>
> Signed-off-by: Harshitha Ramamurthy <hramamurthy@google.com>
> ---
> Changes in v2:
> - Link to v1: https://lore.kernel.org/netdev/20260701005341.3699161-1-hramamurthy@google.com/
> - Relocated the starvation timer to the end of gve_rx_ring to avoid polluting
> hotpath cachelines
> - Decoupled timer lifecycle from allocation cycles by moving initialization
> and shutdown to start/stop pathways instead of setup/remove pathways.
> - Added explicit rationale for the 32-descriptor threshold
> (GVE_RX_BUF_THRESH_DQO) ensuring it is safe for maximum-sized RSC packets.
> - Removed addition of a stat tracking critical low buffer events
> 
>  drivers/net/ethernet/google/gve/gve.h        |  3 +++
>  drivers/net/ethernet/google/gve/gve_rx_dqo.c | 34 ++++++++++++++++++++++++++++++++++
>  2 files changed, 37 insertions(+)
> 

[...]

>  	rx->fill_cnt += num_posted;
> +
> +	/* If the queue has fewer than GVE_RX_BUF_THRESH_DQO descriptors
> +	 * visible to the hardware, the hardware is in danger of starving
> +	 * and cannot trigger interrupts.
> +	 *
> +	 * We use a threshold of 32 because a single maximum-sized RSC
> +	 * packet can consume up to 19 descriptors in the Rx path. Lower
> +	 * thresholds (e.g., 8 or 16) would be unsafe as they could cause
> +	 * the device to drop/stall on a maximum-sized RSC packet.
> +	 *
> +	 * Start the timer to periodically reschedule NAPI and recover.
> +	 */
> +	num_bufs_avail_to_hw =
> +		((bufq->tail & ~(GVE_RX_BUF_THRESH_DQO - 1)) -
> +		 bufq->head) & bufq->mask;
> +
> +	if (num_bufs_avail_to_hw < GVE_RX_BUF_THRESH_DQO) {
> +		mod_timer(&rx->starvation_timer,
> +			  jiffies + msecs_to_jiffies(GVE_RX_NAPI_RESCHED_MS));
> +	}

nit: redundant braces

>  }
>  
>  static void gve_rx_skb_csum(struct sk_buff *skb,
> -- 
> 2.55.0.795.g602f6c329a-goog
> 

^ permalink raw reply

* Re: [PATCH net v1 3/3] net: hibmcge: fix double-free of tx skb on DMA mapping failure
From: Jijie Shao @ 2026-07-10 10:15 UTC (permalink / raw)
  To: xuanqiang.luo, netdev
  Cc: shaojijie, Xuanqiang Luo, Jian Shen, Andrew Lunn,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	linux-kernel, stable
In-Reply-To: <20260710090527.58354-4-xuanqiang.luo@linux.dev>


on 2026/7/10 17:05, xuanqiang.luo@linux.dev wrote:
> From: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
>
> If hbg_dma_map() fails, hbg_net_start_xmit() frees the skb, but buffer->skb
> is left pointing to it. ring->ntu is not advanced, so the buffer is not
> visible to the TX cleanup path.
>
> A subsequent transmit normally overwrites the buffer. However, if the
> interface is brought down first, hbg_ring_uninit() calls hbg_buffer_free().
> It sees the stale pointer, attempts to unmap the failed mapping, and frees
> the skb again.
>
> Clear buffer->skb before freeing the skb in the error path, preventing
> hbg_buffer_free() from treating it as an outstanding TX buffer.
>
> Fixes: 40735e7543f9 ("net: hibmcge: Implement .ndo_start_xmit function")
> Cc: stable@vger.kernel.org
> Assisted-by: Opencode:deepseek-v4-pro[1m]
> Signed-off-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>

Thanks for fixing this. The patch looks good to me.

Reviewed-by: Jijie Shao <shaojijie@huawei.com>

> ---
>   drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c | 1 +
>   1 file changed, 1 insertion(+)
>
> diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c b/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c
> index 0ae3149946769..4382af937e2e7 100644
> --- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c
> +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c
> @@ -155,6 +155,7 @@ netdev_tx_t hbg_net_start_xmit(struct sk_buff *skb, struct net_device *netdev)
>   	buffer->skb = skb;
>   	buffer->skb_len = skb->len;
>   	if (unlikely(hbg_dma_map(buffer))) {
> +		buffer->skb = NULL;
>   		dev_kfree_skb_any(skb);
>   		return NETDEV_TX_OK;
>   	}

^ permalink raw reply

* Re: [PATCH net-next v7 1/2] net: libwx: add support for set_ringparam in wx_ethtool_ops_vf
From: Przemek Kitszel @ 2026-07-10 10:19 UTC (permalink / raw)
  To: Mengyuan Lou; +Cc: jiawenwu, duanqiangwen, netdev, horms, kuba, pabeni
In-Reply-To: <20260710015925.34769-2-mengyuanlou@net-swift.com>

On 7/10/26 03:59, Mengyuan Lou wrote:
> Add support for the set_ringparam in wx_ethtool_ops_vf,
> which is used to set ring sizes for ngbevf and txgbevf.
> 
> Signed-off-by: Mengyuan Lou <mengyuanlou@net-swift.com>
> ---
>   .../net/ethernet/wangxun/libwx/wx_ethtool.c   | 61 +++++++++++++++++++
>   drivers/net/ethernet/wangxun/libwx/wx_lib.c   |  9 +--
>   drivers/net/ethernet/wangxun/libwx/wx_lib.h   |  4 +-
>   .../net/ethernet/wangxun/libwx/wx_vf_common.c |  4 +-
>   .../net/ethernet/wangxun/libwx/wx_vf_common.h |  2 +
>   5 files changed, 72 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
> index 5df971aca9e3..eae038df6875 100644
> --- a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
> +++ b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
> @@ -9,6 +9,7 @@
>   #include "wx_ethtool.h"
>   #include "wx_hw.h"
>   #include "wx_lib.h"
> +#include "wx_vf_common.h"
>   
>   struct wx_stats {
>   	char stat_string[ETH_GSTRING_LEN];
> @@ -775,6 +776,65 @@ static int wx_get_link_ksettings_vf(struct net_device *netdev,
>   	return 0;
>   }
>   
> +static int wx_set_ringparam_vf(struct net_device *netdev,
> +			       struct ethtool_ringparam *ring,
> +			       struct kernel_ethtool_ringparam *kernel_ring,
> +			       struct netlink_ext_ack *extack)
> +{
> +	struct wx *wx = netdev_priv(netdev);
> +	u32 new_rx_count, new_tx_count;
> +	struct wx_ring *temp_ring;
> +	int i, err = 0;
> +
> +	new_tx_count = clamp_t(u32, ring->tx_pending, WX_MIN_TXD, WX_MAX_TXD);
> +	new_tx_count = ALIGN(new_tx_count, WX_REQ_TX_DESCRIPTOR_MULTIPLE);
> +
> +	new_rx_count = clamp_t(u32, ring->rx_pending, WX_MIN_RXD, WX_MAX_RXD);
> +	new_rx_count = ALIGN(new_rx_count, WX_REQ_RX_DESCRIPTOR_MULTIPLE);
> +
> +	if (new_tx_count == wx->tx_ring_count &&
> +	    new_rx_count == wx->rx_ring_count)
> +		return 0;
> +
> +	mutex_lock(&wx->reset_lock);
> +	set_bit(WX_STATE_RESETTING, wx->state);
> +
> +	if (!netif_running(wx->netdev)) {
> +		for (i = 0; i < wx->num_tx_queues; i++)
> +			wx->tx_ring[i]->count = new_tx_count;
> +		for (i = 0; i < wx->num_rx_queues; i++)
> +			wx->rx_ring[i]->count = new_rx_count;
> +		wx->tx_ring_count = new_tx_count;
> +		wx->rx_ring_count = new_rx_count;
> +
> +		goto clear_reset;
> +	}
> +
> +	/* allocate temporary buffer to store rings in */
> +	i = max_t(int, wx->num_tx_queues, wx->num_rx_queues);
> +	temp_ring = kvmalloc_objs(struct wx_ring, i);
> +	if (!temp_ring) {
> +		err = -ENOMEM;
> +		goto clear_reset;
> +	}

would be much better to move tempbuf allocation into the helper,
and just do it at the beginning there

in the unlikely event of -ENOMEM, you will just call the "up"
in the unroll path

> +
> +	wxvf_down(wx);
> +	/* wx_set_ring() may partially apply changes before
> +	 * returning an error. The error indicates that not all
> +	 * requested ring parameters could be configured.
> +	 */
> +	err = wx_set_ring(wx, new_tx_count, new_rx_count, temp_ring);
> +	if (err)
> +		wx_err(wx, "failed to set ring parameters: %d", err);
> +	wx_configure_vf(wx);
> +	wxvf_up_complete(wx);
> +	kvfree(temp_ring);
> +clear_reset:
> +	clear_bit(WX_STATE_RESETTING, wx->state);
> +	mutex_unlock(&wx->reset_lock);
> +	return err;
> +}


^ permalink raw reply

* Re: [PATCH net-next v7 2/2] net: libwx: add support for set_coalesce in wx_ethtool_ops_vf
From: Przemek Kitszel @ 2026-07-10 10:24 UTC (permalink / raw)
  To: Mengyuan Lou; +Cc: jiawenwu, duanqiangwen, netdev, horms, kuba, pabeni
In-Reply-To: <20260710015925.34769-3-mengyuanlou@net-swift.com>

On 7/10/26 03:59, Mengyuan Lou wrote:
> Add support for set_coalesce in wx_ethtool_ops_vf, which
> is used to set interrupt coalescing parameters.
> 
> Update wx_write_eitr_vf() to use the same interrupt
> moderation encoding as PF devices, since PF and VF share
> the same register layout. And remove the now-unused
> WX_VXITR_MASK definition.
> 
> Signed-off-by: Mengyuan Lou <mengyuanlou@net-swift.com>
> ---
>   drivers/net/ethernet/wangxun/libwx/wx_ethtool.c |  7 ++++++-
>   drivers/net/ethernet/wangxun/libwx/wx_vf.h      |  1 -
>   drivers/net/ethernet/wangxun/libwx/wx_vf_lib.c  | 13 ++++++++++++-
>   3 files changed, 18 insertions(+), 3 deletions(-)

looks good,
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>

^ permalink raw reply

* Re: [PATCH net v3] tipc: fix u16 MTU truncation in media and bearer MTU validation
From: Vadim Fedorenko @ 2026-07-10 10:41 UTC (permalink / raw)
  To: Cen Zhang (Microsoft), jmaloy, davem, edumazet, kuba, pabeni,
	horms
  Cc: netdev, tipc-discussion, linux-kernel, tung.quang.nguyen,
	AutonomousCodeSecurity, tgopinath, kys
In-Reply-To: <20260708180212.2898-1-blbllhy@gmail.com>

On 08/07/2026 19:02, Cen Zhang (Microsoft) wrote:
> Both TIPC_NL_MEDIA_SET and TIPC_NL_BEARER_SET accept user-supplied
> MTU values but only enforce a minimum bound, not a maximum. When a user
> sets the MTU to a value exceeding U16_MAX (65535), it passes validation
> but is silently truncated when assigned to u16 fields l->mtu and
> l->advertised_mtu in tipc_link_create(). Values like 65536 (0x10000)
> truncate to 0, causing a division by zero in tipc_link_set_queue_limits()
> which computes TIPC_MAX_PUBL / (l->mtu / ITEM_SIZE). Other overflowing
> values (e.g. 65537-131071) produce small incorrect MTU values, resulting
> in link malfunction behaviors.
> 
> Crash stack (triggered as unprivileged user via user namespace):
> 
>    tipc_link_set_queue_limits  net/tipc/link.c:2531
>    tipc_link_create            net/tipc/link.c:520
>    tipc_node_check_dest        net/tipc/node.c:1279
>    tipc_disc_rcv               net/tipc/discover.c:252
>    tipc_rcv                    net/tipc/node.c:2129
>    tipc_udp_recv               net/tipc/udp_media.c:392
> 
> Two independent paths lack the upper bound check:
> 1. tipc_udp_mtu_bad() -- called from __tipc_nl_media_set() (MEDIA_SET)
> 2. inline check in __tipc_nl_bearer_set() at bearer.c:1160 (BEARER_SET)
> 
> Fix both by rejecting MTU values above U16_MAX.
> 
> Fixes: 901271e0403a ("tipc: implement configuration of UDP media MTU")
> Reported-by: AutonomousCodeSecurity@microsoft.com
> Closes: https://lore.kernel.org/all/CAB8m9WgETt0AjmFwE=F-CKjGXsK6_WDv0=kbYRcC8-noo+amnA@mail.gmail.com
> Signed-off-by: Cen Zhang (Microsoft) <blbllhy@gmail.com>
> ---
> v3: Use nla_policy check to limit MTU max value as suggested by Vadim
> v2: Solved format issue
> Link: https://lore.kernel.org/all/CAB8m9WgETt0AjmFwE=F-CKjGXsK6_WDv0=kbYRcC8-noo+amnA@mail.gmail.com
> 
>   net/tipc/netlink.c | 6 +++++-
>   1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
> index 8336a9664703..1307dd1a9613 100644
> --- a/net/tipc/netlink.c
> +++ b/net/tipc/netlink.c
> @@ -113,12 +113,16 @@ const struct nla_policy tipc_nl_node_policy[TIPC_NLA_NODE_MAX + 1] = {
>   };
>   
>   /* Properties valid for media, bearer and link */
> +static const struct netlink_range_validation tipc_nl_mtu_range = {
> +	.max = U16_MAX,
> +};
> +
>   const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = {
>   	[TIPC_NLA_PROP_UNSPEC]		= { .type = NLA_UNSPEC },
>   	[TIPC_NLA_PROP_PRIO]		= { .type = NLA_U32 },
>   	[TIPC_NLA_PROP_TOL]		= { .type = NLA_U32 },
>   	[TIPC_NLA_PROP_WIN]		= { .type = NLA_U32 },
> -	[TIPC_NLA_PROP_MTU]		= { .type = NLA_U32 },
> +	[TIPC_NLA_PROP_MTU]		= NLA_POLICY_FULL_RANGE(NLA_U32, &tipc_nl_mtu_range),
>   	[TIPC_NLA_PROP_BROADCAST]	= { .type = NLA_U32 },
>   	[TIPC_NLA_PROP_BROADCAST_RATIO]	= { .type = NLA_U32 }
>   };

Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>

^ permalink raw reply

* Re: [PATCH net v2] net: hip04: fix tx coalesce timer and IRQ teardown races
From: Przemek Kitszel @ 2026-07-10 10:43 UTC (permalink / raw)
  To: Fan Wu
  Cc: shenjian15, netdev, salil.mehta, dingtianhong, horms,
	andrew+netdev, davem, edumazet, kuba, pabeni, linux-kernel,
	stable
In-Reply-To: <20260710015730.630775-1-fanwu01@zju.edu.cn>

On 7/10/26 03:57, Fan Wu wrote:
> The hip04 remove path frees the TX/RX rings before unregistering the
> netdev. If the interface is still up, unregister_netdev() then runs
> .ndo_stop, whose TX reclaim and NAPI poll touch the already-freed DMA
> ring memory. The TX coalesce timer and the platform IRQ also outlive
> the netdev private data they dereference.
> 
> Reorder hip04_remove() so the netdev is unregistered (which runs .ndo_stop
> synchronously, stopping NAPI and the TX queue) before the rings are freed.
> Free the devm-managed IRQ explicitly before free_netdev(), so
> hip04_mac_interrupt() (whose dev_id is the netdev) cannot fire against
> freed memory: devm would otherwise release it only after .remove returns.
> 
> hip04_mac_stop() must quiesce both arming sites of the coalesce timer.
> The NAPI poll arms it, and napi_disable() returns once the poll calls
> napi_complete_done(), not when the poll function returns, so move that
> arm before napi_complete_done(). 

> The existing early exits that jump to
> done do not call napi_complete_done(), so they remain outside the
> completion-after-arm window this change closes. 

this particular sentence is hard to read, as you use AI, would be good
to rephrase

> The TX xmit path also

s/Tx xmit/Tx/

> arms it, and mac_stop() is reached directly from hip04_tx_timeout_task()
> as well as via .ndo_stop, so use netif_tx_disable() rather than
> netif_stop_queue() to wait for an in-flight hip04_mac_start_xmit() to
> finish.  The timer is then drained with hrtimer_cancel().  A "closing"
> flag, checked at the single arming site, guards against a later arm.
> 
> hip04_tx_timeout_task() restarts the device with mac_stop() + mac_open();
> serialize that restart against .ndo_stop with rtnl_lock(), matching the

given the direction to reduce RTNL usage I see no point adding more
usage in the driver
perhaps netdev_lock() will be sufficient?

> netdev core's locking, skip it if the device is no longer running, and
> emit an error if the restart fails instead of silently leaving it down.
> 
> This issue was found by an in-house static analysis tool.

Thank you for detailed description, I get from that what the bug is,
what is the fix, and agree in principle with all of that.

> 
> Fixes: a41ea46a9a12 ("net: hisilicon: new hip04 ethernet driver")
> Cc: stable@vger.kernel.org
> Assisted-by: Codex:gpt-5.5
> Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>


^ permalink raw reply

* [PATCH iwl-next v1 0/2] Implement ixgbe PCI reset
From: Sergey Temerkhanov @ 2026-07-10 10:54 UTC (permalink / raw)
  To: intel-wired-lan; +Cc: netdev

This series adds an ability to properly perform PCI level reset
via sysfs to the ixgbe driver.

To achieve this, several operation handlers are refactored to
check whether the netdev is available during the invocation, and
the actual reset handlers are implemented which prepare the device
for the reset and re-initialize it afterwards.

Sergey Temerkhanov (2):
  ixgbe: Refactor device operations to check whether netdev is available
  ixgbe: Implement PCI reset handler

 drivers/net/ethernet/intel/ixgbe/ixgbe.h      |   5 +
 .../net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c   |  13 +-
 .../net/ethernet/intel/ixgbe/ixgbe_ethtool.c  |  34 ++++--
 drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c |  20 +++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 112 ++++++++++++++++--
 drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c  |   4 +-
 6 files changed, 159 insertions(+), 29 deletions(-)

-- 
2.53.0


^ permalink raw reply

* [PATCH iwl-next v1 1/2] ixgbe: Refactor device operations to check whether netdev is available
From: Sergey Temerkhanov @ 2026-07-10 10:54 UTC (permalink / raw)
  To: intel-wired-lan; +Cc: netdev
In-Reply-To: <20260710105403.1050025-1-sergey.temerkhanov@intel.com>

Refactor several ixgbe driver operations to check whether the
netdev they operate on is enabled. This will allow the system
to get synchronized, for example, during the PCI resets.

Signed-off-by: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h      |  5 +++
 .../net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c   | 13 +++++--
 .../net/ethernet/intel/ixgbe/ixgbe_ethtool.c  | 34 ++++++++++++-------
 drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c | 20 ++++++++---
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 22 +++++++-----
 drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c  |  4 +--
 6 files changed, 69 insertions(+), 29 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 594ccb28da20..e801433c5db8 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -955,6 +955,11 @@ extern char ixgbe_driver_name[];
 extern char ixgbe_default_device_descr[];
 #endif /* IXGBE_FCOE */
 
+static inline bool ixgbe_netif_running(struct net_device *netdev)
+{
+	return netif_running(netdev) && netif_device_present(netdev);
+}
+
 int ixgbe_open(struct net_device *netdev);
 int ixgbe_close(struct net_device *netdev);
 void ixgbe_up(struct ixgbe_adapter *adapter);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
index 382d097e4b11..7c7408d32742 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
@@ -277,17 +277,23 @@ static void ixgbe_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority,
 static void ixgbe_dcbnl_devreset(struct net_device *dev)
 {
 	struct ixgbe_adapter *adapter = ixgbe_from_netdev(dev);
+	bool running;
+
+	if (!netif_device_present(dev))
+		return;
+
+	running = ixgbe_netif_running(dev);
 
 	while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
 		usleep_range(1000, 2000);
 
-	if (netif_running(dev))
+	if (running)
 		dev->netdev_ops->ndo_stop(dev);
 
 	ixgbe_clear_interrupt_scheme(adapter);
 	ixgbe_init_interrupt_scheme(adapter);
 
-	if (netif_running(dev))
+	if (running)
 		dev->netdev_ops->ndo_open(dev);
 
 	clear_bit(__IXGBE_RESETTING, &adapter->state);
@@ -515,6 +521,9 @@ static int ixgbe_dcbnl_ieee_setets(struct net_device *dev,
 	if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
 		return -EINVAL;
 
+	if (!netif_device_present(dev))
+		return -ENETDOWN;
+
 	if (!adapter->ixgbe_ieee_ets) {
 		adapter->ixgbe_ieee_ets = kmalloc_obj(struct ieee_ets);
 		if (!adapter->ixgbe_ieee_ets)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index 36e43b5e88d1..02aff411426d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -466,6 +466,9 @@ static int ixgbe_set_link_ksettings(struct net_device *netdev,
 	u32 advertised, old;
 	int err = 0;
 
+	if (!netif_device_present(netdev))
+		return -ENETDOWN;
+
 	if ((hw->phy.media_type == ixgbe_media_type_copper) ||
 	    (hw->phy.multispeed_fiber)) {
 		/*
@@ -576,9 +579,9 @@ static void ixgbe_set_pauseparam_finalize(struct net_device *netdev,
 	/* If the thing changed then we'll update and use new autoneg. */
 	if (memcmp(fc, &hw->fc, sizeof(*fc))) {
 		hw->fc = *fc;
-		if (netif_running(netdev))
+		if (ixgbe_netif_running(netdev))
 			ixgbe_reinit_locked(adapter);
-		else
+		else if (netif_device_present(netdev))
 			ixgbe_reset(adapter);
 	}
 }
@@ -1266,7 +1269,7 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
 	while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
 		usleep_range(1000, 2000);
 
-	if (!netif_running(adapter->netdev)) {
+	if (!ixgbe_netif_running(adapter->netdev)) {
 		for (i = 0; i < adapter->num_tx_queues; i++)
 			adapter->tx_ring[i]->count = new_tx_count;
 		for (i = 0; i < adapter->num_xdp_queues; i++)
@@ -2249,10 +2252,11 @@ static void ixgbe_diag_test(struct net_device *netdev,
 			    struct ethtool_test *eth_test, u64 *data)
 {
 	struct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);
-	bool if_running = netif_running(netdev);
+	bool if_running = ixgbe_netif_running(netdev);
 
-	if (ixgbe_removed(adapter->hw.hw_addr)) {
-		e_err(hw, "Adapter removed - test blocked\n");
+	if (ixgbe_removed(adapter->hw.hw_addr) ||
+	    !netif_device_present(netdev)) {
+		e_err(hw, "Adapter removed or detached - test blocked\n");
 		data[0] = 1;
 		data[1] = 1;
 		data[2] = 1;
@@ -2466,7 +2470,7 @@ static int ixgbe_nway_reset(struct net_device *netdev)
 {
 	struct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);
 
-	if (netif_running(netdev))
+	if (ixgbe_netif_running(netdev))
 		ixgbe_reinit_locked(adapter);
 
 	return 0;
@@ -2650,7 +2654,8 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
 		else
 			/* rx only or mixed */
 			q_vector->itr = rx_itr_param;
-		ixgbe_write_eitr(q_vector);
+		if (netif_device_present(netdev))
+			ixgbe_write_eitr(q_vector);
 	}
 
 	/*
@@ -3694,6 +3699,9 @@ static int ixgbe_set_eee_e610(struct net_device *netdev,
 	    kedata->eee_enabled)
 		return -EOPNOTSUPP;
 
+	if (!netif_device_present(netdev))
+		return -ENETDOWN;
+
 	hw->phy.eee_speeds_advertised = kedata->eee_enabled ?
 					hw->phy.eee_speeds_supported : 0;
 
@@ -3709,9 +3717,9 @@ static int ixgbe_set_eee_e610(struct net_device *netdev,
 	else
 		adapter->flags2 &= ~IXGBE_FLAG2_EEE_ENABLED;
 
-	if (netif_running(netdev))
+	if (ixgbe_netif_running(netdev))
 		ixgbe_reinit_locked(adapter);
-	else
+	else if (netif_device_present(netdev))
 		ixgbe_reset(adapter);
 
 	return 0;
@@ -3793,9 +3801,9 @@ static int ixgbe_set_eee(struct net_device *netdev, struct ethtool_keee *edata)
 	}
 
 	/* reset link */
-	if (netif_running(netdev))
+	if (ixgbe_netif_running(netdev))
 		ixgbe_reinit_locked(adapter);
-	else
+	else if (netif_device_present(netdev))
 		ixgbe_reset(adapter);
 
 	return 0;
@@ -3851,7 +3859,7 @@ static int ixgbe_set_priv_flags(struct net_device *netdev, u32 priv_flags)
 		adapter->flags2 = flags2;
 
 		/* reset interface to repopulate queues */
-		if (netif_running(netdev))
+		if (ixgbe_netif_running(netdev))
 			ixgbe_reinit_locked(adapter);
 	}
 
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
index e338ff0e6522..a22c20c73cdc 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
@@ -853,6 +853,10 @@ int ixgbe_fcoe_enable(struct net_device *netdev)
 {
 	struct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);
 	struct ixgbe_fcoe *fcoe = &adapter->fcoe;
+	bool running;
+
+	if (!netif_device_present(netdev))
+		return -ENETDOWN;
 
 	atomic_inc(&fcoe->refcnt);
 
@@ -862,12 +866,14 @@ int ixgbe_fcoe_enable(struct net_device *netdev)
 	if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
 		return -EINVAL;
 
+	running = ixgbe_netif_running(netdev);
+
 	e_info(drv, "Enabling FCoE offload features.\n");
 
 	if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
 		e_warn(probe, "Enabling FCoE on PF will disable legacy VFs\n");
 
-	if (netif_running(netdev))
+	if (running)
 		netdev->netdev_ops->ndo_stop(netdev);
 
 	/* Allocate per CPU memory to track DDP pools */
@@ -882,7 +888,7 @@ int ixgbe_fcoe_enable(struct net_device *netdev)
 	ixgbe_clear_interrupt_scheme(adapter);
 	ixgbe_init_interrupt_scheme(adapter);
 
-	if (netif_running(netdev))
+	if (running)
 		netdev->netdev_ops->ndo_open(netdev);
 
 	return 0;
@@ -899,6 +905,10 @@ int ixgbe_fcoe_enable(struct net_device *netdev)
 int ixgbe_fcoe_disable(struct net_device *netdev)
 {
 	struct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);
+	bool running;
+
+	if (!netif_device_present(netdev))
+		return -ENETDOWN;
 
 	if (!atomic_dec_and_test(&adapter->fcoe.refcnt))
 		return -EINVAL;
@@ -906,8 +916,10 @@ int ixgbe_fcoe_disable(struct net_device *netdev)
 	if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))
 		return -EINVAL;
 
+	running = ixgbe_netif_running(netdev);
+
 	e_info(drv, "Disabling FCoE offload features.\n");
-	if (netif_running(netdev))
+	if (running)
 		netdev->netdev_ops->ndo_stop(netdev);
 
 	/* Free per CPU memory to track DDP pools */
@@ -923,7 +935,7 @@ int ixgbe_fcoe_disable(struct net_device *netdev)
 	ixgbe_clear_interrupt_scheme(adapter);
 	ixgbe_init_interrupt_scheme(adapter);
 
-	if (netif_running(netdev))
+	if (running)
 		netdev->netdev_ops->ndo_open(netdev);
 
 	return 0;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 2ac274c73d61..42dac766c907 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -7420,7 +7420,7 @@ static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu)
 	/* must set new MTU before calling down or up */
 	WRITE_ONCE(netdev->mtu, new_mtu);
 
-	if (netif_running(netdev))
+	if (ixgbe_netif_running(netdev))
 		ixgbe_reinit_locked(adapter);
 
 	return 0;
@@ -9917,6 +9917,7 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc)
 {
 	struct ixgbe_adapter *adapter = ixgbe_from_netdev(dev);
 	struct ixgbe_hw *hw = &adapter->hw;
+	bool running = ixgbe_netif_running(dev);
 
 	/* Hardware supports up to 8 traffic classes */
 	if (tc > adapter->dcb_cfg.num_tcs.pg_tcs)
@@ -9929,7 +9930,10 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc)
 	 * match packet buffer alignment. Unfortunately, the
 	 * hardware is not flexible enough to do this dynamically.
 	 */
-	if (netif_running(dev))
+	if (!netif_device_present(dev))
+		return -ENETDOWN;
+
+	if (running)
 		ixgbe_close(dev);
 	else
 		ixgbe_reset(adapter);
@@ -9942,7 +9946,7 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc)
 			e_warn(probe, "DCB is not supported with XDP\n");
 
 			ixgbe_init_interrupt_scheme(adapter);
-			if (netif_running(dev))
+			if (running)
 				ixgbe_open(dev);
 			return -EINVAL;
 		}
@@ -9977,7 +9981,7 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc)
 
 	ixgbe_defrag_macvlan_pools(dev);
 
-	if (netif_running(dev))
+	if (running)
 		return ixgbe_open(dev);
 
 	return 0;
@@ -10503,9 +10507,9 @@ void ixgbe_do_reset(struct net_device *netdev)
 {
 	struct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);
 
-	if (netif_running(netdev))
+	if (ixgbe_netif_running(netdev))
 		ixgbe_reinit_locked(adapter);
-	else
+	else if (netif_device_present(netdev))
 		ixgbe_reset(adapter);
 }
 
@@ -10837,7 +10841,7 @@ static void *ixgbe_fwd_add(struct net_device *pdev, struct net_device *vdev)
 	accel->pool = pool;
 	accel->netdev = vdev;
 
-	if (!netif_running(pdev))
+	if (!ixgbe_netif_running(pdev))
 		return accel;
 
 	err = ixgbe_fwd_ring_up(adapter, accel);
@@ -10968,8 +10972,10 @@ static int ixgbe_xdp_setup(struct net_device *dev, struct bpf_prog *prog)
 			synchronize_rcu();
 		err = ixgbe_setup_tc(dev, adapter->hw_tcs);
 
-		if (err)
+		if (err) {
+			xchg(&adapter->xdp_prog, old_prog);
 			return -EINVAL;
+		}
 		if (!prog)
 			xdp_features_clear_redirect_target(dev);
 	} else {
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
index 89f96c463f02..02820982b202 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
@@ -39,7 +39,7 @@ static int ixgbe_xsk_pool_enable(struct ixgbe_adapter *adapter,
 	if (err)
 		return err;
 
-	if_running = netif_running(adapter->netdev) &&
+	if_running = ixgbe_netif_running(adapter->netdev) &&
 		     ixgbe_enabled_xdp_adapter(adapter);
 
 	if (if_running)
@@ -71,7 +71,7 @@ static int ixgbe_xsk_pool_disable(struct ixgbe_adapter *adapter, u16 qid)
 	if (!pool)
 		return -EINVAL;
 
-	if_running = netif_running(adapter->netdev) &&
+	if_running = ixgbe_netif_running(adapter->netdev) &&
 		     ixgbe_enabled_xdp_adapter(adapter);
 
 	if (if_running)
-- 
2.53.0


^ permalink raw reply related

* [PATCH iwl-next v1 2/2] ixgbe: Implement PCI reset handler
From: Sergey Temerkhanov @ 2026-07-10 10:54 UTC (permalink / raw)
  To: intel-wired-lan; +Cc: netdev
In-Reply-To: <20260710105403.1050025-1-sergey.temerkhanov@intel.com>

Implement PCI device reset handler to allow the network device to
get re-initialized and function after a PCI-level reset.

This is necessary for the adapter to avoid TX queue timeouts
occurring after the PCI reset is performed via sysfs during
its operation.

The reset codepath may trigger a number of dependencies in the
reset of the driver, so that it is necessary to check if
the netdev is present and running there.

Signed-off-by: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
Reviewed-by: Przemyslaw Korba <przemyslaw.korba@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 90 +++++++++++++++++++
 1 file changed, 90 insertions(+)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 42dac766c907..1865b604ace7 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -12358,6 +12358,94 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
 	return result;
 }
 
+/**
+ * ixgbe_pci_reset_prepare - called before the pci bus is reset.
+ * @pdev: Pointer to PCI device
+ *
+ * Quiesce the driver in preparation for a PCI function reset. Called from
+ * pci_dev_save_and_disable() before the core saves config state and writes
+ * PCI_COMMAND_INTX_DISABLE to clear bus mastering and MMIO decode, so MMIO
+ * access to the device is still valid here.
+ */
+static void ixgbe_pci_reset_prepare(struct pci_dev *pdev)
+{
+	struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
+	struct net_device *netdev;
+
+	if (!adapter)
+		return;
+
+	netdev = adapter->netdev;
+
+	rtnl_lock();
+	netif_device_detach(netdev);
+	if (netif_running(netdev))
+		ixgbe_close_suspend(adapter);
+	rtnl_unlock();
+
+	/* __IXGBE_RESETTING is intentionally not set here: it is spun on
+	 * while holding rtnl by ixgbe_reinit_locked(), ixgbe_dcbnl_devreset()
+	 * and the ethtool reset paths, so holding it across the rtnl drop
+	 * would deadlock those callers against ixgbe_pci_reset_done(), which
+	 * needs to re-acquire rtnl.  During the reset window concurrent
+	 * rtnl-holding paths must treat the netdev as detached, while teardown
+	 * paths also observe __IXGBE_DOWN set by ixgbe_down() via
+	 * ixgbe_close_suspend(), matching the existing ixgbe_io_error_detected()
+	 * flow.
+	 */
+
+	if (test_bit(__IXGBE_SERVICE_INITED, &adapter->state)) {
+		/* The service timer was already stopped by ixgbe_down() via
+		 * ixgbe_close_suspend(); if the netdev was not running, the
+		 * timer is not armed.  Only the currently queued service task
+		 * (if any) still needs to be flushed here.
+		 */
+		cancel_work_sync(&adapter->service_task);
+		clear_bit(__IXGBE_SERVICE_SCHED, &adapter->state);
+	}
+}
+
+/**
+ * ixgbe_pci_reset_done - called after the pci bus has been reset.
+ * @pdev: Pointer to PCI device
+ *
+ * Re-initialize the device after a PCI function reset. The PCI core has
+ * already called pci_restore_state() before invoking this callback, so the
+ * saved Command register (including bus mastering) is back in place.
+ */
+static void ixgbe_pci_reset_done(struct pci_dev *pdev)
+{
+	struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
+	struct net_device *netdev;
+	bool running;
+	int err = 0;
+
+	if (!adapter)
+		return;
+
+	netdev = adapter->netdev;
+
+	rtnl_lock();
+	adapter->hw.hw_addr = adapter->io_addr;
+	ixgbe_reset(adapter);
+	IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0);
+	running = netif_running(netdev);
+	if (running) {
+		err = ixgbe_open(netdev);
+		if (err) {
+			e_dev_err("Cannot re-open netdev after PCI reset: %d. A new reset is needed.\n",
+				  err);
+			dev_close(netdev);
+		}
+	}
+	/* Restore presence so userspace can retry later. If ixgbe_open() failed,
+	 * dev_close() cleared IFF_UP first so netif_device_attach() will not wake
+	 * Tx queues without a successful open.
+	 */
+	netif_device_attach(netdev);
+	rtnl_unlock();
+}
+
 /**
  * ixgbe_io_resume - called when traffic can start flowing again.
  * @pdev: Pointer to PCI device
@@ -12390,6 +12478,8 @@ static const struct pci_error_handlers ixgbe_err_handler = {
 	.error_detected = ixgbe_io_error_detected,
 	.slot_reset = ixgbe_io_slot_reset,
 	.resume = ixgbe_io_resume,
+	.reset_prepare = ixgbe_pci_reset_prepare,
+	.reset_done = ixgbe_pci_reset_done,
 };
 
 static DEFINE_SIMPLE_DEV_PM_OPS(ixgbe_pm_ops, ixgbe_suspend, ixgbe_resume);
-- 
2.53.0


^ permalink raw reply related

* [PATCH net-next 0/2] net: dsa: mt7530: add EcoNet EN7528 built-in switch support
From: Ahmed Naseef @ 2026-07-10 10:54 UTC (permalink / raw)
  To: netdev
  Cc: Arınç ÜNAL, Chester A. Unal, David S. Miller,
	Andrew Lunn, AngeloGioacchino Del Regno, Conor Dooley,
	DENG Qingfang, Daniel Golle, Eric Dumazet, Jakub Kicinski,
	Krzysztof Kozlowski, Landen Chao, Matthias Brugger, Paolo Abeni,
	Rob Herring, Russell King, Sean Wang, Vladimir Oltean, devicetree,
	linux-arm-kernel, linux-kernel, linux-mediatek, Ahmed Naseef

The EcoNet EN7528 is a MIPS SoC whose platform support is already
upstream. It integrates an MT7530 switch, memory-mapped like the built-in
switches of the MediaTek MT7988 and Airoha EN7581/AN7583 SoCs, but with a
true MT7530 core, four Gigabit PHYs on ports 1-4 and a CPU port at a fixed
1000 Mbps full duplex link.

Patch 1 documents the compatible, patch 2 adds the driver support.

Ahmed Naseef (2):
  dt-bindings: net: dsa: mediatek,mt7530: add econet,en7528-switch
  net: dsa: mt7530: add EN7528 support

 .../bindings/net/dsa/mediatek,mt7530.yaml     |  5 ++
 drivers/net/dsa/mt7530-mmio.c                 |  1 +
 drivers/net/dsa/mt7530.c                      | 56 ++++++++++++++++++-
 drivers/net/dsa/mt7530.h                      |  1 +
 4 files changed, 62 insertions(+), 1 deletion(-)


base-commit: fe3e786ef4eb6e47d2901f568a27bd920477bbe9
-- 
2.34.1


^ permalink raw reply

* [PATCH net-next 1/2] dt-bindings: net: dsa: mediatek,mt7530: add econet,en7528-switch
From: Ahmed Naseef @ 2026-07-10 10:54 UTC (permalink / raw)
  To: netdev
  Cc: Arınç ÜNAL, Chester A. Unal, David S. Miller,
	Andrew Lunn, AngeloGioacchino Del Regno, Conor Dooley,
	DENG Qingfang, Daniel Golle, Eric Dumazet, Jakub Kicinski,
	Krzysztof Kozlowski, Landen Chao, Matthias Brugger, Paolo Abeni,
	Rob Herring, Russell King, Sean Wang, Vladimir Oltean, devicetree,
	linux-arm-kernel, linux-kernel, linux-mediatek, Ahmed Naseef
In-Reply-To: <cover.1783680864.git.naseefkm@gmail.com>

The EcoNet EN7528 MIPS SoC integrates an MT7530 Gigabit switch,
memory-mapped in the SoC register space like the built-in switches of
the MediaTek MT7988 and Airoha EN7581/AN7583 SoCs. Its four user ports
are connected to integrated Gigabit PHYs and its CPU port is connected
internally to the SoC Ethernet MAC.

Add the econet,en7528-switch compatible, with the same constraints as
the other built-in switches.

Signed-off-by: Ahmed Naseef <naseefkm@gmail.com>
---
 .../devicetree/bindings/net/dsa/mediatek,mt7530.yaml         | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml b/Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml
index 815a90808901..90b3582b7619 100644
--- a/Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml
+++ b/Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml
@@ -100,6 +100,10 @@ properties:
           Built-in switch of the Airoha AN7583 SoC
         const: airoha,an7583-switch
 
+      - description:
+          Built-in switch of the EcoNet EN7528 SoC
+        const: econet,en7528-switch
+
   reg:
     maxItems: 1
 
@@ -318,6 +322,7 @@ allOf:
             - mediatek,mt7988-switch
             - airoha,en7581-switch
             - airoha,an7583-switch
+            - econet,en7528-switch
     then:
       $ref: "#/$defs/builtin-dsa-port"
       properties:
-- 
2.34.1


^ permalink raw reply related

* [PATCH net-next 2/2] net: dsa: mt7530: add EN7528 support
From: Ahmed Naseef @ 2026-07-10 10:54 UTC (permalink / raw)
  To: netdev
  Cc: Arınç ÜNAL, Chester A. Unal, David S. Miller,
	Andrew Lunn, AngeloGioacchino Del Regno, Conor Dooley,
	DENG Qingfang, Daniel Golle, Eric Dumazet, Jakub Kicinski,
	Krzysztof Kozlowski, Landen Chao, Matthias Brugger, Paolo Abeni,
	Rob Herring, Russell King, Sean Wang, Vladimir Oltean, devicetree,
	linux-arm-kernel, linux-kernel, linux-mediatek, Ahmed Naseef
In-Reply-To: <cover.1783680864.git.naseefkm@gmail.com>

The EcoNet EN7528 SoC integrates an MT7530 switch (the chip revision
register reads 0x7530), memory-mapped in the SoC register space and
reached through the same MMIO glue used for the built-in switches of the
MediaTek MT7988 and Airoha EN7581/AN7583 SoCs. Its reset sequence and its
PHY indirect access registers are the same as on those switches, so add
an ID_EN7528 variant bound with the "econet,en7528-switch" compatible,
reusing mt7988_setup() and the indirect PHY accessors.

The switch core, however, is an MT7530 and not an MT7531 derivative: it
has no MT7531 CFC register, and the CPU port to trap frames to is set
through the MT7530-style CPU_EN / CPU_PORT fields of the MFC register, so
add it to the MT7530 handling in mt753x_conduit_state_change(). For the
same reason the MT7530 mirror and force-mode register layouts already
apply to it as the default of the MT753X_*() macros.

The four user ports (1-4) are connected to integrated Gigabit PHYs at
MDIO addresses 9-12 of the switch internal MDIO bus. The CPU port (port
6) is connected to the SoC Ethernet MAC at a fixed 1000 Mbps full duplex
link, so the port capabilities cannot be shared with the MT7988 and
EN7581 switches, whose CPU ports run at 10 Gbps.

The LAN GPHYs advertise EEE by default, but negotiating EEE with some
link partners results in an unstable link with dropped frames. Disable
EEE advertisement on them at setup time, like mt7531_setup() does for the
MT7531 switch PHYs.

Signed-off-by: Ahmed Naseef <naseefkm@gmail.com>
---
 drivers/net/dsa/mt7530-mmio.c |  1 +
 drivers/net/dsa/mt7530.c      | 56 ++++++++++++++++++++++++++++++++++-
 drivers/net/dsa/mt7530.h      |  1 +
 3 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/drivers/net/dsa/mt7530-mmio.c b/drivers/net/dsa/mt7530-mmio.c
index 1dc8b93fb51a..1065671bcdd1 100644
--- a/drivers/net/dsa/mt7530-mmio.c
+++ b/drivers/net/dsa/mt7530-mmio.c
@@ -13,6 +13,7 @@
 static const struct of_device_id mt7988_of_match[] = {
 	{ .compatible = "airoha,an7583-switch", .data = &mt753x_table[ID_AN7583], },
 	{ .compatible = "airoha,en7581-switch", .data = &mt753x_table[ID_EN7581], },
+	{ .compatible = "econet,en7528-switch", .data = &mt753x_table[ID_EN7528], },
 	{ .compatible = "mediatek,mt7988-switch", .data = &mt753x_table[ID_MT7988], },
 	{ /* sentinel */ },
 };
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 3c2a3029b10c..2aecad77af9a 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2912,6 +2912,30 @@ static void en7581_mac_port_get_caps(struct dsa_switch *ds, int port,
 	}
 }
 
+static void en7528_mac_port_get_caps(struct dsa_switch *ds, int port,
+				     struct phylink_config *config)
+{
+	switch (port) {
+	/* Ports which are connected to switch PHYs. There is no MII pinout. */
+	case 1 ... 4:
+		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
+			  config->supported_interfaces);
+
+		config->mac_capabilities |= MAC_10 | MAC_100 | MAC_1000FD;
+		break;
+
+	/* Port 6 is connected to SoC's GMAC at 1000 Mbps full duplex. There
+	 * is no MII pinout.
+	 */
+	case 6:
+		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
+			  config->supported_interfaces);
+
+		config->mac_capabilities |= MAC_1000FD;
+		break;
+	}
+}
+
 static void
 mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 		  phy_interface_t interface)
@@ -3254,7 +3278,8 @@ mt753x_conduit_state_change(struct dsa_switch *ds,
 	 * forwarded to the numerically smallest CPU port whose conduit
 	 * interface is up.
 	 */
-	if (priv->id != ID_MT7530 && priv->id != ID_MT7621)
+	if (priv->id != ID_MT7530 && priv->id != ID_MT7621 &&
+	    priv->id != ID_EN7528)
 		return;
 
 	mask = BIT(cpu_dp->index);
@@ -3319,9 +3344,17 @@ static int mt753x_setup_tc(struct dsa_switch *ds, int port,
 	}
 }
 
+/* The EN7528 LAN ports are integrated GPHYs at MDIO addresses 9..12 (switch
+ * ports 1..4) on the switch internal MDIO bus, reachable only through the PHY
+ * indirect access registers. There is no mdiodev to derive the addresses from.
+ */
+#define EN7528_GPHY_BASE		9
+#define EN7528_NUM_GPHYS		4
+
 static int mt7988_setup(struct dsa_switch *ds)
 {
 	struct mt7530_priv *priv = ds->priv;
+	int i;
 
 	/* Reset the switch */
 	reset_control_assert(priv->rstc);
@@ -3342,6 +3375,17 @@ static int mt7988_setup(struct dsa_switch *ds)
 	/* Reset the switch PHYs */
 	mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_PHY_RST);
 
+	/* The EN7528 LAN GPHYs advertise EEE by default, but negotiating EEE
+	 * with common link partners (e.g. Realtek GbE NICs) results in an
+	 * unstable link with dropped frames. Disable EEE advertisement on
+	 * them.
+	 */
+	if (priv->id == ID_EN7528)
+		for (i = EN7528_GPHY_BASE;
+		     i < EN7528_GPHY_BASE + EN7528_NUM_GPHYS; i++)
+			mt7531_ind_c45_phy_write(priv, i, MDIO_MMD_AN,
+						 MDIO_AN_EEE_ADV, 0);
+
 	return mt7531_setup_common(ds);
 }
 
@@ -3459,6 +3503,16 @@ const struct mt753x_info mt753x_table[] = {
 		.phy_write_c45 = mt7531_ind_c45_phy_write,
 		.mac_port_get_caps = en7581_mac_port_get_caps,
 	},
+	[ID_EN7528] = {
+		.id = ID_EN7528,
+		.pcs_ops = &mt7530_pcs_ops,
+		.sw_setup = mt7988_setup,
+		.phy_read_c22 = mt7531_ind_c22_phy_read,
+		.phy_write_c22 = mt7531_ind_c22_phy_write,
+		.phy_read_c45 = mt7531_ind_c45_phy_read,
+		.phy_write_c45 = mt7531_ind_c45_phy_write,
+		.mac_port_get_caps = en7528_mac_port_get_caps,
+	},
 };
 EXPORT_SYMBOL_GPL(mt753x_table);
 
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index dd33b0df3419..5f1e841f42c0 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -21,6 +21,7 @@ enum mt753x_id {
 	ID_MT7988 = 3,
 	ID_EN7581 = 4,
 	ID_AN7583 = 5,
+	ID_EN7528 = 6,
 };
 
 #define	NUM_TRGMII_CTRL			5
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH net-next v2 0/8] netconsole: stop charging netpoll users for netconsole-only data
From: Breno Leitao @ 2026-07-10 11:01 UTC (permalink / raw)
  To: Paolo Abeni
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Simon Horman,
	Andrew Lunn, netdev, asantostc, gustavold, linux-kernel,
	kernel-team
In-Reply-To: <alC5pjeFfFnBuipL@gmail.com>

On Fri, Jul 10, 2026 at 02:46:17AM -0700, Breno Leitao wrote:
> On Thu, Jul 09, 2026 at 12:20:24PM +0200, Paolo Abeni wrote:
> > Because this initialization happens before acquiring rtnl_lock inside
> > netpoll_setup(), enabled_store() can execute INIT_WORK() and
> > skb_queue_head_init() simultaneously with the cleanup thread executing
> > cancel_work_sync() and skb_queue_purge_reason() on the exact same
> > fields.
> 
> I don't think this is a big issue, given worst case scenario, the pool
> will not be populated, but this seems a clear regression.

Actually, this is a significant issue. We're calling
skb_queue_head_init() and INIT_WORK() while those same pointers are
being accessed concurrently.

The best approach IMO is to move the initialization early (calling
INIT_WORK()/skb_queue_head_init() before the race window), making the
critical section safe.

I'll send an updated series that also addresses another pre-existing bug,
bringing the total sashiko issue count to something we can enumerate on
our fingers.

^ permalink raw reply

* Re: [PATCH v2 net-next 13/14] ipvlan: Protect ipvl_port.ipvlans with mutex.
From: Paolo Abeni @ 2026-07-10 11:08 UTC (permalink / raw)
  To: Kuniyuki Iwashima, David S . Miller, Eric Dumazet, Jakub Kicinski,
	Andrew Lunn
  Cc: Simon Horman, Kuniyuki Iwashima, netdev
In-Reply-To: <20260703001009.1572444-14-kuniyu@google.com>

On 7/3/26 2:09 AM, Kuniyuki Iwashima wrote:
> @@ -800,9 +831,15 @@ static int ipvlan_device_event(struct notifier_block *unused,
>  		if (dev->reg_state != NETREG_UNREGISTERING)
>  			break;
>  
> -		list_for_each_entry_safe(ipvlan, next, &port->ipvlans, pnode)
> -			ipvlan->dev->rtnl_link_ops->dellink(ipvlan->dev,
> -							    &lst_kill);
> +		list_for_each_entry_safe(ipvlan, next, &port->ipvlans, pnode) {
> +#if IS_ENABLED(CONFIG_IPVTAP)
> +			if (ipvlan->dev->rtnl_link_ops != &ipvlan_link_ops)
> +				__ipvtap_dellink_ptr(ipvlan->dev, &lst_kill);
> +			else
> +#endif
> +				__ipvlan_link_delete(ipvlan->dev, &lst_kill);

I'm not sure if it's worthy a repost, but what about adding a
link_delete_unlocked() cb to `struct ipvl_dev *`? IMHO should make this
code more straight forward.

/P


^ permalink raw reply

* Re: [PATCH v2 net-next 06/14] net: Add per-netns netdev unregistration infra.
From: Paolo Abeni @ 2026-07-10 11:11 UTC (permalink / raw)
  To: Kuniyuki Iwashima, David S . Miller, Eric Dumazet, Jakub Kicinski,
	Andrew Lunn
  Cc: Simon Horman, Kuniyuki Iwashima, netdev
In-Reply-To: <20260703001009.1572444-7-kuniyu@google.com>

On 7/3/26 2:09 AM, Kuniyuki Iwashima wrote:
> When we need to unregister a netdev in a different netns, we will
> delegate its unregistration to per-netns work.
> 
> There are three types of such cross-netns devices:
> 
>   1. Paired devices (e.g., netkit, veth, vxcan)
>      -> Unregistering one device also deletes its peer, which
>         may reside in another netns.
> 
>   2. Tunnel devices (e.g., bareudp, geneve, etc)
>      -> Destroying a netns removes devices in another netns if
>         their backend sockets reside in the dying netns
> 
>   3. Stacked devices (e.g., ipvlan, macvlan, etc)
>      -> Removing the lower device also removes multiple upper
>         devices, each of which may reside in different namespaces.
> 
> In these cases, we will use unregister_netdevice_queue_net() to
> queue such potential cross-netns devices for destruction.
> 
> Each driver must not call both unregister_netdevice_queue_net()
> and unregister_netdevice_queue() for the same device.  See the
> subsequent veth/bareudp/ipvlan patches for how they avoid double
> queueing.

Only if a repost is needed, possibly avoid the double negation above?

"""
Each driver must exactly call either unregister_netdevice_queue_net() or
unregister_netdevice_queue()...
"""

/P


^ permalink raw reply

* [PATCH net] mac802154: flush rx_mac_cmd_list before freeing sdata
From: Ibrahim Hashimov @ 2026-07-10 11:13 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, Miquel Raynal, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni
  Cc: Simon Horman, linux-wpan, netdev, linux-kernel, stable

mac802154_rx_mac_cmd_worker() (net/mac802154/rx.c) is queued on
local->mac_wq every time a MAC-command frame (assoc req/resp, disassoc
notify, beacon req) is received on any interface of a given phy. Each
queued struct cfg802154_mac_pkt stashes a *raw* pointer to the
receiving interface's ieee802154_sub_if_data (sdata) in
ieee802154_subif_frame():

	mac_pkt->sdata = sdata;
	list_add_tail(&mac_pkt->node, &sdata->local->rx_mac_cmd_list);
	queue_work(sdata->local->mac_wq, &sdata->local->rx_mac_cmd_work);

and the worker later dereferences it with no liveness check at all,
e.g. for IEEE802154_CMD_ASSOCIATION_REQ:

	if (mac_pkt->sdata->wpan_dev.iftype != NL802154_IFTYPE_COORD)

Neither teardown path drains this queue before the sdata it points to
is freed:

 * ieee802154_if_remove() (net/mac802154/iface.c), reached from the
   nl802154 NL802154_CMD_DEL_INTERFACE handler, does list_del_rcu() +
   synchronize_rcu() + unregister_netdevice(sdata->dev) -- which frees
   sdata via priv_destructor/needs_free_netdev -- without touching
   local->mac_wq or local->rx_mac_cmd_list at all.

 * ieee802154_unregister_hw() (net/mac802154/main.c) only flushes
   local->workqueue (the DATA-path queue) before calling
   ieee802154_remove_interfaces(), which frees every sdata on the
   phy; local->mac_wq is drained only via destroy_workqueue() much
   later, after the interfaces (and their sdata) are already gone.

Either way, if mac802154_rx_mac_cmd_worker() is already queued (or
races back in from a frame received just before teardown), it runs
after the free and dereferences freed memory -- confirmed under
KASAN: flooding a victim NODE interface with MAC_CMD frames from a
MONITOR interface on a sibling phy, then deleting the victim via
NL802154_CMD_DEL_INTERFACE, reliably produces:

  BUG: KASAN: use-after-free in mac802154_rx_mac_cmd_worker+0x463/0x630 [mac802154]
  Read of size 4 at addr ffff888004b22a18 by task kworker/u8:1/31
  Workqueue: phy0-mac-cmds mac802154_rx_mac_cmd_worker [mac802154]
  Freed by task 498: ... (the DEL_INTERFACE task, ieee802154_if_remove)

Verified on the same v6.19 KASAN stand with this patch applied: the
identical MONITOR-flood-then-DEL_INTERFACE reproducer no longer trips
the use-after-free report in mac802154_rx_mac_cmd_worker().

Fix it the same way mac802154_flush_queued_beacons() (net/mac802154/scan.c)
already flushes local->rx_beacon_list on scan cleanup, plus a
cancel_work_sync() step: rx_beacon_work's worker never dereferences
sdata, so the existing sibling doesn't need it, but rx_mac_cmd_work's
does. Add mac802154_flush_queued_mac_cmds(local, sdata):

 - cancel_work_sync(&local->rx_mac_cmd_work) waits out a run already
   in flight (still safe -- nothing has been freed yet) and blocks any
   new run from starting while we hold the RTNL;
 - every rx_mac_cmd_list entry whose ->sdata matches (or every entry,
   when called with sdata == NULL for full-teardown) is then dropped,
   so no future run of the worker can see it;
 - if entries belonging to *other*, still-live interfaces on the same
   local remain, the work is re-queued so they still get processed.

Call it from both teardown paths:

 - ieee802154_if_remove(), before unregister_netdevice(sdata->dev),
   filtered to the sdata being removed (other interfaces on the same
   phy may have legitimate entries in flight);
 - ieee802154_unregister_hw(), before ieee802154_remove_interfaces(),
   with sdata == NULL since every interface on the local is going
   away and local->workqueue's flush_workqueue() does not cover
   local->mac_wq.

This mirrors how mac80211 drains per-interface work (e.g. the
analogous per-sdata work items cancelled from ieee80211_do_stop()
before an interface is torn down) and the existing mac802154 scan.c
list-flush idiom, applied to the one rx_mac_cmd_list consumer that
actually dereferences the freed interface.

Fixes: d021d218f6d9 ("mac802154: Handle received BEACON_REQ")
Cc: stable@vger.kernel.org
Signed-off-by: Ibrahim Hashimov <security@auditcode.ai>
Assisted-by: AuditCode-AI:2026.07
---
 net/mac802154/ieee802154_i.h |  2 ++
 net/mac802154/iface.c        | 10 +++++++++
 net/mac802154/main.c         | 11 ++++++++++
 net/mac802154/rx.c           | 42 ++++++++++++++++++++++++++++++++++++
 4 files changed, 65 insertions(+)

diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h
index 8f2bff268392..e3c5c8d5b5d0 100644
--- a/net/mac802154/ieee802154_i.h
+++ b/net/mac802154/ieee802154_i.h
@@ -300,6 +300,8 @@ static inline bool mac802154_is_beaconing(struct ieee802154_local *local)
 }
 
 void mac802154_rx_mac_cmd_worker(struct work_struct *work);
+void mac802154_flush_queued_mac_cmds(struct ieee802154_local *local,
+				     struct ieee802154_sub_if_data *sdata);
 
 int mac802154_perform_association(struct ieee802154_sub_if_data *sdata,
 				  struct ieee802154_pan_device *coord,
diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
index 000be60d9580..a5aa213e25a2 100644
--- a/net/mac802154/iface.c
+++ b/net/mac802154/iface.c
@@ -694,6 +694,16 @@ void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata)
 	mutex_unlock(&sdata->local->iflist_mtx);
 
 	synchronize_rcu();
+
+	/*
+	 * Drop any rx_mac_cmd_list entry still pointing at this sdata
+	 * before it is freed below: mac802154_rx_mac_cmd_worker() runs
+	 * asynchronously on local->mac_wq and derefs mac_pkt->sdata with
+	 * no liveness check of its own (see mac802154_flush_queued_mac_cmds()
+	 * for details).
+	 */
+	mac802154_flush_queued_mac_cmds(sdata->local, sdata);
+
 	unregister_netdevice(sdata->dev);
 }
 
diff --git a/net/mac802154/main.c b/net/mac802154/main.c
index ea1efef3572a..2f8c57e78db1 100644
--- a/net/mac802154/main.c
+++ b/net/mac802154/main.c
@@ -277,6 +277,17 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw)
 	tasklet_kill(&local->tasklet);
 	flush_workqueue(local->workqueue);
 
+	/*
+	 * tasklet_kill() above stops any further frame reaching
+	 * ieee802154_subif_frame(), but mac802154_rx_mac_cmd_worker() may
+	 * still be queued/running on local->mac_wq and derefs the sdata of
+	 * every interface ieee802154_remove_interfaces() is about to free
+	 * below. flush_workqueue(local->workqueue) does not cover it --
+	 * that is the DATA workqueue, not local->mac_wq -- so drain it
+	 * explicitly first.
+	 */
+	mac802154_flush_queued_mac_cmds(local, NULL);
+
 	rtnl_lock();
 
 	ieee802154_remove_interfaces(local);
diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
index cd8f2a11920d..0b167f76cb23 100644
--- a/net/mac802154/rx.c
+++ b/net/mac802154/rx.c
@@ -128,6 +128,48 @@ out:
 	kfree(mac_pkt);
 }
 
+/**
+ * mac802154_flush_queued_mac_cmds - drop pending rx_mac_cmd_list work
+ * @local: the mac802154 device the queue belongs to
+ * @sdata: interface being torn down, or %NULL to flush unconditionally
+ *
+ * Every queued &struct cfg802154_mac_pkt stashes a raw pointer to the
+ * interface it was received on (see ieee802154_subif_frame() below) which
+ * mac802154_rx_mac_cmd_worker() dereferences without ever checking whether
+ * that interface is still alive. Callers must invoke this before freeing
+ * @sdata -- or every interface on @local, when @sdata is %NULL -- so the
+ * worker can never run against freed memory:
+ *
+ *  - cancel_work_sync() waits out a run already in flight. That is still
+ *    safe to let finish because nothing has been freed yet, and it blocks
+ *    any new run from starting for as long as we hold the RTNL.
+ *  - every list entry pointing at @sdata (all of them, if @sdata is NULL)
+ *    is then dropped so no future run of the worker can see it.
+ *
+ * Mirrors mac802154_flush_queued_beacons() in scan.c, which does not need
+ * the cancel_work_sync() step because its worker never dereferences sdata.
+ */
+void mac802154_flush_queued_mac_cmds(struct ieee802154_local *local,
+				     struct ieee802154_sub_if_data *sdata)
+{
+	struct cfg802154_mac_pkt *mac_pkt, *tmp;
+
+	cancel_work_sync(&local->rx_mac_cmd_work);
+
+	list_for_each_entry_safe(mac_pkt, tmp, &local->rx_mac_cmd_list, node) {
+		if (sdata && mac_pkt->sdata != sdata)
+			continue;
+
+		list_del(&mac_pkt->node);
+		kfree_skb(mac_pkt->skb);
+		kfree(mac_pkt);
+	}
+
+	/* Other interfaces on @local may still have entries pending. */
+	if (!list_empty(&local->rx_mac_cmd_list))
+		queue_work(local->mac_wq, &local->rx_mac_cmd_work);
+}
+
 static int
 ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata,
 		       struct sk_buff *skb, const struct ieee802154_hdr *hdr)
-- 
2.50.1 (Apple Git-155)


^ permalink raw reply related

* [ANN] E830 NIC join intel's netdev-ci
From: Pielech, Adrian @ 2026-07-10 11:20 UTC (permalink / raw)
  To: kuba, netdev
  Cc: Kitszel, Przemyslaw, intel-wired-lan, Nguyen, Anthony L, pabeni,
	davem, edumazet, horms, andrew+netdev

Hi folks,

I'm pleased to announce that E830-XXVDA2 NIC from Intel Ethernet E830 
product line joins the suite that tests ice driver against net-next-hw 
branch.

Adrian

^ permalink raw reply

* [PATCH] selftests: nci: Fix wrong size of status variables in nci_dev test
From: Thomas Huth @ 2026-07-10 11:23 UTC (permalink / raw)
  To: Bongsu Jeon, netdev; +Cc: Shuah Khan, linux-kselftest, linux-kernel

From: Thomas Huth <thuth@redhat.com>

pthread_join() stores the thread's return value (a "void *", i.e.
8 bytes on 64 bit computers) into the address of "status", but the
"status" variable is declared as "int" with only 4 bytes. The extra
four bytes clobber whatever is adjacent on the stack, which could
silently corrupt other local variables. Use "intptr_t" to declare
the "status" variables with the correct size.

Signed-off-by: Thomas Huth <thuth@redhat.com>
---
 tools/testing/selftests/nci/nci_dev.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/tools/testing/selftests/nci/nci_dev.c b/tools/testing/selftests/nci/nci_dev.c
index 312f84ee0444f..4e7a5856f7ea3 100644
--- a/tools/testing/selftests/nci/nci_dev.c
+++ b/tools/testing/selftests/nci/nci_dev.c
@@ -6,6 +6,7 @@
  * Test code for nci
  */
 
+#include <stdint.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <string.h>
@@ -404,7 +405,7 @@ FIXTURE_SETUP(NCI)
 	struct msgtemplate msg;
 	pthread_t thread_t;
 	__u32 event_group;
-	int status;
+	intptr_t status;
 	int rc;
 
 	self->open_state = false;
@@ -497,7 +498,7 @@ static void *virtual_deinit_v2(void *data)
 FIXTURE_TEARDOWN(NCI)
 {
 	pthread_t thread_t;
-	int status;
+	intptr_t status;
 	int rc;
 
 	if (self->open_state) {
@@ -585,7 +586,7 @@ int start_polling(int dev_idx, int proto, int virtual_fd, int sd, int fid, int p
 	void *nla_start_poll_data[2] = {&dev_idx, &proto};
 	int nla_start_poll_len[2] = {4, 4};
 	pthread_t thread_t;
-	int status;
+	intptr_t status;
 	int rc;
 
 	rc = pthread_create(&thread_t, NULL, virtual_poll_start,
@@ -605,7 +606,7 @@ int start_polling(int dev_idx, int proto, int virtual_fd, int sd, int fid, int p
 int stop_polling(int dev_idx, int virtual_fd, int sd, int fid, int pid)
 {
 	pthread_t thread_t;
-	int status;
+	intptr_t status;
 	int rc;
 
 	rc = pthread_create(&thread_t, NULL, virtual_poll_stop,
@@ -816,7 +817,7 @@ int disconnect_tag(int nfc_sock, int virtual_fd)
 {
 	pthread_t thread_t;
 	char buf[256];
-	int status;
+	intptr_t status;
 	int len;
 
 	send(nfc_sock, &nci_t4t_select_cmd3[3], sizeof(nci_t4t_select_cmd3) - 3, 0);
@@ -860,7 +861,7 @@ TEST_F(NCI, deinit)
 {
 	struct msgtemplate msg;
 	pthread_t thread_t;
-	int status;
+	intptr_t status;
 	int rc;
 
 	rc = get_nci_devid(self->sd, self->fid, self->pid, self->dev_idex,
-- 
2.55.0


^ permalink raw reply related

* Re: [PATCH RFC net-next 0/2] seg6: add support for the SRv6 End.MAP behavior
From: Yuya Kusakabe @ 2026-07-10 11:24 UTC (permalink / raw)
  To: Andrea Mayer, Andrea Mayer, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, David Ahern,
	Ido Schimmel, Shuah Khan
  Cc: linux-kernel, netdev, linux-kselftest, Justin Iurman
In-Reply-To: <20260710-seg6-mobile-end-map-v1-0-99be02d68143@gmail.com>

+Cc Justin Iurman

Jakub added Justin to the Cc of the SRv6 Mobile User Plane v2 thread
[1], which I missed carrying over to this per-behavior posting.
Justin, the cover letter above has the context.

[1] https://lore.kernel.org/netdev/20260504182833.344d7b33@kernel.org/

^ permalink raw reply

* Re: [PATCH net v2] net/mlx5: free mlx5_st_idx_data on final dealloc
From: Paolo Abeni @ 2026-07-10 11:25 UTC (permalink / raw)
  To: Zhiping Zhang, Jason Gunthorpe, Leon Romanovsky,
	Saeed Mahameed Michael, Tariq Toukan, Mark Bloch
  Cc: Michael Guralnik, netdev, linux-rdma, linux-kernel, stable
In-Reply-To: <20260702222507.1234467-1-zhipingz@meta.com>

On 7/3/26 12:24 AM, Zhiping Zhang wrote:
> Workloads that repeatedly allocate and release mkeys carrying TPH
> steering-tag hints (e.g. churning RDMA MRs) leak one
> struct mlx5_st_idx_data per cycle; kmemleak flags it as unreferenced
> and the kmalloc slab grows over time.
> 
> When the last reference to an ST table entry is dropped,
> mlx5_st_dealloc_index() removed the entry from idx_xa but the backing
> mlx5_st_idx_data allocation was never freed.
> 
> Free idx_data after the xa_erase() so the lifetime of the bookkeeping
> struct matches the lifetime of the ST entry it tracks.
> 
> Cc: stable@vger.kernel.org
> Fixes: 888a7776f4fb ("net/mlx5: Add support for device steering tag")
> Reviewed-by: Michael Gur <michaelgur@nvidia.com>
> Signed-off-by: Zhiping Zhang <zhipingz@meta.com>
@Leon, @Saeed, @Tariq: just in case this fell under the radar, it's
waiting for your ack.

Thanks,

Paolo


^ permalink raw reply

* Re: [PATCH net v3] ppp: defer channel free to an RCU grace period to fix pppol2tp RX UAF
From: patchwork-bot+netdevbpf @ 2026-07-10 11:40 UTC (permalink / raw)
  To: Norbert Szetei
  Cc: netdev, andrew+netdev, davem, edumazet, kuba, pabeni,
	qingfang.deng, yuehaibing, gnault, kees, hataegu0826, linux-ppp,
	linux-kernel
In-Reply-To: <E793FCF2-58DE-4387-A983-C7B4BC3158BD@doyensec.com>

Hello:

This patch was applied to netdev/net.git (main)
by Paolo Abeni <pabeni@redhat.com>:

On Mon, 6 Jul 2026 11:01:59 +0200 you wrote:
> pppol2tp_recv() runs in the L2TP UDP-encap softirq RX path:
> 
>  l2tp_udp_encap_recv() -> l2tp_recv_common() -> pppol2tp_recv()
>    -> ppp_input(&po->chan)
> 
> It runs under rcu_read_lock() holding only an l2tp_session reference and
> takes NO reference on the internal PPP channel (struct channel,
> chan->ppp) that ppp_input() dereferences.
> 
> [...]

Here is the summary with links:
  - [net,v3] ppp: defer channel free to an RCU grace period to fix pppol2tp RX UAF
    https://git.kernel.org/netdev/net/c/ec4215683e47

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



^ permalink raw reply


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