Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net 2/4] net: add the driver-facing netdev_work scheduling API
From: Kuniyuki Iwashima @ 2026-06-25  5:55 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, jv, sdf,
	dongchenchen2, idosch, n05ec, yuantan098, nb, aleksandr.loktionov,
	dtatulea
In-Reply-To: <20260624182018.2445732-3-kuba@kernel.org>

On Wed, Jun 24, 2026 at 11:20 AM Jakub Kicinski <kuba@kernel.org> wrote:
>
> With an extra event mask we can easily extend the netdev work
> to also service driver-defined events. For advanced drivers
> this is probably not a perfect match, but it makes running
> deferred work easier in simple cases.
>
> Expose the netdev_work facility to drivers. Add helpers
> to schedule work and a dedicated ndo to perform the driver-
> -scheduled actions.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>

^ permalink raw reply

* [PATCH v2 1/1] xfrm: nat_keepalive: avoid double free on send error
From: Ren Wei @ 2026-06-25  5:55 UTC (permalink / raw)
  To: netdev
  Cc: steffen.klassert, herbert, davem, eyal.birger, yuantan098, bird,
	qianyuluo3, n05ec

From: Qianyu Luo <qianyuluo3@gmail.com>

nat_keepalive_send() frees the keepalive skb whenever the IPv4 or IPv6
send helper reports an error.

That cleanup is only correct before the skb is handed to the output
path. Once ip_build_and_send_pkt() or ip6_xmit() takes ownership, the
networking stack may already have consumed the skb before returning an
error, so freeing it again is unsafe.

Handle the pre-handoff failure cases inside nat_keepalive_send_ipv4()
and nat_keepalive_send_ipv6(), where the caller still owns the skb, and
keep nat_keepalive_send() responsible only for family dispatch and the
unsupported-family cleanup path.

Fixes: f531d13bdfe3 ("xfrm: support sending NAT keepalives in ESP in UDP states")
Cc: stable@vger.kernel.org
Reported-by: Yuan Tan <yuantan098@gmail.com>
Reported-by: Xin Liu <bird@lzu.edu.cn>
Signed-off-by: Qianyu Luo <qianyuluo3@gmail.com>
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
---
Changes in v2:
- move kfree_skb() after local_unlock_nested_bh() in the IPv6 dst-lookup
  failure path as suggested in review
- rebase onto latest netdev/net

Link: https://lore.kernel.org/all/46eb334399ce0e25e0897b42f21020541d159300.1781788385.git.qianyuluo3@gmail.com/

 net/xfrm/xfrm_nat_keepalive.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/net/xfrm/xfrm_nat_keepalive.c b/net/xfrm/xfrm_nat_keepalive.c
index 458931062a04..eb1b6f67739e 100644
--- a/net/xfrm/xfrm_nat_keepalive.c
+++ b/net/xfrm/xfrm_nat_keepalive.c
@@ -55,8 +55,10 @@ static int nat_keepalive_send_ipv4(struct sk_buff *skb,
 			   ka->encap_sport, sock_net_uid(net, NULL));
 
 	rt = ip_route_output_key(net, &fl4);
-	if (IS_ERR(rt))
+	if (IS_ERR(rt)) {
+		kfree_skb(skb);
 		return PTR_ERR(rt);
+	}
 
 	skb_dst_set(skb, &rt->dst);
 
@@ -101,6 +103,7 @@ static int nat_keepalive_send_ipv6(struct sk_buff *skb,
 	dst = ip6_dst_lookup_flow(net, sk, &fl6, NULL);
 	if (IS_ERR(dst)) {
 		local_unlock_nested_bh(&nat_keepalive_sk_ipv6.bh_lock);
+		kfree_skb(skb);
 		return PTR_ERR(dst);
 	}
 
@@ -118,7 +121,6 @@ static void nat_keepalive_send(struct nat_keepalive *ka)
 					sizeof(struct ipv6hdr)) +
 				    sizeof(struct udphdr);
 	const u8 nat_ka_payload = 0xFF;
-	int err = -EAFNOSUPPORT;
 	struct sk_buff *skb;
 	struct udphdr *uh;
 
@@ -140,16 +142,17 @@ static void nat_keepalive_send(struct nat_keepalive *ka)
 
 	switch (ka->family) {
 	case AF_INET:
-		err = nat_keepalive_send_ipv4(skb, ka);
+		nat_keepalive_send_ipv4(skb, ka);
 		break;
 #if IS_ENABLED(CONFIG_IPV6)
 	case AF_INET6:
-		err = nat_keepalive_send_ipv6(skb, ka, uh);
+		nat_keepalive_send_ipv6(skb, ka, uh);
 		break;
 #endif
-	}
-	if (err)
+	default:
 		kfree_skb(skb);
+		break;
+	}
 }
 
 struct nat_keepalive_work_ctx {
-- 
2.43.7


^ permalink raw reply related

* Re: [PATCH net 1/4] net: turn the rx_mode work into a generic netdev_work facility
From: Kuniyuki Iwashima @ 2026-06-25  5:55 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, jv, sdf,
	dongchenchen2, idosch, n05ec, yuantan098, nb, aleksandr.loktionov,
	dtatulea
In-Reply-To: <20260624182018.2445732-2-kuba@kernel.org>

On Wed, Jun 24, 2026 at 11:20 AM Jakub Kicinski <kuba@kernel.org> wrote:
>
> The rx_mode update runs from a workqueue: drivers have their
> ndo_set_rx_mode_async() callback executed by a single global
> work item under RTNL and ops lock. This is a useful pattern.
>
> Support multiple "events" that need to be serviced and make RX_MODE
> sync the first one. Call the events "core" because later on
> we will let drivers define and schedule their own.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Oh very nice !

I was drafting almost the same change for dev_set_rx_mode()
in mcast path and some ipvlan changes.

Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>

^ permalink raw reply

* Re: [PATCH net v2] octeontx2-af: Block VFs from clobbering special CGX PKIND state
From: Ratheesh Kannoth @ 2026-06-25  5:25 UTC (permalink / raw)
  To: davem, gakula, linux-kernel, netdev, sgoutham
  Cc: andrew+netdev, edumazet, kuba, pabeni, Hariprasad Kelam
In-Reply-To: <20260625044621.2841831-1-rkannoth@marvell.com>

On 2026-06-25 at 10:16:21, Ratheesh Kannoth (rkannoth@marvell.com) wrote:
> From: Hariprasad Kelam <hkelam@marvell.com>
>
> PF and VF NIX LFs that share a CGX LMAC reuse the same hardware PKIND
> programming. When HiGig2 or EDSA parsing is enabled, a VF NIX LF alloc must
> not reset the LMAC RX PKIND or default TX parse config over the PF setup.
>
> Add cgx_get_pkind() and rvu_cgx_is_pkind_config_permitted() so VFs skip
> cgx_set_pkind(), rvu_npc_set_pkind(), and NIX_AF_LFX_TX_PARSE_CFG updates
> when the LMAC is using NPC_RX_HIGIG_PKIND or NPC_RX_EDSA_PKIND.
>
> Fixes: 94d942c5fb97 ("octeontx2-af: Config pkind for CGX mapped PFs")
> Cc: Geetha sowjanya <gakula@marvell.com>
> Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
> Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
>
> ---
> v1 -> v2: Addressed simon comments
> 	https://lore.kernel.org/netdev/20260619041002.1773822-1-rkannoth@marvell.com/
> ---

Apologies for the inconvenience — it appears I submitted an incorrect patch.
I will abandon it and post a revised one later. Thanks.

pw-bot: changes-requested

^ permalink raw reply

* [PATCH net v3] igb: only strip Rx timestamp header on the first buffer of a frame
From: Tjerk Kusters via B4 Relay @ 2026-06-25  5:24 UTC (permalink / raw)
  To: Tony Nguyen, Przemek Kitszel, Andrew Lunn, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Richard Cochran,
	Jesper Dangaard Brouer, Kurt Kanzenbach
  Cc: intel-wired-lan, netdev, linux-kernel, stable, Piotr Kwapulinski,
	Aleksandr Loktionov, Tjerk Kusters

From: Tjerk Kusters <tkusters@aweta.nl>

When Rx hardware timestamping is enabled (e.g. ptp4l, which configures
HWTSTAMP_FILTER_ALL), the NIC prepends a 16-byte timestamp header to the
first Rx buffer of every received frame. igb_clean_rx_irq() strips this
header inside its per-buffer loop:

	if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP)) {
		ts_hdr_len = igb_ptp_rx_pktstamp(rx_ring->q_vector,
						 pktbuf, &timestamp);
		pkt_offset += ts_hdr_len;
		size -= ts_hdr_len;
	}

For a frame that spans more than one Rx buffer (e.g. a jumbo frame), this
block runs once per buffer. The timestamp header only exists at the start
of the first buffer, but igb_ptp_rx_pktstamp() is called for every buffer.

On a continuation buffer the data is packet payload, not a timestamp
header. igb_ptp_rx_pktstamp() already has two guards against acting on a
non-header buffer: it returns 0 if PTP is disabled, and returns 0 if the
reserved dwords (the first 8 bytes) are non-zero. Neither is sufficient
here: PTP is enabled, and a continuation buffer whose payload happens to
begin with 8 zero bytes passes the reserved-dword check. In that case the
payload is mistaken for a valid timestamp header and igb_ptp_rx_pktstamp()
returns IGB_TS_HDR_LEN, so the caller strips 16 bytes of real data from
that buffer. A frame spanning N buffers whose continuation buffers start
with zero bytes therefore loses 16 * (N - 1) bytes from its tail.

This is easily triggered by a GigE Vision camera streaming dark frames
(mostly 0x00 pixel data) over jumbo UDP with PTP active on the receiver:
the all-zero frames arrive truncated while frames with non-zero content
are fine. There is no error indication.

No content-based check can reliably tell a continuation buffer that begins
with zero bytes from a real timestamp header, because both are all zero.
Fix it structurally instead: only attempt the strip on the first buffer of
a frame, which is the only buffer that can contain a timestamp header. In
igb_clean_rx_irq() skb is NULL until the first buffer has been processed,
so guarding the strip with !skb restricts it to the first buffer
regardless of payload content.

Fixes: 5379260852b0 ("igb: Fix XDP with PTP enabled")
Cc: stable@vger.kernel.org
Reviewed-by: Piotr Kwapulinski <piotr.kwapulinski@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Kurt Kanzenbach <kurt@linutronix.de>
Signed-off-by: Tjerk Kusters <tkusters@aweta.nl>
---
Changes in v3:
- update the rx-timestamp comment to note it only applies to the first
  buffer of a frame (Piotr Kwapulinski)
- add Reviewed-by from Aleksandr Loktionov and Piotr Kwapulinski
- no functional change
- Link to v2: https://patch.msgid.link/20260619-igb-rx-ts-fix-v2-1-d3b8d605ca62@aweta.nl

igb: only strip Rx timestamp header on the first buffer of a frame

Changes in v2:
 - resend via b4 (v1 was sent with a mail client)
 - use full author name "Tjerk Kusters" (Jacob Keller)
 - add Reviewed-by from Kurt Kanzenbach
 - no functional change

Link to v1: https://lore.kernel.org/all/PAWPR05MB1069106D52F4E17F1EDB99C67B9182@PAWPR05MB10691.eurprd05.prod.outlook.com/
---
 drivers/net/ethernet/intel/igb/igb_main.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index ce91dda00ec0..539bf5389a24 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -9060,8 +9060,11 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget)
 		rx_buffer = igb_get_rx_buffer(rx_ring, size, &rx_buf_pgcnt);
 		pktbuf = page_address(rx_buffer->page) + rx_buffer->page_offset;
 
-		/* pull rx packet timestamp if available and valid */
-		if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP)) {
+		/* pull rx packet timestamp if available and valid; it is only
+		 * present on the first buffer of a frame
+		 */
+		if (!skb &&
+		    igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP)) {
 			int ts_hdr_len;
 
 			ts_hdr_len = igb_ptp_rx_pktstamp(rx_ring->q_vector,

---
base-commit: 2d3090a8aeb596a26935db0955d46c9a5db5c6ce
change-id: 20260619-igb-rx-ts-fix-cd70585ee316

Best regards,
--  
Tjerk Kusters <tkusters@aweta.nl>



^ permalink raw reply related

* [PATCH net v2] octeontx2-af: Block VFs from clobbering special CGX PKIND state
From: Ratheesh Kannoth @ 2026-06-25  4:46 UTC (permalink / raw)
  To: davem, gakula, linux-kernel, netdev, sgoutham
  Cc: andrew+netdev, edumazet, kuba, pabeni, Hariprasad Kelam,
	Ratheesh Kannoth

From: Hariprasad Kelam <hkelam@marvell.com>

PF and VF NIX LFs that share a CGX LMAC reuse the same hardware PKIND
programming. When HiGig2 or EDSA parsing is enabled, a VF NIX LF alloc must
not reset the LMAC RX PKIND or default TX parse config over the PF setup.

Add cgx_get_pkind() and rvu_cgx_is_pkind_config_permitted() so VFs skip
cgx_set_pkind(), rvu_npc_set_pkind(), and NIX_AF_LFX_TX_PARSE_CFG updates
when the LMAC is using NPC_RX_HIGIG_PKIND or NPC_RX_EDSA_PKIND.

Fixes: 94d942c5fb97 ("octeontx2-af: Config pkind for CGX mapped PFs")
Cc: Geetha sowjanya <gakula@marvell.com>
Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>

---
v1 -> v2: Addressed simon comments
	https://lore.kernel.org/netdev/20260619041002.1773822-1-rkannoth@marvell.com/
---
 .../net/ethernet/marvell/octeontx2/af/cgx.c   | 12 +++++++
 .../net/ethernet/marvell/octeontx2/af/cgx.h   |  1 +
 .../net/ethernet/marvell/octeontx2/af/rvu.h   |  1 +
 .../ethernet/marvell/octeontx2/af/rvu_cgx.c   | 32 +++++++++++++++++++
 .../ethernet/marvell/octeontx2/af/rvu_nix.c   | 28 +++++++++++++---
 5 files changed, 70 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
index 2e94d5105016..f5fd6138c352 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
@@ -518,6 +518,18 @@ int cgx_set_pkind(void *cgxd, u8 lmac_id, int pkind)
 	return 0;
 }
 
+int cgx_get_pkind(void *cgxd, u8 lmac_id, int *pkind)
+{
+	struct cgx *cgx = cgxd;
+
+	if (!is_lmac_valid(cgx, lmac_id))
+		return -ENODEV;
+
+	*pkind = cgx_read(cgx, lmac_id, cgx->mac_ops->rxid_map_offset);
+	*pkind = *pkind & 0x3F;
+	return 0;
+}
+
 static u8 cgx_get_lmac_type(void *cgxd, int lmac_id)
 {
 	struct cgx *cgx = cgxd;
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.h b/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
index 92ccf343dfe0..8411a75dd723 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
@@ -141,6 +141,7 @@ int cgx_get_cgxid(void *cgxd);
 int cgx_get_lmac_cnt(void *cgxd);
 void *cgx_get_pdata(int cgx_id);
 int cgx_set_pkind(void *cgxd, u8 lmac_id, int pkind);
+int cgx_get_pkind(void *cgxd, u8 lmac_id, int *pkind);
 int cgx_lmac_evh_register(struct cgx_event_cb *cb, void *cgxd, int lmac_id);
 int cgx_lmac_evh_unregister(void *cgxd, int lmac_id);
 int cgx_get_tx_stats(void *cgxd, int lmac_id, int idx, u64 *tx_stat);
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
index 7f3505ae6860..bb671e2150aa 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
@@ -1115,6 +1115,7 @@ void npc_read_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
 			 u8 *intf, u8 *ena);
 int npc_config_cntr_default_entries(struct rvu *rvu, bool enable);
 bool is_cgx_config_permitted(struct rvu *rvu, u16 pcifunc);
+bool rvu_cgx_is_pkind_config_permitted(struct rvu *rvu, u16 pcifunc);
 bool is_mac_feature_supported(struct rvu *rvu, int pf, int feature);
 u32  rvu_cgx_get_fifolen(struct rvu *rvu);
 void *rvu_first_cgx_pdata(struct rvu *rvu);
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
index 4ff3935ed3fe..2be1da3476ac 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
@@ -1355,3 +1355,35 @@ void rvu_mac_reset(struct rvu *rvu, u16 pcifunc)
 	if (mac_ops->mac_reset(cgxd, lmac, !is_vf(pcifunc)))
 		dev_err(rvu->dev, "Failed to reset MAC\n");
 }
+
+/* Do not allow CGX-mapped VFs to overwrite PKIND when special parse kinds
+ * (HiGig, EDSA, etc.) are in use on the shared LMAC.
+ */
+bool rvu_cgx_is_pkind_config_permitted(struct rvu *rvu, u16 pcifunc)
+{
+	int pf, err, rxpkind;
+	u8 cgx_id, lmac_id;
+	void *cgxd;
+
+	pf = rvu_get_pf(rvu->pdev, pcifunc);
+
+	if (!(pcifunc & RVU_PFVF_FUNC_MASK))
+		return true;
+
+	if (!is_pf_cgxmapped(rvu, pf))
+		return true;
+
+	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
+	cgxd = rvu_cgx_pdata(cgx_id, rvu);
+	err = cgx_get_pkind(cgxd, lmac_id, &rxpkind);
+	if (err)
+		return false;
+
+	switch (rxpkind) {
+	case NPC_RX_HIGIG_PKIND:
+	case NPC_RX_EDSA_PKIND:
+		return false;
+	default:
+		return true;
+	}
+}
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
index d8989395e875..40f5b25eafb1 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
@@ -338,6 +338,7 @@ static int nix_interface_init(struct rvu *rvu, u16 pcifunc, int type, int nixlf,
 	struct sdp_node_info *sdp_info;
 	int pkind, pf, vf, lbkid, vfid;
 	u8 cgx_id, lmac_id;
+	struct cgx *cgxd;
 	bool from_vf;
 	int err;
 
@@ -363,8 +364,15 @@ static int nix_interface_init(struct rvu *rvu, u16 pcifunc, int type, int nixlf,
 		pfvf->tx_chan_cnt = 1;
 		rsp->tx_link = cgx_id * hw->lmac_per_cgx + lmac_id;
 
-		cgx_set_pkind(rvu_cgx_pdata(cgx_id, rvu), lmac_id, pkind);
-		rvu_npc_set_pkind(rvu, pkind, pfvf);
+		cgxd = rvu_cgx_pdata(cgx_id, rvu);
+
+		mutex_lock(&cgxd->lock);
+		if (rvu_cgx_is_pkind_config_permitted(rvu, pcifunc)) {
+			cgx_set_pkind(rvu_cgx_pdata(cgx_id, rvu), lmac_id,
+				      pkind);
+			rvu_npc_set_pkind(rvu, pkind, pfvf);
+		}
+		mutex_unlock(&cgxd->lock);
 		break;
 	case NIX_INTF_TYPE_LBK:
 		vf = (pcifunc & RVU_PFVF_FUNC_MASK) - 1;
@@ -1508,7 +1516,10 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu,
 	struct rvu_block *block;
 	struct rvu_pfvf *pfvf;
 	u64 cfg, ctx_cfg;
+	struct cgx *cgxd;
 	int blkaddr;
+	u8 cgx;
+	int pf;
 
 	if (!req->rq_cnt || !req->sq_cnt || !req->cq_cnt)
 		return NIX_AF_ERR_PARAM;
@@ -1680,8 +1691,17 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu,
 	rvu_write64(rvu, blkaddr, NIX_AF_LFX_RX_CFG(nixlf), req->rx_cfg);
 
 	/* Configure pkind for TX parse config */
-	cfg = NPC_TX_DEF_PKIND;
-	rvu_write64(rvu, blkaddr, NIX_AF_LFX_TX_PARSE_CFG(nixlf), cfg);
+	if (is_pf_cgxmapped(rvu, rvu_get_pf(rvu->pdev, pcifunc))) {
+		pf = rvu_get_pf(rvu->pdev, pcifunc);
+		cgxd = rvu_cgx_pdata(cgx, rvu);
+
+		mutex_lock(&cgxd->lock);
+		if (rvu_cgx_is_pkind_config_permitted(rvu, pcifunc)) {
+			cfg = NPC_TX_DEF_PKIND;
+			rvu_write64(rvu, blkaddr, NIX_AF_LFX_TX_PARSE_CFG(nixlf), cfg);
+		}
+		mutex_unlock(&cgxd->lock);
+	}
 
 	if (is_rep_dev(rvu, pcifunc)) {
 		pfvf->tx_chan_base = RVU_SWITCH_LBK_CHAN;
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 net] ipv6: fib6: fix NULL deref in fib6_walk_continue() on multi-batch dump
From: Pengfei Zhang @ 2026-06-25  4:41 UTC (permalink / raw)
  To: dsahern, idosch
  Cc: davem, edumazet, kuba, pabeni, horms, netdev, linux-kernel,
	chenzhangqi, baohua, Pengfei Zhang, Pengfei Zhang

From: Pengfei Zhang <zhangpengfei16@xiaomi.com>

inet6_dump_fib() saves its progress in cb->args[1] as a positional
index within the current hash chain.  Between batches the RTNL lock
is released, so a concurrent fib6_new_table() can insert a new table
at the chain head, shifting all existing entries.  The saved index
then lands on a different table, causing fib6_dump_table() to set
w->root to the wrong table while w->node still points into the
previous one.  fib6_walk_continue() dereferences w->node->parent
(NULL) and panics:

  BUG: kernel NULL pointer dereference, address: 0000000000000008
  RIP: 0010:fib6_walk_continue+0x6e/0x170
  Call Trace:
   <TASK>
   fib6_dump_table.isra.0+0xc5/0x240
   inet6_dump_fib+0xf6/0x420
   rtnl_dumpit+0x30/0xa0
   netlink_dump+0x15b/0x460
   netlink_recvmsg+0x1d6/0x2a0
   ____sys_recvmsg+0x17a/0x190

Fix by storing tb->tb6_id in cb->args[1] instead of a positional
index.  On resume, skip entries until the id matches; a concurrent
head-insert can never match the saved id, so the walker always
resumes on the correct table.

Fixes: 1b43af5480c3 ("[IPV6]: Increase number of possible routing tables to 2^32")
Signed-off-by: Pengfei Zhang <zhangfeionline@gmail.com>
---
 net/ipv6/ip6_fib.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index fc95738de..bda492634 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -636,11 +636,11 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
 	};
 	const struct nlmsghdr *nlh = cb->nlh;
 	struct net *net = sock_net(skb->sk);
-	unsigned int e = 0, s_e;
 	struct hlist_head *head;
 	struct fib6_walker *w;
 	struct fib6_table *tb;
 	unsigned int h, s_h;
+	u32 s_id;
 	int err = 0;
 
 	rcu_read_lock();
@@ -701,23 +701,22 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
 	}
 
 	s_h = cb->args[0];
-	s_e = cb->args[1];
+	s_id = cb->args[1];
 
-	for (h = s_h; h < FIB6_TABLE_HASHSZ; h++, s_e = 0) {
-		e = 0;
+	for (h = s_h; h < FIB6_TABLE_HASHSZ; h++, s_id = 0) {
 		head = &net->ipv6.fib_table_hash[h];
 		hlist_for_each_entry_rcu(tb, head, tb6_hlist) {
-			if (e < s_e)
-				goto next;
+			if (s_id && tb->tb6_id != s_id)
+				continue;
+			s_id = 0;
+
+			cb->args[1] = tb->tb6_id;
 			err = fib6_dump_table(tb, skb, cb);
 			if (err != 0)
 				goto out;
-next:
-			e++;
 		}
 	}
 out:
-	cb->args[1] = e;
 	cb->args[0] = h;
 
 unlock:
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH v2 bpf-next 1/2] bpf: Support BPF_F_EGRESS with bpf_redirect_peer
From: Jiayuan Chen @ 2026-06-25  3:37 UTC (permalink / raw)
  To: Jordan Rife, bpf
  Cc: netdev, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Stanislav Fomichev, Jiayuan Chen, Paul Chaignon
In-Reply-To: <20260618182035.43811-2-jordan@jrife.io>


On 6/19/26 2:20 AM, Jordan Rife wrote:
> We have several use cases where a pod injects traffic into the datapath
> of another so that the traffic appears to have originated from that
> pod. One such use case is a synthetic flow generator which injects
> synthetic traffic into a pod's datapath to enable dynamic probing and
> debugging. Another is a transparent proxy where connections originating
> from one pod are redirected towards another which proxies that
> connection. The new connection is bound to the IP of the original pod
> using IP_TRANSPARENT and its traffic is injected into that pod's
> datapath and handled as if it had originated there. This can be used for
> mTLS, etc.
>
[...]
>
>    [ ID] Interval           Transfer     Bitrate         Retr
>    [  5]   0.00-60.00  sec   272 GBytes  38.9 Gbits/sec    0       sender
>    [  5]   0.00-60.00  sec   272 GBytes  38.9 Gbits/sec            receiver
>
> In this test, using bpf_redirect_peer(BPF_F_EGRESS) for the hop from
> [iperf pod] to [pod b] led to ~18% more throughput compared to
> bpf_redirect(BPF_F_INGRESS).
>
> Signed-off-by: Jordan Rife <jordan@jrife.io>
> ---
>   include/uapi/linux/bpf.h       | 19 +++++++++++--------
>   net/core/filter.c              | 12 +++++++-----
>   tools/include/uapi/linux/bpf.h | 19 +++++++++++--------
>   3 files changed, 29 insertions(+), 21 deletions(-)
>
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index 89b36de5fdbb..c91b5a4bda03 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -5079,17 +5079,19 @@ union bpf_attr {
>    * 	Description
>    * 		Redirect the packet to another net device of index *ifindex*.
>    * 		This helper is somewhat similar to **bpf_redirect**\ (), except
> - * 		that the redirection happens to the *ifindex*' peer device and
> - * 		the netns switch takes place from ingress to ingress without
> - * 		going through the CPU's backlog queue.
> + * 		that the redirection happens to the *ifindex*' peer device. If
> + * 		*flags* is 0, the netns switch takes place from ingress to
> + * 		ingress without going through the CPU's backlog queue. If the
> + * 		**BPF_F_EGRESS** flag is provided then redirection happens in
> + * 		the egress direction of the peer device.
>    *
>    * 		*skb*\ **->mark** and *skb*\ **->tstamp** are not cleared during
>    * 		the netns switch.
>    *
> - * 		The *flags* argument is reserved and must be 0. The helper is
> - * 		currently only supported for tc BPF program types at the
> - * 		ingress hook and for veth and netkit target device types. The
> - * 		peer device must reside in a different network namespace.
> + * 		If the *flags* argument is 0, the helper is currently only
> + * 		supported for tc BPF program types at the ingress hook and for
> + * 		veth and netkit target device types. The peer device must reside
> + * 		in a different network namespace.
>    * 	Return
>    * 		The helper returns **TC_ACT_REDIRECT** on success or
>    * 		**TC_ACT_SHOT** on error.
> @@ -6336,9 +6338,10 @@ enum {
>   /* Flags for bpf_redirect and bpf_redirect_map helpers */
>   enum {
>   	BPF_F_INGRESS		= (1ULL << 0), /* used for skb path */
> +	BPF_F_EGRESS		= (1ULL << 1), /* used for skb path */
>   	BPF_F_BROADCAST		= (1ULL << 3), /* used for XDP path */
>   	BPF_F_EXCLUDE_INGRESS	= (1ULL << 4), /* used for XDP path */
> -#define BPF_F_REDIRECT_FLAGS (BPF_F_INGRESS | BPF_F_BROADCAST | BPF_F_EXCLUDE_INGRESS)
> +#define BPF_F_REDIRECT_FLAGS (BPF_F_INGRESS | BPF_F_EGRESS | BPF_F_BROADCAST | BPF_F_EXCLUDE_INGRESS)
>   };
>   

Thanks, BPF_F_EGRESS is clearer.

Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>


^ permalink raw reply

* Re: [PATCH net v3 01/11] rxrpc: Fix ACKALL packet handling
From: Jeffrey E Altman @ 2026-06-25  3:31 UTC (permalink / raw)
  To: David Howells, netdev
  Cc: Marc Dionne, Jakub Kicinski, David S. Miller, Eric Dumazet,
	Paolo Abeni, Simon Horman, linux-afs, linux-kernel, Wyatt Feng,
	Yuan Tan, Yifan Wu, Juefei Pu, Zhengchuan Liang, Xin Liu, Ren Wei,
	stable
In-Reply-To: <20260624163819.3017002-2-dhowells@redhat.com>

On 6/24/2026 12:38 PM, David Howells wrote:

> From: Wyatt Feng <bronzed_45_vested@icloud.com>
>
> rxrpc_input_ackall() accepts ACKALL packets without checking whether the
> call is in a state that can legitimately have outstanding transmit buffers.
> A forged ACKALL can therefore reach a new service call in
> RXRPC_CALL_SERVER_RECV_REQUEST before any reply packets have been queued.
>
> In that state call->tx_top is zero and call->tx_queue is NULL, so
> rxrpc_rotate_tx_window() dereferences a NULL txqueue and triggers a
> null-pointer dereference.
>
> Fix the handling of ACKALL packets by the following means:
>
>   (1) Add two new call states: RXRPC_CALL_CLIENT_PRE_SEND which indicates
>       that the client call is connected, but nothing has been transmitted as
>       yet; and RXRPC_CALL_CLIENT_AWAIT_ACK, which indicates that everything
>       has been transmitted at least once, but we're now waiting for the
>       stuff remaining in the Tx buffer to be ACK'd (retransmissions may
>       still happen).
>
>       The RXRPC_CALL_CLIENT_PRE_SEND state is set when the call is assigned
>       a channel and transitions to RXRPC_CALL_CLIENT_SEND_REQUEST when the
>       first packet is transmitted.
>
>       RXRPC_CALL_CLIENT_AWAIT_REPLY is then narrowed in scope to indicate
>       that all Tx packets have been ACK'd and we're now waiting for the
>       reply to be received.
>
>   (2) As per Wyatt Feng's original patch[1], the ACKALL handler then checks
>       that the call state is one in which there might be stuff in the Tx
>       buffer to ACK, but now this includes AWAIT_ACK rather than
>       AWAIT_REPLY.  ACKALL packets are ignored if received in the wrong
>       state.
>
>       Note that unlike Wyatt Feng's patch, it's no longer necessary to check
>       to see if the Tx buffer exists as this the state set now covers this.
>
>   (3) Make the ACKALL handler use call->tx_transmitted rather than
>       call->tx_top as the former is explicitly the highest packet seq number
>       transmitted, whereas the latter has a looser definition.
>
> Thanks to Jeffrey Altman for a description of the history of the ACKALL
> packet[1].

The Link reference should be [2] instead of [1].

> Fixes: b341a0263b1b ("rxrpc: Implement progressive transmission queue struct")
> Reported-by: Yuan Tan <yuantan098@gmail.com>
> Reported-by: Yifan Wu <yifanwucs@gmail.com>
> Reported-by: Juefei Pu <tomapufckgml@gmail.com>
> Reported-by: Zhengchuan Liang <zcliangcn@gmail.com>
> Reported-by: Xin Liu <bird@lzu.edu.cn>
> Signed-off-by: Wyatt Feng <bronzed_45_vested@icloud.com>
> Co-developed-by: David Howells <dhowells@redhat.com>
> Signed-off-by: David Howells <dhowells@redhat.com>
> cc: Ren Wei <n05ec@lzu.edu.cn>
> cc: Marc Dionne <marc.dionne@auristor.com>
> cc: linux-afs@lists.infradead.org
> Cc: stable@vger.kernel.org
> Link: https://lore.kernel.org/r/20260616155749.2125907-2-dhowells@redhat.com/ [1]
> Link: https://lore.kernel.org/r/c0fd4fec-1576-4070-b31e-a37d5506f5ed@auristor.com/ [2]
> ---
>   net/rxrpc/ar-internal.h |  2 ++
>   net/rxrpc/call_event.c  |  5 ++++-
>   net/rxrpc/call_object.c |  2 ++
>   net/rxrpc/conn_client.c |  2 +-
>   net/rxrpc/input.c       | 23 +++++++++++++++++++----
>   net/rxrpc/sendmsg.c     |  3 ++-
>   6 files changed, 30 insertions(+), 7 deletions(-)
>
> diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
> index 98f2165159d7..b6ccd8a8199b 100644
> --- a/net/rxrpc/ar-internal.h
> +++ b/net/rxrpc/ar-internal.h
> @@ -650,7 +650,9 @@ enum rxrpc_call_event {
>   enum rxrpc_call_state {
>   	RXRPC_CALL_UNINITIALISED,
>   	RXRPC_CALL_CLIENT_AWAIT_CONN,	/* - client waiting for connection to become available */
> +	RXRPC_CALL_CLIENT_PRE_SEND,	/* - client is connected, but hasn't sent anything yet */
>   	RXRPC_CALL_CLIENT_SEND_REQUEST,	/* - client sending request phase */
> +	RXRPC_CALL_CLIENT_AWAIT_ACK,	/* - client awaiting ACKs of request */
>   	RXRPC_CALL_CLIENT_AWAIT_REPLY,	/* - client awaiting reply */
>   	RXRPC_CALL_CLIENT_RECV_REPLY,	/* - client receiving reply phase */
>   	RXRPC_CALL_SERVER_PREALLOC,	/* - service preallocation */
> diff --git a/net/rxrpc/call_event.c b/net/rxrpc/call_event.c
> index fec59d9338b9..21be9c86d7a7 100644
> --- a/net/rxrpc/call_event.c
> +++ b/net/rxrpc/call_event.c
> @@ -178,7 +178,7 @@ static void rxrpc_close_tx_phase(struct rxrpc_call *call)
>   
>   	switch (__rxrpc_call_state(call)) {
>   	case RXRPC_CALL_CLIENT_SEND_REQUEST:
> -		rxrpc_set_call_state(call, RXRPC_CALL_CLIENT_AWAIT_REPLY);
> +		rxrpc_set_call_state(call, RXRPC_CALL_CLIENT_AWAIT_ACK);
>   		break;
>   	case RXRPC_CALL_SERVER_SEND_REPLY:
>   		rxrpc_set_call_state(call, RXRPC_CALL_SERVER_AWAIT_ACK);
> @@ -244,6 +244,8 @@ static void rxrpc_transmit_fresh_data(struct rxrpc_call *call, unsigned int limi
>   				break;
>   		} while (req.n < limit && before(seq, send_top));
>   
> +		if (__rxrpc_call_state(call) == RXRPC_CALL_CLIENT_PRE_SEND)
> +			rxrpc_set_call_state(call, RXRPC_CALL_CLIENT_SEND_REQUEST);
>   		if (txb->flags & RXRPC_LAST_PACKET) {
>   			rxrpc_close_tx_phase(call);
>   			tq = NULL;
> @@ -267,6 +269,7 @@ void rxrpc_transmit_some_data(struct rxrpc_call *call, unsigned int limit,
>   		fallthrough;
>   
>   	case RXRPC_CALL_SERVER_SEND_REPLY:
> +	case RXRPC_CALL_CLIENT_PRE_SEND:
>   	case RXRPC_CALL_CLIENT_SEND_REQUEST:
>   		if (!rxrpc_tx_window_space(call))
>   			return;
> diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c
> index fcb9d38bb521..817ed9acb91e 100644
> --- a/net/rxrpc/call_object.c
> +++ b/net/rxrpc/call_object.c
> @@ -18,7 +18,9 @@
>   const char *const rxrpc_call_states[NR__RXRPC_CALL_STATES] = {
>   	[RXRPC_CALL_UNINITIALISED]		= "Uninit  ",
>   	[RXRPC_CALL_CLIENT_AWAIT_CONN]		= "ClWtConn",
> +	[RXRPC_CALL_CLIENT_PRE_SEND]		= "ClPreSnd",
>   	[RXRPC_CALL_CLIENT_SEND_REQUEST]	= "ClSndReq",
> +	[RXRPC_CALL_CLIENT_AWAIT_ACK]		= "ClAwtAck",
>   	[RXRPC_CALL_CLIENT_AWAIT_REPLY]		= "ClAwtRpl",
>   	[RXRPC_CALL_CLIENT_RECV_REPLY]		= "ClRcvRpl",
>   	[RXRPC_CALL_SERVER_PREALLOC]		= "SvPrealc",
> diff --git a/net/rxrpc/conn_client.c b/net/rxrpc/conn_client.c
> index 9b757798dedd..48519f0de185 100644
> --- a/net/rxrpc/conn_client.c
> +++ b/net/rxrpc/conn_client.c
> @@ -449,7 +449,7 @@ static void rxrpc_activate_one_channel(struct rxrpc_connection *conn,
>   	trace_rxrpc_connect_call(call);
>   	call->tx_last_sent = ktime_get_real();
>   	rxrpc_start_call_timer(call);
> -	rxrpc_set_call_state(call, RXRPC_CALL_CLIENT_SEND_REQUEST);
> +	rxrpc_set_call_state(call, RXRPC_CALL_CLIENT_PRE_SEND);
>   	wake_up(&call->waitq);
>   }
>   
> diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c
> index ce761466b02d..2eedab1b0919 100644
> --- a/net/rxrpc/input.c
> +++ b/net/rxrpc/input.c
> @@ -181,7 +181,8 @@ void rxrpc_congestion_degrade(struct rxrpc_call *call)
>   	if (call->cong_ca_state != RXRPC_CA_SLOW_START &&
>   	    call->cong_ca_state != RXRPC_CA_CONGEST_AVOIDANCE)
>   		return;
> -	if (__rxrpc_call_state(call) == RXRPC_CALL_CLIENT_AWAIT_REPLY)
> +	if (__rxrpc_call_state(call) == RXRPC_CALL_CLIENT_AWAIT_ACK ||
> +	    __rxrpc_call_state(call) == RXRPC_CALL_CLIENT_AWAIT_REPLY)
>   		return;
>   
>   	rtt = ns_to_ktime(call->srtt_us * (NSEC_PER_USEC / 8));
> @@ -356,6 +357,7 @@ static void rxrpc_end_tx_phase(struct rxrpc_call *call, bool reply_begun,
>   
>   	switch (__rxrpc_call_state(call)) {
>   	case RXRPC_CALL_CLIENT_SEND_REQUEST:
> +	case RXRPC_CALL_CLIENT_AWAIT_ACK:
>   	case RXRPC_CALL_CLIENT_AWAIT_REPLY:
>   		if (reply_begun) {
>   			rxrpc_set_call_state(call, RXRPC_CALL_CLIENT_RECV_REPLY);
> @@ -694,6 +696,7 @@ static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb)
>   
>   	switch (__rxrpc_call_state(call)) {
>   	case RXRPC_CALL_CLIENT_SEND_REQUEST:
> +	case RXRPC_CALL_CLIENT_AWAIT_ACK:
>   	case RXRPC_CALL_CLIENT_AWAIT_REPLY:
>   		/* Received data implicitly ACKs all of the request
>   		 * packets we sent when we're acting as a client.
> @@ -1154,10 +1157,12 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb)
>   	if (hard_ack + 1 == 0)
>   		return rxrpc_proto_abort(call, 0, rxrpc_eproto_ackr_zero);
>   
> -	/* Ignore ACKs unless we are or have just been transmitting. */
> +	/* Ignore ACKs unless we are transmitting or are waiting for
> +	 * acknowledgement of the packets we've just been transmitting.
> +	 */
>   	switch (__rxrpc_call_state(call)) {
>   	case RXRPC_CALL_CLIENT_SEND_REQUEST:
> -	case RXRPC_CALL_CLIENT_AWAIT_REPLY:
> +	case RXRPC_CALL_CLIENT_AWAIT_ACK:
>   	case RXRPC_CALL_SERVER_SEND_REPLY:
>   	case RXRPC_CALL_SERVER_AWAIT_ACK:
>   		break;
> @@ -1215,7 +1220,17 @@ static void rxrpc_input_ackall(struct rxrpc_call *call, struct sk_buff *skb)
>   {
>   	struct rxrpc_ack_summary summary = { 0 };
>   
> -	if (rxrpc_rotate_tx_window(call, call->tx_top, &summary))
> +	switch (__rxrpc_call_state(call)) {
> +	case RXRPC_CALL_CLIENT_SEND_REQUEST:
> +	case RXRPC_CALL_CLIENT_AWAIT_ACK:
> +	case RXRPC_CALL_SERVER_SEND_REPLY:
> +	case RXRPC_CALL_SERVER_AWAIT_ACK:
> +		break;
> +	default:
> +		return;
> +	}
> +
> +	if (rxrpc_rotate_tx_window(call, call->tx_transmitted, &summary))
>   		rxrpc_end_tx_phase(call, false, rxrpc_eproto_unexpected_ackall);
>   }
>   
> diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c
> index c35de4fd75e3..ed2c9a51005a 100644
> --- a/net/rxrpc/sendmsg.c
> +++ b/net/rxrpc/sendmsg.c
> @@ -366,7 +366,8 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
>   	if (state >= RXRPC_CALL_COMPLETE)
>   		goto maybe_error;
>   	ret = -EPROTO;
> -	if (state != RXRPC_CALL_CLIENT_SEND_REQUEST &&
> +	if (state != RXRPC_CALL_CLIENT_PRE_SEND &&
> +	    state != RXRPC_CALL_CLIENT_SEND_REQUEST &&
>   	    state != RXRPC_CALL_SERVER_ACK_REQUEST &&
>   	    state != RXRPC_CALL_SERVER_SEND_REPLY) {
>   		/* Request phase complete for this client call */
>
Thanks for the update patch.

Reviewed-by: Jeffrey Altman <jaltman@auristor.com>




^ permalink raw reply

* [PATCH v5] net: mvneta_bm: add suspend/resume support to prevent crash after resume
From: Yun Zhou @ 2026-06-25  3:09 UTC (permalink / raw)
  To: marcin.s.wojtas, andrew+netdev, davem, edumazet, kuba, pabeni
  Cc: netdev, linux-kernel, yun.zhou

The mvneta driver uses the hardware Buffer Manager (BM) for RX buffer
allocation. During suspend, mvneta disables its clock, causing BM to
lose all buffer address state. On resume, mvneta_bm_port_init() re-
attaches the BM pool to the NIC, but BM hardware returns stale/garbage
buffer addresses. When NAPI poll processes these buffers, DMA cache
sync hits an invalid virtual address causing a kernel panic:

 Unable to handle kernel paging request at virtual address b0000080
 PC is at v7_dma_inv_range
 Call trace:
  v7_dma_inv_range from arch_sync_dma_for_cpu+0x94/0x158
  arch_sync_dma_for_cpu from __dma_sync_single_for_cpu+0xc4/0x15c
  __dma_sync_single_for_cpu from mvneta_rx_swbm+0x6c8/0xf48
  mvneta_rx_swbm from mvneta_poll+0x6fc/0x70c
  mvneta_poll from __napi_poll.constprop.0+0x2c/0x1e0
  __napi_poll.constprop.0 from net_rx_action+0x160/0x2c4
  net_rx_action from handle_softirqs+0xd8/0x2b8
  handle_softirqs from run_ksoftirqd+0x30/0x94
  run_ksoftirqd from smpboot_thread_fn+0x100/0x204
  smpboot_thread_fn from kthread+0xf4/0x110
  kthread from ret_from_fork+0x14/0x28

Fix by adding suspend/resume callbacks to the BM driver:

- suspend: drain all buffers (with DMA unmapping), free the BPPE
  regions, and reset pool state to FREE before stopping BM and gating
  the clock.

- resume: enable the clock, reinitialize BM defaults, and restore pool
  read/write pointers and size registers. Pool allocation and buffer
  refill are handled by mvneta_resume() through the normal
  mvneta_bm_port_init() path, which sees pools as FREE and performs
  full initialization identical to probe.

Add a device_link (DL_FLAG_AUTOREMOVE_CONSUMER) in mvneta_probe to
guarantee BM resumes before mvneta and suspends after mvneta. If the
link cannot be created, fall back to SW buffer management to avoid a
potential crash on resume due to unordered PM transitions.

Signed-off-by: Yun Zhou <yun.zhou@windriver.com>
---
v5:
  - Call mvneta_bm_pool_disable() per pool before dma_free_coherent()
    in suspend, matching mvneta_bm_pool_destroy() ordering. This also
    ensures ENABLE_MASK is cleared before BM START on resume.
  - Guard dma_free_coherent() with if (bm_pool->virt_addr) to defend
    against a partially-failed mvneta_bm_pool_create() leaving a stale
    pointer.

v4:
  - On device_link_add() failure, fall back to SW buffer management
    (destroy pools, put BM reference, clear bm_priv) instead of merely
    emitting a warning. Without the link, suspend/resume ordering is
    not guaranteed and the original crash can still occur.

v3:
  - Restore per-pool POOL_SIZE_REG, POOL_READ_PTR_REG, and
    POOL_WRITE_PTR_REG in resume, since clock gating loses all BM
    register state.
  - Check device_link_add() return value and emit dev_warn on failure.
  - Replace SIMPLE_DEV_PM_OPS (deprecated) with
    DEFINE_SIMPLE_DEV_PM_OPS and pm_sleep_ptr(), removing the
    #ifdef CONFIG_PM_SLEEP guard.
  - Add dev_warn in suspend if not all buffers could be freed.

v2:
  - Drain buffers via mvneta_bm_bufs_free() in suspend instead of only
    stopping BM and gating the clock. This ensures proper DMA unmapping
    and avoids buffer leaks.
  - Free the BPPE DMA-coherent region in suspend so that resume takes
    the full probe-time initialization path (alloc + fill), eliminating
    the need to modify mvneta_bm_pool_create().
  - Reset pool type to MVNETA_BM_FREE in suspend so mvneta_bm_pool_use()
    correctly re-creates and refills pools on resume.
  - Check clk_prepare_enable() return value in resume.
  - Add device_link between mvneta (consumer) and mvneta_bm (supplier)
    to guarantee correct suspend/resume ordering.

 drivers/net/ethernet/marvell/mvneta.c    | 18 +++++++
 drivers/net/ethernet/marvell/mvneta_bm.c | 63 ++++++++++++++++++++++++
 2 files changed, 81 insertions(+)

diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 744d6585a949..543e566425c1 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -5678,6 +5678,24 @@ static int mvneta_probe(struct platform_device *pdev)
 					 "use SW buffer management\n");
 				mvneta_bm_put(pp->bm_priv);
 				pp->bm_priv = NULL;
+			} else if (!device_link_add(&pdev->dev,
+						    &pp->bm_priv->pdev->dev,
+						    DL_FLAG_AUTOREMOVE_CONSUMER)) {
+				/*
+				 * Link guarantees BM resumes before mvneta.
+				 * Without it, BM may not be ready when
+				 * mvneta_bm_port_init() runs on resume,
+				 * causing stale buffer addresses and a crash.
+				 * Fall back to SW management to be safe.
+				 */
+				dev_warn(&pdev->dev,
+					 "failed to link to BM, use SW buffer management\n");
+				mvneta_bm_pool_destroy(pp->bm_priv,
+						       pp->pool_long, 1 << pp->id);
+				mvneta_bm_pool_destroy(pp->bm_priv,
+						       pp->pool_short, 1 << pp->id);
+				mvneta_bm_put(pp->bm_priv);
+				pp->bm_priv = NULL;
 			}
 		}
 		/* Set RX packet offset correction for platforms, whose
diff --git a/drivers/net/ethernet/marvell/mvneta_bm.c b/drivers/net/ethernet/marvell/mvneta_bm.c
index 6bb380494919..c23982bfc20b 100644
--- a/drivers/net/ethernet/marvell/mvneta_bm.c
+++ b/drivers/net/ethernet/marvell/mvneta_bm.c
@@ -477,6 +477,68 @@ static void mvneta_bm_remove(struct platform_device *pdev)
 	clk_disable_unprepare(priv->clk);
 }
 
+static int mvneta_bm_suspend(struct device *dev)
+{
+	struct mvneta_bm *priv = dev_get_drvdata(dev);
+	int i;
+
+	/* Drain buffers and free pool resources while BM is still clocked */
+	for (i = 0; i < MVNETA_BM_POOLS_NUM; i++) {
+		struct mvneta_bm_pool *bm_pool = &priv->bm_pools[i];
+		int size_bytes;
+
+		if (bm_pool->type == MVNETA_BM_FREE)
+			continue;
+
+		mvneta_bm_bufs_free(priv, bm_pool, bm_pool->port_map);
+		if (bm_pool->hwbm_pool.buf_num)
+			dev_warn(&priv->pdev->dev,
+				 "pool %d: %d buffers not freed\n",
+				 bm_pool->id, bm_pool->hwbm_pool.buf_num);
+
+		mvneta_bm_pool_disable(priv, bm_pool->id);
+
+		if (bm_pool->virt_addr) {
+			size_bytes = sizeof(u32) * bm_pool->hwbm_pool.size;
+			dma_free_coherent(&priv->pdev->dev, size_bytes,
+					  bm_pool->virt_addr,
+					  bm_pool->phys_addr);
+			bm_pool->virt_addr = NULL;
+		}
+		bm_pool->type = MVNETA_BM_FREE;
+	}
+
+	mvneta_bm_write(priv, MVNETA_BM_COMMAND_REG, MVNETA_BM_STOP_MASK);
+	clk_disable_unprepare(priv->clk);
+	return 0;
+}
+
+static int mvneta_bm_resume(struct device *dev)
+{
+	struct mvneta_bm *priv = dev_get_drvdata(dev);
+	int i, err;
+
+	err = clk_prepare_enable(priv->clk);
+	if (err)
+		return err;
+
+	/* Reinitialize BM hardware; pools are refilled by mvneta_resume() */
+	mvneta_bm_default_set(priv);
+
+	/* Restore pool registers lost during clock gating */
+	for (i = 0; i < MVNETA_BM_POOLS_NUM; i++) {
+		mvneta_bm_write(priv, MVNETA_BM_POOL_READ_PTR_REG(i), 0);
+		mvneta_bm_write(priv, MVNETA_BM_POOL_WRITE_PTR_REG(i), 0);
+		mvneta_bm_write(priv, MVNETA_BM_POOL_SIZE_REG(i),
+				priv->bm_pools[i].hwbm_pool.size);
+	}
+
+	mvneta_bm_write(priv, MVNETA_BM_COMMAND_REG, MVNETA_BM_START_MASK);
+	return 0;
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(mvneta_bm_pm_ops, mvneta_bm_suspend, mvneta_bm_resume);
+
 static const struct of_device_id mvneta_bm_match[] = {
 	{ .compatible = "marvell,armada-380-neta-bm" },
 	{ }
@@ -489,6 +551,7 @@ static struct platform_driver mvneta_bm_driver = {
 	.driver = {
 		.name = MVNETA_BM_DRIVER_NAME,
 		.of_match_table = mvneta_bm_match,
+		.pm = pm_sleep_ptr(&mvneta_bm_pm_ops),
 	},
 };
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH] net: pch_gbe: return errors from MIIM accesses
From: Pengpeng Hou @ 2026-06-25  3:05 UTC (permalink / raw)
  To: Andrew Lunn, davem, Eric Dumazet, Jakub Kicinski, Paolo Abeni
  Cc: netdev, linux-kernel, pengpeng

pch_gbe_mac_ctrl_miim() polls for the MIIM controller to become ready,
but returns zero on the initial ready timeout and ignores the completion
timeout after issuing the operation. MDIO and PHY helpers can then report
success with zero or stale data.

Make the MIIM helper return an errno and pass read data through an output
parameter. Propagate the error through the MDIO read path, the probe-time
PHY discovery path, and the internal PHY register helpers that already
return an error status.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
 .../net/ethernet/oki-semi/pch_gbe/pch_gbe.h   |  4 +-
 .../ethernet/oki-semi/pch_gbe/pch_gbe_main.c  | 54 ++++++++++++++-----
 .../ethernet/oki-semi/pch_gbe/pch_gbe_phy.c   | 22 +++++---
 3 files changed, 57 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h
index 108f312bc542..4bdf0afca462 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h
@@ -619,6 +619,6 @@ void pch_gbe_set_ethtool_ops(struct net_device *netdev);
 
 /* pch_gbe_mac.c */
 s32 pch_gbe_mac_force_mac_fc(struct pch_gbe_hw *hw);
-u16 pch_gbe_mac_ctrl_miim(struct pch_gbe_hw *hw, u32 addr, u32 dir, u32 reg,
-			  u16 data);
+int pch_gbe_mac_ctrl_miim(struct pch_gbe_hw *hw, u32 addr, u32 dir, u32 reg,
+			  u16 data, u16 *read_data);
 #endif /* _PCH_GBE_H_ */
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index 62f05f4569b1..61d47b529a0e 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -476,35 +476,48 @@ static void pch_gbe_mac_set_wol_event(struct pch_gbe_hw *hw, u32 wu_evt)
  * @dir:  Operetion. (Write or Read)
  * @reg:  Access register of PHY
  * @data: Write data.
+ * @read_data: Read data.
  *
- * Returns: Read date.
+ * Return: 0 on success, negative error code on failure.
  */
-u16 pch_gbe_mac_ctrl_miim(struct pch_gbe_hw *hw, u32 addr, u32 dir, u32 reg,
-			u16 data)
+int pch_gbe_mac_ctrl_miim(struct pch_gbe_hw *hw, u32 addr, u32 dir, u32 reg,
+			  u16 data, u16 *read_data)
 {
 	struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
 	unsigned long flags;
 	u32 data_out;
+	int ret;
 
 	spin_lock_irqsave(&hw->miim_lock, flags);
 
-	if (readx_poll_timeout_atomic(ioread32, &hw->reg->MIIM, data_out,
-				      data_out & PCH_GBE_MIIM_OPER_READY, 20, 2000)) {
+	ret = readx_poll_timeout_atomic(ioread32, &hw->reg->MIIM, data_out,
+					data_out & PCH_GBE_MIIM_OPER_READY, 20,
+					2000);
+	if (ret) {
 		netdev_err(adapter->netdev, "pch-gbe.miim won't go Ready\n");
 		spin_unlock_irqrestore(&hw->miim_lock, flags);
-		return 0;	/* No way to indicate timeout error */
+		return ret;
 	}
 	iowrite32(((reg << PCH_GBE_MIIM_REG_ADDR_SHIFT) |
 		  (addr << PCH_GBE_MIIM_PHY_ADDR_SHIFT) |
 		  dir | data), &hw->reg->MIIM);
-	readx_poll_timeout_atomic(ioread32, &hw->reg->MIIM, data_out,
-				  data_out & PCH_GBE_MIIM_OPER_READY, 20, 2000);
+	ret = readx_poll_timeout_atomic(ioread32, &hw->reg->MIIM, data_out,
+					data_out & PCH_GBE_MIIM_OPER_READY, 20,
+					2000);
+	if (ret) {
+		netdev_err(adapter->netdev, "pch-gbe.miim operation timed out\n");
+		spin_unlock_irqrestore(&hw->miim_lock, flags);
+		return ret;
+	}
 	spin_unlock_irqrestore(&hw->miim_lock, flags);
 
 	netdev_dbg(adapter->netdev, "PHY %s: reg=%d, data=0x%04X\n",
 		   dir == PCH_GBE_MIIM_OPER_READ ? "READ" : "WRITE", reg,
 		   dir == PCH_GBE_MIIM_OPER_READ ? data_out : data);
-	return (u16) data_out;
+	if (dir == PCH_GBE_MIIM_OPER_READ && read_data)
+		*read_data = (u16)data_out;
+
+	return 0;
 }
 
 /**
@@ -589,14 +602,20 @@ static int pch_gbe_init_phy(struct pch_gbe_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
 	u32 addr;
-	u16 bmcr, stat;
+	int bmcr, stat;
 
 	/* Discover phy addr by searching addrs in order {1,0,2,..., 31} */
 	for (addr = 0; addr < PCH_GBE_PHY_REGS_LEN; addr++) {
 		adapter->mii.phy_id = (addr == 0) ? 1 : (addr == 1) ? 0 : addr;
 		bmcr = pch_gbe_mdio_read(netdev, adapter->mii.phy_id, MII_BMCR);
+		if (bmcr < 0)
+			return bmcr;
 		stat = pch_gbe_mdio_read(netdev, adapter->mii.phy_id, MII_BMSR);
+		if (stat < 0)
+			return stat;
 		stat = pch_gbe_mdio_read(netdev, adapter->mii.phy_id, MII_BMSR);
+		if (stat < 0)
+			return stat;
 		if (!((bmcr == 0xFFFF) || ((stat == 0) && (bmcr == 0))))
 			break;
 	}
@@ -611,6 +630,8 @@ static int pch_gbe_init_phy(struct pch_gbe_adapter *adapter)
 					   BMCR_ISOLATE);
 		} else {
 			bmcr = pch_gbe_mdio_read(netdev, addr, MII_BMCR);
+			if (bmcr < 0)
+				return bmcr;
 			pch_gbe_mdio_write(netdev, addr, MII_BMCR,
 					   bmcr & ~BMCR_ISOLATE);
 		}
@@ -639,9 +660,15 @@ static int pch_gbe_mdio_read(struct net_device *netdev, int addr, int reg)
 {
 	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
 	struct pch_gbe_hw *hw = &adapter->hw;
+	u16 data;
+	int ret;
+
+	ret = pch_gbe_mac_ctrl_miim(hw, addr, PCH_GBE_HAL_MIIM_READ, reg,
+				    0, &data);
+	if (ret)
+		return ret;
 
-	return pch_gbe_mac_ctrl_miim(hw, addr, PCH_GBE_HAL_MIIM_READ, reg,
-				     (u16) 0);
+	return data;
 }
 
 /**
@@ -657,7 +684,8 @@ static void pch_gbe_mdio_write(struct net_device *netdev,
 	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
 	struct pch_gbe_hw *hw = &adapter->hw;
 
-	pch_gbe_mac_ctrl_miim(hw, addr, PCH_GBE_HAL_MIIM_WRITE, reg, data);
+	pch_gbe_mac_ctrl_miim(hw, addr, PCH_GBE_HAL_MIIM_WRITE, reg, data,
+			      NULL);
 }
 
 /**
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.c
index 3426f6fa2b57..edf3644f7589 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.c
@@ -139,9 +139,10 @@ s32 pch_gbe_phy_read_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 *data)
 			   offset);
 		return -EINVAL;
 	}
-	*data = pch_gbe_mac_ctrl_miim(hw, phy->addr, PCH_GBE_HAL_MIIM_READ,
-				      offset, (u16)0);
-	return 0;
+
+	*data = 0;
+	return pch_gbe_mac_ctrl_miim(hw, phy->addr, PCH_GBE_HAL_MIIM_READ,
+				     offset, 0, data);
 }
 
 /**
@@ -164,9 +165,8 @@ s32 pch_gbe_phy_write_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 data)
 			   offset);
 		return -EINVAL;
 	}
-	pch_gbe_mac_ctrl_miim(hw, phy->addr, PCH_GBE_HAL_MIIM_WRITE,
-				 offset, data);
-	return 0;
+	return pch_gbe_mac_ctrl_miim(hw, phy->addr, PCH_GBE_HAL_MIIM_WRITE,
+				     offset, data, NULL);
 }
 
 /**
@@ -266,13 +266,19 @@ static int pch_gbe_phy_tx_clk_delay(struct pch_gbe_hw *hw)
 	case PHY_AR803X_ID:
 		netdev_dbg(adapter->netdev,
 			   "Configuring AR803X PHY for 2ns TX clock delay\n");
-		pch_gbe_phy_read_reg_miic(hw, PHY_AR8031_DBG_OFF, &mii_reg);
+		ret = pch_gbe_phy_read_reg_miic(hw, PHY_AR8031_DBG_OFF,
+						&mii_reg);
+		if (ret)
+			break;
 		ret = pch_gbe_phy_write_reg_miic(hw, PHY_AR8031_DBG_OFF,
 						 PHY_AR8031_SERDES);
 		if (ret)
 			break;
 
-		pch_gbe_phy_read_reg_miic(hw, PHY_AR8031_DBG_DAT, &mii_reg);
+		ret = pch_gbe_phy_read_reg_miic(hw, PHY_AR8031_DBG_DAT,
+						&mii_reg);
+		if (ret)
+			break;
 		mii_reg |= PHY_AR8031_SERDES_TX_CLK_DLY;
 		ret = pch_gbe_phy_write_reg_miic(hw, PHY_AR8031_DBG_DAT,
 						 mii_reg);
-- 
2.50.1 (Apple Git-155)


^ permalink raw reply related

* [PATCH] ice: propagate ETH56G deskew read errors
From: Pengpeng Hou @ 2026-06-25  3:03 UTC (permalink / raw)
  To: Tony Nguyen, Przemek Kitszel
  Cc: Andrew Lunn, davem, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Richard Cochran, intel-wired-lan, netdev, linux-kernel, pengpeng

ice_ptp_calc_deskew_eth56g() returns a u32 deskew value, but it also
returns the negative read_poll_timeout() error when the DESKEW valid bit
never appears. That converts the negative error into a large unsigned
deskew contribution, which can then be folded into the RX timestamp
offset and programmed into hardware.

Return the deskew value through an output parameter and propagate the
read error from ice_phy_set_offsets_eth56g() instead of using it as
offset data.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
 drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 27 +++++++++++++++------
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
index 8e5f97835954..bd2e31b816a8 100644
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
@@ -1736,17 +1736,21 @@ static u32 ice_ptp_calc_bitslip_eth56g(struct ice_hw *hw, u8 port, u32 bs,
  * @ds: deskew multiplier
  * @rs: RS-FEC enabled
  * @spd: link speed
+ * @deskew: calculated deskew value
  *
- * Return: calculated deskew value
+ * Return: 0 on success, negative error code otherwise
  */
-static u32 ice_ptp_calc_deskew_eth56g(struct ice_hw *hw, u8 port, u32 ds,
-				      bool rs, enum ice_eth56g_link_spd spd)
+static int ice_ptp_calc_deskew_eth56g(struct ice_hw *hw, u8 port, u32 ds,
+				      bool rs, enum ice_eth56g_link_spd spd,
+				      u32 *deskew)
 {
 	u32 deskew_i, deskew_f;
 	int err;
 
-	if (!ds)
+	if (!ds) {
+		*deskew = 0;
 		return 0;
+	}
 
 	read_poll_timeout(ice_read_ptp_reg_eth56g, err,
 			  FIELD_GET(PHY_REG_DESKEW_0_VALID, deskew_i), 500,
@@ -1766,7 +1770,9 @@ static u32 ice_ptp_calc_deskew_eth56g(struct ice_hw *hw, u8 port, u32 ds,
 	deskew_i = FIELD_PREP(ICE_ETH56G_MAC_CFG_RX_OFFSET_INT, deskew_i);
 	/* Shift 3 fractional bits to the end of the integer part */
 	deskew_f <<= ICE_ETH56G_MAC_CFG_FRAC_W - PHY_REG_DESKEW_0_RLEVEL_FRAC_W;
-	return mul_u32_u32_fx_q9(deskew_i | deskew_f, ds);
+	*deskew = mul_u32_u32_fx_q9(deskew_i | deskew_f, ds);
+
+	return 0;
 }
 
 /**
@@ -1789,6 +1795,7 @@ static int ice_phy_set_offsets_eth56g(struct ice_hw *hw, u8 port,
 {
 	u32 rx_offset, tx_offset, bs_ds;
 	bool onestep, sfd;
+	int err;
 
 	onestep = hw->ptp.phy.eth56g.onestep_ena;
 	sfd = hw->ptp.phy.eth56g.sfd_ena;
@@ -1805,11 +1812,15 @@ static int ice_phy_set_offsets_eth56g(struct ice_hw *hw, u8 port,
 	if (sfd)
 		rx_offset = add_u32_u32_fx(rx_offset, cfg->rx_offset.sfd);
 
-	if (spd < ICE_ETH56G_LNK_SPD_40G)
+	if (spd < ICE_ETH56G_LNK_SPD_40G) {
 		bs_ds = ice_ptp_calc_bitslip_eth56g(hw, port, bs_ds, fc, rs,
 						    spd);
-	else
-		bs_ds = ice_ptp_calc_deskew_eth56g(hw, port, bs_ds, rs, spd);
+	} else {
+		err = ice_ptp_calc_deskew_eth56g(hw, port, bs_ds, rs, spd,
+						 &bs_ds);
+		if (err)
+			return err;
+	}
 	rx_offset = add_u32_u32_fx(rx_offset, bs_ds);
 	rx_offset &= ICE_ETH56G_MAC_CFG_RX_OFFSET_INT |
 		     ICE_ETH56G_MAC_CFG_RX_OFFSET_FRAC;
-- 
2.50.1 (Apple Git-155)


^ permalink raw reply related

* Re: [PATCH v3 1/7] list: Add mutable iterator variants
From: Kaitao Cheng @ 2026-06-25  3:01 UTC (permalink / raw)
  To: David Laight, Christian König, Jani Nikula,
	David Hildenbrand (Arm), Alexei Starovoitov
  Cc: Andrew Morton, David Hildenbrand, Jens Axboe, Tejun Heo,
	Alexander Viro, Christian Brauner, Daniel Borkmann,
	Andrii Nakryiko, Johannes Weiner, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Namhyung Kim, Thomas Gleixner,
	Juri Lelli, Vincent Guittot, Paul Moore, Andy Shevchenko,
	Paul E. McKenney, Shakeel Butt, David Howells, Simona Vetter,
	Randy Dunlap, Luca Ceresoli, Philipp Stanner, linux-block,
	linux-kernel, cgroups, linux-ntfs-dev, linux-fsdevel, io-uring,
	audit, bpf, netdev, dri-devel, linux-perf-users,
	linux-trace-kernel, kexec, live-patching, linux-modules,
	linux-crypto, linux-pm, rcu, sched-ext, linux-mm, virtualization,
	damon, llvm, Kaitao Cheng, Muchun Song
In-Reply-To: <20260624152324.3def88ce@pumpkin>

在 2026/6/24 22:23, David Laight 写道:
> On Wed, 24 Jun 2026 15:23:47 +0200
> Christian König <christian.koenig@amd.com> wrote:
>> On 6/24/26 15:14, Kaitao Cheng wrote:
>>> 在 2026/6/22 16:42, David Laight 写道:  
>>>> On Mon, 22 Jun 2026 12:05:31 +0800
>>>> Kaitao Cheng <kaitao.cheng@linux.dev> wrote:
>>>>  
>>>>> From: Kaitao Cheng <chengkaitao@kylinos.cn>
>>>>>
>>>>> The list_for_each*_safe() helpers are used when the loop body may
>>>>> remove the current entry.  Their API exposes the temporary cursor at
>>>>> every call site, even though most users only need it for the iterator
>>>>> implementation and never reference it in the loop body.
>>>>>
>>>>> Add *_mutable() variants for list and hlist iteration.  The new helpers
>>>>> support both forms: callers may keep passing an explicit temporary cursor
>>>>> when they need to inspect or reset it, or omit it and let the helper use
>>>>> a unique internal cursor.  
>>>>
>>>> I'm not really sure 'mutable' means anything either.
>>>> It is possible to make it valid for the loop body (or even other threads)
>>>> to delete arbitrary list items - but that needs significant extra overheads.
>>>>
>>>> It might be worth doing something that doesn't need the extra variable,
>>>> but there is little point doing all the churn just to rename things.
>>>>  
>>>>>
>>>>> This makes call sites that only mutate the list through the current entry
>>>>> less noisy, while keeping the existing *_safe() helpers available for
>>>>> compatibility.
>>>>>
>>>>> Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
>>>>> ---
>>>>>  include/linux/list.h | 269 +++++++++++++++++++++++++++++++++++++------
>>>>>  1 file changed, 231 insertions(+), 38 deletions(-)
>>>>>
>>>>> diff --git a/include/linux/list.h b/include/linux/list.h
>>>>> index 09d979976b3b..1081def7cea9 100644
>>>>> --- a/include/linux/list.h
>>>>> +++ b/include/linux/list.h
>>>>> @@ -7,6 +7,7 @@
>>>>>  #include <linux/stddef.h>
>>>>>  #include <linux/poison.h>
>>>>>  #include <linux/const.h>
>>>>> +#include <linux/args.h>
>>>>>  
>>>>>  #include <asm/barrier.h>
>>>>>  
>>>>> @@ -763,28 +764,72 @@ static inline void list_splice_tail_init(struct list_head *list,
>>>>>  #define list_for_each_prev(pos, head) \
>>>>>  	for (pos = (head)->prev; !list_is_head(pos, (head)); pos = pos->prev)
>>>>>  
>>>>> -/**
>>>>> - * list_for_each_safe - iterate over a list safe against removal of list entry
>>>>> - * @pos:	the &struct list_head to use as a loop cursor.
>>>>> - * @n:		another &struct list_head to use as temporary storage
>>>>> - * @head:	the head for your list.
>>>>> +/*
>>>>> + * list_for_each_safe is an old interface, use list_for_each_mutable instead.
>>>>>   */
>>>>>  #define list_for_each_safe(pos, n, head) \
>>>>>  	for (pos = (head)->next, n = pos->next; \
>>>>>  	     !list_is_head(pos, (head)); \
>>>>>  	     pos = n, n = pos->next)
>>>>>  
>>>>> +#define __list_for_each_mutable_internal(pos, tmp, head)		\
>>>>> +	for (typeof(pos) tmp = (pos = (head)->next)->next;		\  
>>>>
>>>> Use auto
>>>>  
>>>>> +	     !list_is_head(pos, (head));				\
>>>>> +	     pos = tmp, tmp = pos->next)
>>>>> +
>>>>> +#define __list_for_each_mutable1(pos, head)				\
>>>>> +	__list_for_each_mutable_internal(pos, __UNIQUE_ID(next), head)
>>>>> +
>>>>> +#define __list_for_each_mutable2(pos, next, head)			\
>>>>> +	list_for_each_safe(pos, next, head)
>>>>> +
>>>>>  /**
>>>>> - * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
>>>>> + * list_for_each_mutable - iterate over a list safe against entry removal
>>>>>   * @pos:	the &struct list_head to use as a loop cursor.
>>>>> - * @n:		another &struct list_head to use as temporary storage
>>>>> - * @head:	the head for your list.
>>>>> + * @...:	either (head) or (next, head)
>>>>> + *
>>>>> + * next:	another &struct list_head to use as optional temporary storage.
>>>>> + *		The temporary cursor is internal unless explicitly supplied by
>>>>> + *		the caller.
>>>>> + * head:	the head for your list.
>>>>> + */
>>>>> +#define list_for_each_mutable(pos, ...)					\
>>>>> +	CONCATENATE(__list_for_each_mutable, COUNT_ARGS(__VA_ARGS__))	\
>>>>> +		(pos, __VA_ARGS__)  
>>>>
>>>> The variable argument count logic really just slows down compilation.
>>>> Maybe there aren't enough copies of this code to make that significant.
>>>> But just because you can do it doesn't mean it is a gooD idea.
>>>> I'm also not sure it really adds anything to the readability.
>>>>
>>>> And, it you are going to make the middle argument optional there is
>>>> no need to change the macro name.  
>>>
>>> Christian König and Jani Nikula also disagree with the variadic-argument
>>> implementation approach. If we abandon that method, it means we will
>>> inevitably need to add some new macros. If mutable is not a good name,
>>> suggestions for better alternatives would be welcome; coming up with a
>>> suitable name is indeed rather tricky.  
>>
>> I don't think you need to add a new macro for the specific use case that people want to modify the next element of the iteration.
>>
>> If I remember your numbers correctly that is a really corner case and keeping using the existing *_safe() macros for that sounds perfectly fine to me.
> 
> IIRC currently you have a choice of either:
> 	define               Item that can't be deleted
> 	list_for_each()	     The current item.
> 	list_for_each_safe() The next item.
> There is also likely to be code that updates the variables to allow
> for other scenarios.
> 
> Note that if increase a reference count and release a lock then list_for_each()
> is likely safer than list_for_each_safe() :-)
> 
> list.h has 9 variants of the 'safe' loop.
> The bloat of another 9 is getting excessive.
> 
> It has to be said that this is one of my least favourite type of list...

Hi Christian König, David Laight, Jani Nikula, David Hildenbrand,
Andy Shevchenko, Alexei Starovoitov

For ease of discussion, I need to summarize the currently possible
approaches and briefly describe their respective pros and cons,
using the list_for_each_entry* interfaces as examples.

1. Add list_for_each_entry_mutable, while keeping list_for_each_entry
and list_for_each_entry_safe unchanged. list_for_each_entry_mutable
would be used specifically for safe deletion scenarios that do not
need to expose the temporary cursor externally. The code can refer to
the v1 version.

Pros: Does not depend on immediate per-subsystem adaptation and can be
      merged directly.
Cons: Requires adding a whole set of mutable interfaces, which makes the
      code somewhat redundant.

2. Directly optimize away the temporary cursor in list_for_each_entry_safe
and define it inside the loop instead, changing the interface from four
arguments to three.

Pros: Does not add redundant interfaces.
Cons: (1) Users need to manually update special cases that use the
      traversal variable of list_for_each_entry_safe, the new
      list_for_each_entry_safe would no longer apply there and would
      need to be open-coded.
      (2) Because the macro arguments changes, all list_for_each_entry_safe
      callers would need to be modified and merged together, making it
      difficult to merge such a large amount of code at once.

3. Use a variadic macro approach to optimize list_for_each_entry_safe,
so that it supports both three and four arguments.

Pros: (1) Does not add redundant interfaces.
      (2) Does not depend on immediate per-subsystem adaptation and can
      be merged directly.
Cons: (1) Increases compile time.
      (2) Makes the interface harder for users to use.

4. Optimize list_for_each_entry by defining the temporary cursor internally,
making it compatible with the functionality of list_for_each_entry_safe.
The code can refer to the v2 version.

Pros: (1) Does not add redundant interfaces.
      (2) The number of externally visible arguments of list_for_each_entry
      remains unchanged, still three.
Cons: (1) list_for_each_entry and list_for_each_entry_safe would be merged
      into one, and list_for_each_entry_safe would gradually be deprecated.
      (2) Users need to manually update special cases that use the traversal
      variable of list_for_each_entry, the new list_for_each_entry would no
      longer apply there and would need to be open-coded. There are 15 such
      cases in total.

5. Use a variadic macro approach to optimize list_for_each_entry, so that
it supports both three and four arguments.

Pros: (1) Does not add redundant interfaces.
      (2) Does not depend on immediate per-subsystem adaptation and can be
      merged directly.
Cons: (1) Increases compile time.
      (2) list_for_each_entry and list_for_each_entry_safe would be merged
      into one, and list_for_each_entry_safe would gradually be deprecated.

6. Make no changes, keep the current logic unchanged, and close the current
email discussion.


Which of the six solutions above do people prefer?

-- 
Thanks
Kaitao Cheng


^ permalink raw reply

* Re: [PATCH net 0/8][pull request] Intel Wired LAN Driver Updates 2026-06-22 (ice, i40e, e1000e)
From: patchwork-bot+netdevbpf @ 2026-06-25  3:00 UTC (permalink / raw)
  To: Tony Nguyen; +Cc: davem, kuba, pabeni, edumazet, andrew+netdev, netdev
In-Reply-To: <20260622220059.2471844-1-anthony.l.nguyen@intel.com>

Hello:

This series was applied to netdev/net.git (main)
by Tony Nguyen <anthony.l.nguyen@intel.com>:

On Mon, 22 Jun 2026 15:00:47 -0700 you wrote:
> For ice:
> Dawid changes call to release control VSI during reset to prevent
> leaking it.
> 
> Lukasz fixes flow control error check to check value rather than treat
> is as bitmap values.
> 
> [...]

Here is the summary with links:
  - [net,1/8] ice: fix FDIR CTRL VSI resource leak in ice_reset_all_vfs()
    https://git.kernel.org/netdev/net/c/ebbe8868cf47
  - [net,2/8] ice: fix AQ error code comparison in ice_set_pauseparam()
    https://git.kernel.org/netdev/net/c/2bf7744bc322
  - [net,3/8] ice: fix ice_init_link() error return preventing probe
    https://git.kernel.org/netdev/net/c/eb509638686b
  - [net,4/8] ice: call netif_keep_dst() once when entering switchdev mode
    https://git.kernel.org/netdev/net/c/c0d00c882bc4
  - [net,5/8] ice: dpll: set pointers to NULL after kfree in ice_dpll_deinit_info
    https://git.kernel.org/netdev/net/c/a903afff66d7
  - [net,6/8] ice: dpll: fix memory leak in ice_dpll_init_info error paths
    https://git.kernel.org/netdev/net/c/20da495f2df0
  - [net,7/8] i40e: Fix i40e_debug() to use struct i40e_hw argument
    https://git.kernel.org/netdev/net/c/798f94603eb0
  - [net,8/8] e1000e: Reconfigure PLL clock gate timeout and re-enable K1 on Meteor Lake
    https://git.kernel.org/netdev/net/c/578294b8b60d

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



^ permalink raw reply

* Re: [PATCH net 01/14] netfilter: nf_nat: avoid invalid nat_net pointer use on failed nf_nat_init()
From: patchwork-bot+netdevbpf @ 2026-06-25  3:00 UTC (permalink / raw)
  To: Pablo Neira Ayuso
  Cc: netfilter-devel, davem, netdev, kuba, pabeni, edumazet, fw, horms
In-Reply-To: <20260623221548.701545-2-pablo@netfilter.org>

Hello:

This series was applied to netdev/net.git (main)
by Pablo Neira Ayuso <pablo@netfilter.org>:

On Wed, 24 Jun 2026 00:15:34 +0200 you wrote:
> From: Mathias Krause <minipli@grsecurity.net>
> 
> We ran into below KASAN splat, which is mostly uninteresting, beside
> for having nf_nat_register_fn() in the call chain as a cause for the
> offending access:
> 
> ==================================================================
> BUG: KASAN: slab-out-of-bounds in nf_nat_register_fn+0x5f9/0x640
> Read of size 8 at addr ffff890031e54c20 by task iptables/9510
> 
> [...]

Here is the summary with links:
  - [net,01/14] netfilter: nf_nat: avoid invalid nat_net pointer use on failed nf_nat_init()
    https://git.kernel.org/netdev/net/c/069cfe3de2a5
  - [net,02/14] netfilter: nf_conncount: prevent connlimit drops for early confirmed ct
    https://git.kernel.org/netdev/net/c/c8b6f36f7669
  - [net,03/14] netfilter: flowtable: Validate iph->ihl in nf_flow_ip4_tunnel_proto()
    https://git.kernel.org/netdev/net/c/84460b644329
  - [net,04/14] netfilter: x_tables.h: fix all kernel-doc warnings
    https://git.kernel.org/netdev/net/c/22f9dbed18bc
  - [net,05/14] netfilter: nft_synproxy: stop bypassing the priv->info snapshot
    https://git.kernel.org/netdev/net/c/11d4bc4e26fb
  - [net,06/14] selftests: netfilter: conntrack_sctp_collision.sh: Introduce SCTP INIT collision test
    https://git.kernel.org/netdev/net/c/a49a8e51eebc
  - [net,07/14] netfilter: nft_compat: ebtables emulation must reject non-bridge targets
    https://git.kernel.org/netdev/net/c/9dbba7e694ec
  - [net,08/14] selftests: nft_queue.sh: add a bridge queue test
    https://git.kernel.org/netdev/net/c/8a2cfe7951f6
  - [net,09/14] netfilter: ctnetlink: do not allow to reset helper on existing conntrack
    https://git.kernel.org/netdev/net/c/aaa0cd698ffa
  - [net,10/14] netfilter: conntrack: add deprecation warnings for irc and pptp trackers
    https://git.kernel.org/netdev/net/c/57f940017a77
  - [net,11/14] netfilter: nf_conntrack_expect: store master_tuple in expectation
    https://git.kernel.org/netdev/net/c/979c13114c0b
  - [net,12/14] netfilter: nf_conntrack_expect: run expectation eviction with no helper
    https://git.kernel.org/netdev/net/c/be57dd9c1c17
  - [net,13/14] netfilter: nft_ct: expectation timeouts are passed in milliseconds
    https://git.kernel.org/netdev/net/c/6fb421bd07f1
  - [net,14/14] netfilter: nf_conntrack_helper: cap maximum number of expectation at helper registration
    https://git.kernel.org/netdev/net/c/397c8300972f

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



^ permalink raw reply

* Re: [PATCH net] net: udp_tunnel: fix use-after-free by refcounting udp_tunnel_nic
From: Jakub Kicinski @ 2026-06-25  2:55 UTC (permalink / raw)
  To: Jiayuan Chen
  Cc: Eric Dumazet, David S . Miller, Paolo Abeni, Simon Horman,
	Ido Schimmel, David Ahern, netdev, eric.dumazet, Yue Sun
In-Reply-To: <04d09dea-baa2-4c43-ada1-cd71579aad53@linux.dev>

On Thu, 25 Jun 2026 10:47:09 +0800 Jiayuan Chen wrote:
> On 6/25/26 5:57 AM, Jakub Kicinski wrote:
> > On Wed, 24 Jun 2026 17:10:34 +0000 Eric Dumazet wrote:  
> >> Yue Sun reported a use-after-free and debugobjects warning in
> >> udp_tunnel_nic_device_sync_work() during concurrent device operations.
> >>
> >> The state flags of struct udp_tunnel_nic were originally bitfields
> >> sharing a byte, modified concurrently without locking (RCU vs worker).  
> > Can you clarify the path where the bits are modified without locks??
> > My mental model is that this is basically all under rtnl_lock, and
> > Stan added _another_ lock so that drivers can call "sync" / reply
> > without needing rtnl lock, but any changes are still under rtnl_lock.
> >
> > The gap seems to be that we don't check pending under Stan's new lock,
> > since commit 1ead7501094c6 ("udp_tunnel: remove rtnl_lock dependency")
> > did:  
> 
> 
> I think the real problem is that a single work_pending flag can't track 
> the work being queued twice:
> 
> 1. Thread A calls queue_work() -> work_pending = 1.
> 2. The worker gets picked up; workqueue clears the PENDING(internal work 
> queue flag) bit before running the work function.
>     The worker then blocks on rtnl/utn->lock.
> 3. Thread B calls queue_work() again. Since PENDING was already cleared, 
> it enqueues a second
>     instance and sets work_pending = 1.
> 4. A's worker finally gets the lock and does work_pending = 0, runs, 
> returns.
> 5. Now work_pending == 0 but B's instance is still queued. unregister 
> sees 0, frees utn.

Ah, thanks, now I get it. Claude told me the same thing but in 10,000
words and I lost the thread before reading 'til the end... 

In that case:

diff --git a/net/ipv4/udp_tunnel_nic.c b/net/ipv4/udp_tunnel_nic.c
index 9944ed923ddf..3b32a0afa979 100644
--- a/net/ipv4/udp_tunnel_nic.c
+++ b/net/ipv4/udp_tunnel_nic.c
@@ -301,7 +301,7 @@ __udp_tunnel_nic_device_sync(struct net_device *dev, struct udp_tunnel_nic *utn)
 static void
 udp_tunnel_nic_device_sync(struct net_device *dev, struct udp_tunnel_nic *utn)
 {
-       if (!utn->need_sync)
+       if (!utn->need_sync || utn->work_pending)
                return;
 
        queue_work(udp_tunnel_nic_workqueue, &utn->work);

^ permalink raw reply related

* Re: [PATCH net v3] fsl/fman: Free init resources on KeyGen failure in fman_init()
From: Jakub Kicinski @ 2026-06-25  2:48 UTC (permalink / raw)
  To: Haoxiang Li
  Cc: madalin.bucur, sean.anderson, andrew+netdev, davem, edumazet,
	pabeni, florinel.iordache, netdev, linux-kernel, stable,
	Pavan Chebbi, Breno Leitao
In-Reply-To: <20260625004834.3394389-1-haoxiang_li2024@163.com>

On Thu, 25 Jun 2026 08:48:34 +0800 Haoxiang Li wrote:
> fman_muram_alloc() allocates initialization resources before
> initializing the KeyGen block. If keygen_init() fails, the
> function returns -EINVAL directly and leaves those resources
> allocated. Free the initialization resources before returning
> from the KeyGen failure path.

Please slow down. You're sending a lot of low value patches.
Please do not have more than 5 outstanding "active" networking
patches under name at any given time:

https://patchwork.kernel.org/project/netdevbpf/list/?submitter=215341

^ permalink raw reply

* Re: [PATCH net] net: udp_tunnel: fix use-after-free by refcounting udp_tunnel_nic
From: Jiayuan Chen @ 2026-06-25  2:47 UTC (permalink / raw)
  To: Jakub Kicinski, Eric Dumazet
  Cc: David S . Miller, Paolo Abeni, Simon Horman, Ido Schimmel,
	David Ahern, netdev, eric.dumazet, Yue Sun
In-Reply-To: <20260624145722.083632b6@kernel.org>


On 6/25/26 5:57 AM, Jakub Kicinski wrote:
> On Wed, 24 Jun 2026 17:10:34 +0000 Eric Dumazet wrote:
>> Yue Sun reported a use-after-free and debugobjects warning in
>> udp_tunnel_nic_device_sync_work() during concurrent device operations.
>>
>> The state flags of struct udp_tunnel_nic were originally bitfields
>> sharing a byte, modified concurrently without locking (RCU vs worker).
> Can you clarify the path where the bits are modified without locks??
> My mental model is that this is basically all under rtnl_lock, and
> Stan added _another_ lock so that drivers can call "sync" / reply
> without needing rtnl lock, but any changes are still under rtnl_lock.
>
> The gap seems to be that we don't check pending under Stan's new lock,
> since commit 1ead7501094c6 ("udp_tunnel: remove rtnl_lock dependency")
> did:


I think the real problem is that a single work_pending flag can't track 
the work being queued twice:

1. Thread A calls queue_work() -> work_pending = 1.
2. The worker gets picked up; workqueue clears the PENDING(internal work 
queue flag) bit before running the work function.
    The worker then blocks on rtnl/utn->lock.
3. Thread B calls queue_work() again. Since PENDING was already cleared, 
it enqueues a second
    instance and sets work_pending = 1.
4. A's worker finally gets the lock and does work_pending = 0, runs, 
returns.
5. Now work_pending == 0 but B's instance is still queued. unregister 
sees 0, frees utn.



^ permalink raw reply

* Re: [PATCH net-next] fsl/fman: make enable() return void
From: Jakub Kicinski @ 2026-06-25  2:46 UTC (permalink / raw)
  To: Haoxiang Li
  Cc: madalin.bucur, sean.anderson, andrew+netdev, davem, edumazet,
	pabeni, netdev, linux-kernel
In-Reply-To: <20260625005600.3400023-1-haoxiang_li2024@163.com>

On Thu, 25 Jun 2026 08:56:00 +0800 Haoxiang Li wrote:
> The enable() helper always returns 0 and has no failure path.
> Make it return void and update the only caller accordingly.

## Form letter - net-next-closed

We have already submitted our pull request with net-next material for v7.2,
and therefore net-next is closed for new drivers, features, code refactoring
and optimizations. We are currently accepting bug fixes only.

Please repost when net-next reopens after June 29th.

RFC patches sent for review only are obviously welcome at any time.

See: https://www.kernel.org/doc/html/next/process/maintainer-netdev.html#development-cycle
-- 
pw-bot: defer
pv-bot: closed


^ permalink raw reply

* Re: [External Mail] Re: [PATCH v3 0/7] net: wwan: t9xx: Add MediaTek T9XX WWAN driver
From: Jakub Kicinski @ 2026-06-25  2:45 UTC (permalink / raw)
  To: Wu. JackBB (GSM)
  Cc: Loic Poulain, Sergey Ryazanov, Johannes Berg, Andrew Lunn,
	David S. Miller, Eric Dumazet, Paolo Abeni, Wen-Zhi Huang,
	Shi-Wei Yeh, Minano Tseng, Matthias Brugger,
	AngeloGioacchino Del Regno, Simon Horman, Jonathan Corbet,
	Shuah Khan, linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-mediatek@lists.infradead.org, linux-doc@vger.kernel.org
In-Reply-To: <cec5736466864641967b99adcfaf324a@compal.com>

On Thu, 25 Jun 2026 01:55:49 +0000 Wu. JackBB (GSM) wrote:
>   I have a question about the preferred workflow: the cover
>   letter changelog would get quite long if I include detailed
>   explanations for each sashiko comment we chose not to fix.
> 
>   Was the concern more about timing? Should we have replied
>   to the sashiko review promptly when it came in, rather than
>   waiting until the full v3 was ready?

Either way works. Either give reviewers 24h to dispute the comments or
add the comments to the repost. You don't have to keep a full detailed
log in the changelog.

> ================================================================================================================================================================
> This message may contain information which is private, privileged or confidential of Compal Electronics, Inc. If you are not the intended recipient of this message, please notify the sender and destroy/delete the message. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon this information, by persons or entities other than the intended recipient is prohibited.
> ================================================================================================================================================================

Again, please fix this.

^ permalink raw reply

* Re: [PATCH net] tools/ynl: add missing uapi header deps in Makefile.deps
From: patchwork-bot+netdevbpf @ 2026-06-25  2:40 UTC (permalink / raw)
  To: Thorsten Leemhuis
  Cc: netdev, davem, edumazet, kuba, pabeni, donald.hunter, riana.tauro,
	linux-kernel
In-Reply-To: <20260623070818.2161810-1-linux@leemhuis.info>

Hello:

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

On Tue, 23 Jun 2026 09:08:18 +0200 you wrote:
> drm_ras includes drm/drm_ras.h, which is a relatively new header not yet
> shipped in most distro kernel-header packages. Without the explicit
> entry, the build might fail with a message like this:
> 
>   drm_ras-user.c:19:10: error: ‘DRM_RAS_CMD_CLEAR_ERROR_COUNTER’ \
>    undeclared here (not in a function); did you mean \
>   ‘DRM_RAS_CMD_GET_ERROR_COUNTER’
> 
> [...]

Here is the summary with links:
  - [net] tools/ynl: add missing uapi header deps in Makefile.deps
    https://git.kernel.org/netdev/net/c/636838ebb74a

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



^ permalink raw reply

* Re: [PATCH net v3 0/2] net: ethernet: sunplus: spl2sw: fix of_node refcount leaks
From: patchwork-bot+netdevbpf @ 2026-06-25  2:40 UTC (permalink / raw)
  To: Shitalkumar Gandhi
  Cc: wellslutw, kuba, andrew, davem, edumazet, pabeni, horms, netdev,
	linux-kernel, shitalkumar.gandhi
In-Reply-To: <cover.1782195965.git.shitalkumar.gandhi@cambiumnetworks.com>

Hello:

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

On Tue, 23 Jun 2026 12:11:41 +0530 you wrote:
> This series fixes of_node refcount leaks in the Sunplus SP7021 ethernet
> driver, found by inspection. Compile-tested only; no SP7021 hardware
> available here.
> 
> Patch 1/2 fixes the phy_node leak in the remove path.
> Patch 2/2 fixes multiple leaks in the probe path and depends on the
> cleanup contract from patch 1/2.
> 
> [...]

Here is the summary with links:
  - [net,v3,1/2] net: ethernet: sunplus: spl2sw: fix phy_node refcount leak in remove
    https://git.kernel.org/netdev/net/c/a9e29dcd8a84

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



^ permalink raw reply

* Re: [PATCH net v2 0/2] net: stmmac: dwmac-spacemit: Fix wrong macro definition
From: patchwork-bot+netdevbpf @ 2026-06-25  2:40 UTC (permalink / raw)
  To: Inochi Amaoto
  Cc: andrew+netdev, davem, edumazet, kuba, pabeni, mcoquelin.stm32,
	alexandre.torgue, dlan, rmk+kernel, netdev, linux-stm32,
	linux-arm-kernel, linux-riscv, spacemit, linux-kernel, dlan,
	looong.bin
In-Reply-To: <20260623074637.503864-1-inochiama@gmail.com>

Hello:

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

On Tue, 23 Jun 2026 15:46:33 +0800 you wrote:
> Fix Wrong macro definition of the Spacemit K3.
> 
> Changed from v1:
> - https://lore.kernel.org/netdev/20260618064143.1102179-1-inochiama@gmail.com
> 1. Separate the patch into two patches
> 2. Use the right macro name for the LPI interrupt.
> 
> [...]

Here is the summary with links:
  - [net,v2,1/2] net: stmmac: dwmac-spacemit: Fix wrong phy interface definition
    https://git.kernel.org/netdev/net/c/d1e3a4c3b24d
  - [net,v2,2/2] net: stmmac: dwmac-spacemit: Fix wrong irq definition
    https://git.kernel.org/netdev/net/c/bf5cd5d4ca42

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



^ permalink raw reply

* Re: [PATCH net v3 0/2] net: ethernet: sunplus: spl2sw: fix of_node refcount leaks
From: Jakub Kicinski @ 2026-06-25  2:35 UTC (permalink / raw)
  To: Shitalkumar Gandhi
  Cc: Wells Lu, Andrew Lunn, David S. Miller, Eric Dumazet, Paolo Abeni,
	Simon Horman, netdev, linux-kernel, Shitalkumar Gandhi
In-Reply-To: <cover.1782195965.git.shitalkumar.gandhi@cambiumnetworks.com>

On Tue, 23 Jun 2026 12:11:41 +0530 Shitalkumar Gandhi wrote:
> Shitalkumar Gandhi (2):
>   net: ethernet: sunplus: spl2sw: fix phy_node refcount leak in remove
>   net: ethernet: sunplus: spl2sw: fix multiple of_node refcount leaks in
>     probe

Only the first patch reached the list

^ permalink raw reply

* Re: [PATCH net-next] selftests/xsk: preserve UMEM view in bidi test
From: Jakub Kicinski @ 2026-06-25  2:33 UTC (permalink / raw)
  To: Maciej Fijalkowski
  Cc: netdev, bpf, magnus.karlsson, stfomichev, pabeni, horms,
	tushar.vyavahare, kerneljasonxing
In-Reply-To: <20260623091008.1046547-1-maciej.fijalkowski@intel.com>

On Tue, 23 Jun 2026 11:10:08 +0200 Maciej Fijalkowski wrote:
> Subject: [PATCH net-next] selftests/xsk: preserve UMEM view in bidi test

Do you want it in net? Either way - we'll need a rebase

> Signed-off-by: Maciej Fijalkowski maciej.fijalkowski@intel.com

missing <> around the email 

^ 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