* [PATCH net-next v3 3/4] net: hsr: allow PRP RedBox (interlink) creation
From: Xin Xie @ 2026-07-07 13:59 UTC (permalink / raw)
To: netdev
Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Shuah Khan, Sebastian Andrzej Siewior, Felix Maurer,
Luka Gejak, Fernando Fernandez Mancera, linux-kselftest,
linux-kernel, Xin Xie
In-Reply-To: <20260707135937.18-1-xiexinet@gmail.com>
With the PRP interlink datapath, duplicate discard and supervision support
in place, a PRP device can act as a RedBox. Remove the rtnetlink rejection
of "type hsr ... interlink <dev> proto 1"; the feature is implemented
unconditionally by the preceding patches.
Signed-off-by: Xin Xie <xiexinet@gmail.com>
---
net/hsr/hsr_netlink.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c
index 8099f2069a7..88940e8014b 100644
--- a/net/hsr/hsr_netlink.c
+++ b/net/hsr/hsr_netlink.c
@@ -121,14 +121,8 @@ static int hsr_newlink(struct net_device *dev,
}
}
- if (proto == HSR_PROTOCOL_PRP) {
+ if (proto == HSR_PROTOCOL_PRP)
proto_version = PRP_V1;
- if (interlink) {
- NL_SET_ERR_MSG_MOD(extack,
- "Interlink only works with HSR");
- return -EINVAL;
- }
- }
return hsr_dev_finalize(dev, link, interlink, multicast_spec,
proto_version, extack);
--
2.53.0
^ permalink raw reply related
* [PATCH net-next v3 2/4] net: hsr: emit RedBox-MAC TLV in PRP RedBox supervision frames
From: Xin Xie @ 2026-07-07 13:59 UTC (permalink / raw)
To: netdev
Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Shuah Khan, Sebastian Andrzej Siewior, Felix Maurer,
Luka Gejak, Fernando Fernandez Mancera, linux-kselftest,
linux-kernel, Xin Xie
In-Reply-To: <20260707135937.18-1-xiexinet@gmail.com>
A PRP RedBox must announce the SANs it proxies so peers populate their
proxy node tables. The proxy-announce machinery (hsr_proxy_announce(),
armed via hsr->redbox) already iterates proxy_node_db under RCU and calls
send_sv_frame() once per SAN, but the PRP sender emitted neither the
announced SAN MAC nor the RedBox-MAC TLV that IEC 62439-3 requires.
Extend send_prp_supervision_frame() so that, for a proxy-announce
(identified by the interlink port, an O(1) test), the frame carries the
proxied SAN MAC as MacAddressA followed by the RedBox-MAC TLV (Type 30)
and an explicit End-of-TLV marker before padding.
hsr_get_node() must also accept the reinjected proxy-announce: a PRP
supervision frame is an untagged ETH_P_PRP frame (mac_len == ETH_HLEN, the
RCT is appended only on egress) sourced from macaddress_redbox, which is
never learned from data. Exempt only PRP supervision frames from the
hsr_ethhdr length guard; HSR (ETH_P_HSR) supervision is front-tagged and
keeps the original guard, so HSR malformed-frame filtering is unchanged.
Also align macaddress_redbox so that ether_addr_copy() and
ether_addr_equal() on it are safe on architectures without efficient
unaligned access.
Signed-off-by: Xin Xie <xiexinet@gmail.com>
---
net/hsr/hsr_device.c | 33 ++++++++++++++++++++++++++++++---
net/hsr/hsr_framereg.c | 13 +++++++++++--
net/hsr/hsr_main.h | 2 +-
3 files changed, 42 insertions(+), 6 deletions(-)
diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
index 5af491ed2b7..0973f9a94f4 100644
--- a/net/hsr/hsr_device.c
+++ b/net/hsr/hsr_device.c
@@ -372,10 +372,21 @@ static void send_prp_supervision_frame(struct hsr_port *master,
{
struct hsr_priv *hsr = master->hsr;
struct hsr_sup_payload *hsr_sp;
+ struct hsr_sup_tlv *hsr_stlv;
struct hsr_sup_tag *hsr_stag;
struct sk_buff *skb;
+ bool redbox_proxy;
+ int extra = 0;
+
+ redbox_proxy = hsr->redbox && master->type == HSR_PT_INTERLINK;
+
+ /* A proxy-announce carries a RedBox-MAC TLV and an EOT marker. */
+ if (redbox_proxy)
+ extra = sizeof(struct hsr_sup_tlv) +
+ sizeof(struct hsr_sup_payload) +
+ sizeof(struct hsr_sup_tlv);
- skb = hsr_init_skb(master, 0);
+ skb = hsr_init_skb(master, extra);
if (!skb) {
netdev_warn_once(master->dev, "PRP: Could not send supervision frame\n");
return;
@@ -393,9 +404,25 @@ static void send_prp_supervision_frame(struct hsr_port *master,
hsr_stag->tlv.HSR_TLV_type = PRP_TLV_LIFE_CHECK_DD;
hsr_stag->tlv.HSR_TLV_length = sizeof(struct hsr_sup_payload);
- /* Payload: MacAddressA */
+ /* Payload: MacAddressA, the announced node. */
hsr_sp = skb_put(skb, sizeof(struct hsr_sup_payload));
- ether_addr_copy(hsr_sp->macaddress_A, master->dev->dev_addr);
+ ether_addr_copy(hsr_sp->macaddress_A, addr);
+
+ /* Proxy-announce: append the RedBox-MAC TLV (Type 30) and an explicit
+ * EOT to terminate the TLV chain before zero padding.
+ */
+ if (redbox_proxy) {
+ hsr_stlv = skb_put(skb, sizeof(struct hsr_sup_tlv));
+ hsr_stlv->HSR_TLV_type = PRP_TLV_REDBOX_MAC;
+ hsr_stlv->HSR_TLV_length = sizeof(struct hsr_sup_payload);
+
+ hsr_sp = skb_put(skb, sizeof(struct hsr_sup_payload));
+ ether_addr_copy(hsr_sp->macaddress_A, hsr->macaddress_redbox);
+
+ hsr_stlv = skb_put(skb, sizeof(struct hsr_sup_tlv));
+ hsr_stlv->HSR_TLV_type = HSR_TLV_EOT;
+ hsr_stlv->HSR_TLV_length = 0;
+ }
if (skb_put_padto(skb, ETH_ZLEN)) {
spin_unlock_bh(&hsr->seqnr_lock);
diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c
index 8f708b6e6c3..b3b106be692 100644
--- a/net/hsr/hsr_framereg.c
+++ b/net/hsr/hsr_framereg.c
@@ -293,8 +293,17 @@ struct hsr_node *hsr_get_node(struct hsr_port *port, struct list_head *node_db,
*/
if (ethhdr->h_proto == htons(ETH_P_PRP) ||
ethhdr->h_proto == htons(ETH_P_HSR)) {
- /* Check if skb contains hsr_ethhdr */
- if (skb->mac_len < sizeof(struct hsr_ethhdr))
+ bool prp_sup;
+
+ /* A PRP supervision frame is an untagged ETH_P_PRP frame
+ * (mac_len == ETH_HLEN); its RCT is appended only on egress.
+ * HSR (ETH_P_HSR) supervision is front-tagged and still must
+ * contain a struct hsr_ethhdr.
+ */
+ prp_sup = hsr->prot_version == PRP_V1 &&
+ ethhdr->h_proto == htons(ETH_P_PRP) && is_sup;
+
+ if (!prp_sup && skb->mac_len < sizeof(struct hsr_ethhdr))
return NULL;
} else {
rct = skb_get_PRP_rct(skb);
diff --git a/net/hsr/hsr_main.h b/net/hsr/hsr_main.h
index 134e4f3fff6..c27cfdd9ca3 100644
--- a/net/hsr/hsr_main.h
+++ b/net/hsr/hsr_main.h
@@ -211,7 +211,7 @@ struct hsr_priv {
*/
bool fwd_offloaded; /* Forwarding offloaded to HW */
bool redbox; /* Device supports HSR RedBox */
- unsigned char macaddress_redbox[ETH_ALEN];
+ unsigned char macaddress_redbox[ETH_ALEN] __aligned(sizeof(u16));
unsigned char sup_multicast_addr[ETH_ALEN] __aligned(sizeof(u16));
/* Align to u16 boundary to avoid unaligned access
* in ether_addr_equal
--
2.53.0
^ permalink raw reply related
* [PATCH net-next v3 1/4] net: hsr: add PRP interlink (RedBox) datapath and duplicate discard
From: Xin Xie @ 2026-07-07 13:59 UTC (permalink / raw)
To: netdev
Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Shuah Khan, Sebastian Andrzej Siewior, Felix Maurer,
Luka Gejak, Fernando Fernandez Mancera, linux-kselftest,
linux-kernel, Xin Xie
In-Reply-To: <20260707135937.18-1-xiexinet@gmail.com>
A PRP RedBox proxies SANs that sit behind an interlink port: their frames
must reach the PRP network with the SAN source MAC preserved, and PRP
unicast must be steered between the LAN and the SAN segment correctly.
Add the PRP interlink forwarding rules to prp_drop_frame() and give RedBox
nodes a second duplicate-discard slot so the two LAN copies of a frame
destined to a SAN collapse to a single delivery out the interlink.
The destination classification (is the unicast DA a PRP-network node or a
proxied SAN) is resolved once per frame in fill_frame_info(), gated to PRP
RedBox devices, and cached in struct hsr_frame_info, so prp_drop_frame()
stays O(1) and does not walk the node tables for every candidate egress
port in the softIRQ path. HSR RedBox frame classification is untouched.
Factor the LAN A/B duplicate test into prp_is_lan_dup() so the new PRP
interlink rules do not change hsr_drop_frame() behaviour, including the
NETIF_F_HW_HSR_FWD path which keeps using the LAN-duplicate test only.
Publish the RedBox state before the first hsr_add_port(): the slave and
interlink rx handlers are live from hsr_add_port() on and rtnl does not
stop softirq processing, so a frame could otherwise be handled while
hsr->redbox is still false. hsr_add_node() sizes each node's per-port
sequence state from hsr->redbox; a node learned in that window would get
a single-port sequence block, breaking the interlink duplicate discard
(WARN_ON_ONCE plus duplicate delivery to the SAN) and letting the
supervision sequence-block merge read beyond the source node's allocated
sequence bitmap. Publishing the flag before any port exists makes the
per-node sizing uniform by construction. This is safe: the proxy
announce timer is only armed from hsr_check_announce() once the master
is running, the packet-path readers of hsr->redbox tolerate an empty
proxy node database and an absent interlink port, and the
prune_proxy_timer is still armed only after the interlink port has been
attached successfully.
Additionally bound the supervision sequence-block merge by the smaller
of the two nodes' seq_port_cnt as defense in depth against mismatched
node sizes.
Signed-off-by: Xin Xie <xiexinet@gmail.com>
---
net/hsr/hsr_device.c | 11 ++++++++--
net/hsr/hsr_forward.c | 49 ++++++++++++++++++++++++++++++++++++------
net/hsr/hsr_framereg.c | 14 ++++++++----
net/hsr/hsr_framereg.h | 2 ++
4 files changed, 64 insertions(+), 12 deletions(-)
diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
index 5555b71ab19..5af491ed2b7 100644
--- a/net/hsr/hsr_device.c
+++ b/net/hsr/hsr_device.c
@@ -768,6 +768,15 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],
/* Make sure the 1st call to netif_carrier_on() gets through */
netif_carrier_off(hsr_dev);
+ /* Publish the RedBox state before any port is attached: the rx
+ * handlers are live from hsr_add_port() on, and hsr_add_node()
+ * sizes each node's per-port sequence state from hsr->redbox.
+ */
+ if (interlink) {
+ hsr->redbox = true;
+ ether_addr_copy(hsr->macaddress_redbox, interlink->dev_addr);
+ }
+
res = hsr_add_port(hsr, hsr_dev, HSR_PT_MASTER, extack);
if (res)
goto err_add_master;
@@ -805,8 +814,6 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],
if (res)
goto err_unregister;
- hsr->redbox = true;
- ether_addr_copy(hsr->macaddress_redbox, interlink->dev_addr);
mod_timer(&hsr->prune_proxy_timer,
jiffies + msecs_to_jiffies(PRUNE_PROXY_PERIOD));
}
diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
index 0774981a65c..efcd0acef38 100644
--- a/net/hsr/hsr_forward.c
+++ b/net/hsr/hsr_forward.c
@@ -440,12 +440,37 @@ static int hsr_xmit(struct sk_buff *skb, struct hsr_port *port,
return dev_queue_xmit(skb);
}
+static bool prp_is_lan_dup(struct hsr_frame_info *frame,
+ struct hsr_port *port)
+{
+ enum hsr_port_type rx = frame->port_rcv->type;
+
+ return (rx == HSR_PT_SLAVE_A && port->type == HSR_PT_SLAVE_B) ||
+ (rx == HSR_PT_SLAVE_B && port->type == HSR_PT_SLAVE_A);
+}
+
bool prp_drop_frame(struct hsr_frame_info *frame, struct hsr_port *port)
{
- return ((frame->port_rcv->type == HSR_PT_SLAVE_A &&
- port->type == HSR_PT_SLAVE_B) ||
- (frame->port_rcv->type == HSR_PT_SLAVE_B &&
- port->type == HSR_PT_SLAVE_A));
+ enum hsr_port_type rx = frame->port_rcv->type;
+
+ /* Supervision frames are not delivered to a SAN on the interlink. */
+ if (frame->is_supervision && port->type == HSR_PT_INTERLINK)
+ return true;
+
+ if (prp_is_lan_dup(frame, port))
+ return true;
+
+ /* LAN to interlink: keep PRP-network unicast off the SAN segment. */
+ if ((rx == HSR_PT_SLAVE_A || rx == HSR_PT_SLAVE_B) &&
+ port->type == HSR_PT_INTERLINK)
+ return frame->dst_in_node_db;
+
+ /* Interlink to LAN: keep SAN-to-SAN unicast local. */
+ if ((port->type == HSR_PT_SLAVE_A || port->type == HSR_PT_SLAVE_B) &&
+ rx == HSR_PT_INTERLINK)
+ return frame->dst_in_proxy_node_db;
+
+ return false;
}
bool hsr_drop_frame(struct hsr_frame_info *frame, struct hsr_port *port)
@@ -453,7 +478,7 @@ bool hsr_drop_frame(struct hsr_frame_info *frame, struct hsr_port *port)
struct sk_buff *skb;
if (port->dev->features & NETIF_F_HW_HSR_FWD)
- return prp_drop_frame(frame, port);
+ return prp_is_lan_dup(frame, port);
/* RedBox specific frames dropping policies
*
@@ -466,7 +491,7 @@ bool hsr_drop_frame(struct hsr_frame_info *frame, struct hsr_port *port)
* are addressed to interlink port (and are in the ProxyNodeTable).
*/
skb = frame->skb_hsr;
- if (skb && prp_drop_frame(frame, port) &&
+ if (skb && prp_is_lan_dup(frame, port) &&
is_unicast_ether_addr(eth_hdr(skb)->h_dest) &&
hsr_is_node_in_db(&port->hsr->proxy_node_db,
eth_hdr(skb)->h_dest)) {
@@ -706,6 +731,18 @@ static int fill_frame_info(struct hsr_frame_info *frame,
frame->is_vlan = false;
proto = ethhdr->h_proto;
+ /* PRP RedBox only: classify the unicast destination once so the
+ * per-egress-port decision in prp_drop_frame() stays O(1). HSR RedBox
+ * does its own classification and must not pay these node-table walks.
+ */
+ if (hsr->prot_version == PRP_V1 && hsr->redbox &&
+ is_unicast_ether_addr(ethhdr->h_dest)) {
+ frame->dst_in_node_db =
+ hsr_is_node_in_db(&hsr->node_db, ethhdr->h_dest);
+ frame->dst_in_proxy_node_db =
+ hsr_is_node_in_db(&hsr->proxy_node_db, ethhdr->h_dest);
+ }
+
if (proto == htons(ETH_P_8021Q))
frame->is_vlan = true;
diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c
index e4492987127..8f708b6e6c3 100644
--- a/net/hsr/hsr_framereg.c
+++ b/net/hsr/hsr_framereg.c
@@ -199,7 +199,7 @@ static struct hsr_node *hsr_add_node(struct hsr_priv *hsr,
spin_lock_init(&new_node->seq_out_lock);
if (hsr->prot_version == PRP_V1)
- new_node->seq_port_cnt = 1;
+ new_node->seq_port_cnt = hsr->redbox ? 2 : 1;
else
new_node->seq_port_cnt = HSR_PT_PORTS - 1;
@@ -381,6 +381,7 @@ void hsr_handle_sup_frame(struct hsr_frame_info *frame)
struct ethhdr *ethhdr;
unsigned int total_pull_size = 0;
unsigned int pull_size = 0;
+ unsigned int seq_port_cnt;
unsigned long idx;
int i;
@@ -474,6 +475,7 @@ void hsr_handle_sup_frame(struct hsr_frame_info *frame)
}
}
+ seq_port_cnt = min(node_real->seq_port_cnt, node_curr->seq_port_cnt);
xa_for_each(&node_curr->seq_blocks, idx, src_blk) {
if (hsr_seq_block_is_old(src_blk))
continue;
@@ -482,7 +484,7 @@ void hsr_handle_sup_frame(struct hsr_frame_info *frame)
if (!merge_blk)
continue;
merge_blk->time = min(merge_blk->time, src_blk->time);
- for (i = 0; i < node_real->seq_port_cnt; i++) {
+ for (i = 0; i < seq_port_cnt; i++) {
bitmap_or(merge_blk->seq_nrs[i], merge_blk->seq_nrs[i],
src_blk->seq_nrs[i], HSR_SEQ_BLOCK_SIZE);
}
@@ -649,9 +651,13 @@ int prp_register_frame_out(struct hsr_port *port, struct hsr_frame_info *frame)
if (frame->port_rcv->type == HSR_PT_MASTER)
return 0;
- /* for PRP we should only forward frames from the slave ports
- * to the master port
+ /* RedBox: forward LAN frames out the interlink to a SAN, deduping the
+ * two LAN copies on a dedicated slot.
*/
+ if (port->type == HSR_PT_INTERLINK)
+ return hsr_check_duplicate(frame, 1);
+
+ /* For PRP only slave-to-master frames are forwarded. */
if (port->type != HSR_PT_MASTER)
return 1;
diff --git a/net/hsr/hsr_framereg.h b/net/hsr/hsr_framereg.h
index c65ecb92573..127a3fb64d5 100644
--- a/net/hsr/hsr_framereg.h
+++ b/net/hsr/hsr_framereg.h
@@ -27,6 +27,8 @@ struct hsr_frame_info {
bool is_local_dest;
bool is_local_exclusive;
bool is_from_san;
+ bool dst_in_node_db;
+ bool dst_in_proxy_node_db;
};
void hsr_del_self_node(struct hsr_priv *hsr);
--
2.53.0
^ permalink raw reply related
* [PATCH net-next v3 0/4] net: hsr: PRP RedBox (PRP-SAN) support
From: Xin Xie @ 2026-07-07 13:59 UTC (permalink / raw)
To: netdev
Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Shuah Khan, Sebastian Andrzej Siewior, Felix Maurer,
Luka Gejak, Fernando Fernandez Mancera, linux-kselftest,
linux-kernel, Xin Xie
This series adds PRP RedBox support to the hsr driver: a PRP node that
proxies one or more SANs sitting behind an interlink port (IEC 62439-3,
PRP-SAN). HSR-SAN has been supported since commit 5055cccfc2d1 ("net: hsr:
Provide RedBox support (HSR-SAN)"); this extends the equivalent capability
to PRP, reusing the existing protocol-neutral proxy machinery
(proxy_node_db, hsr_proxy_announce(), hsr_prune_proxy_nodes()).
A SAN behind the interlink does bidirectional unicast with peers on the PRP
network, its source MAC is preserved on the wire, the PRP RCT is correct,
and the RedBox announces each proxied SAN with the RedBox-MAC TLV (Type 30)
in its supervision frames.
The series is bisect-safe: the datapath, duplicate discard and supervision
support are added first; the rtnetlink rejection of "type hsr ... interlink
<dev> proto 1" is removed only in patch 3, once the feature is complete.
Design notes:
- prp_drop_frame() does not walk the node tables. The destination
classification (PRP-network node vs proxied SAN) is resolved once per
frame in fill_frame_info() and cached in struct hsr_frame_info, so the
per egress-port drop decision is O(1) in the softIRQ path. The
classification is gated on PRP RedBox devices (prot_version == PRP_V1 &&
hsr->redbox), so HSR RedBox traffic is not affected.
- The LAN A/B duplicate test is factored into prp_is_lan_dup() so the new
PRP interlink rules in prp_drop_frame() do not change hsr_drop_frame()
behaviour, including the NETIF_F_HW_HSR_FWD path. This is software PRP
RedBox only; it adds no new hardware-offload contract.
- The supervision emitter uses pre-reserved tailroom (hsr_init_skb() +
skb_put()) on the existing GFP_ATOMIC path; no skb_linearize() or
pskb_expand_head(). The RedBox-MAC TLV is followed by an explicit EOT
(Type 0, Length 0); padding via skb_put_padto(ETH_ZLEN) and the 6-byte
PRP RCT remain at the absolute tail of the egress frame.
- The hsr_get_node() hsr_ethhdr length guard is relaxed only for PRP
supervision frames (prot_version == PRP_V1 && ETH_P_PRP && is_sup), which
are untagged with mac_len == ETH_HLEN. HSR (ETH_P_HSR) supervision is
front-tagged and keeps the original length requirement, so HSR
malformed-frame filtering is unchanged.
Testing (on a net-next v7.2-rc1 kernel built from this base, x86-64):
- checkpatch.pl --strict: patches 1-3 clean; patch 4 reports only the
expected "added file(s), does MAINTAINERS need updating?" note, which is
ignorable here -- MAINTAINERS already lists
tools/testing/selftests/net/hsr/ under HSR NETWORK PROTOCOL.
- git diff --check clean; the series git-am's onto the base commit.
- tools/testing/selftests/net/hsr/hsr_prp_redbox.sh: PASS on the patched
kernel (bidirectional unicast, SAN MAC preservation, RedBox-MAC TLV +
EOT in the proxy-announce).
- HSR regression on the same kernel: hsr_redbox.sh (HSR-SAN/RedBox),
hsr_ping.sh and prp_ping.sh all PASS, confirming the PRP changes do not
regress the existing HSR/PRP paths.
- netns checks: peer<->SAN 0% loss with no duplicates and a valid PRP RCT
on the wire; a silent SAN is pruned from the announce; zero driver
WARN/BUG/Oops/RCU-stall during the run.
Beyond the in-tree selftest, this exact series (applied to this base and
running as the net-next kernel on x86-64 hardware) was also validated with an
out-of-tree IEC 62439-3 conformance harness (supervision TLV chain, duplicate
discard, cross-LAN rejection, seqnr rollover, VLAN/multicast/GOOSE frame types
with the RCT verified at the absolute frame tail), and interoperability-tested
against a commercial PRP RedBox (Siemens SCALANCE X204RNA) over 100 Mbit/s
Fast Ethernet with NIC hardware (PTP) timestamping: a mid-stream single-LAN
outage of ~2 s at 10 kpps was bridged with zero lost and zero duplicate frames
(seamless PRP failover), and the duplicate-discard window held zero lost /
zero duplicates under netem asymmetric delay up to 100 ms (~1000 sequence
numbers in flight), 25% reorder, and 5% single-LAN loss. The failover and
impairment matrix was additionally repeated on a KASAN + lockdep + kmemleak
instrumented build of this kernel, including a 72-carrier-event link
flap-storm with deliberate double-LAN cuts: zero KASAN, lockdep, or kmemleak
findings. This out-of-tree testing is supplementary and not required to
evaluate the series.
v3:
- no code changes; repost as a new thread (v2 was incorrectly posted
in reply to v1)
v2: https://lore.kernel.org/netdev/20260706134131.61659-1-xiexinet@gmail.com/
- publish the RedBox state before lower RX handlers can learn nodes:
fixes an initialization-ordering race where a node learned during
device setup got a single-port sequence block, breaking interlink
duplicate discard and letting the supervision merge read beyond the
source node's allocated sequence bitmap (reported by the NIPA Sashiko
review)
- harden the supervision sequence-block merge against mismatched
seq_port_cnt
- align macaddress_redbox for ether_addr_copy() on strict-alignment
architectures
- selftest: kill the background ping by exact PID and wrap an overlong
line
v1: https://lore.kernel.org/netdev/20260704234704.4297-1-xiexinet@gmail.com/
Xin Xie (4):
net: hsr: add PRP interlink (RedBox) datapath and duplicate discard
net: hsr: emit RedBox-MAC TLV in PRP RedBox supervision frames
net: hsr: allow PRP RedBox (interlink) creation
selftests: net: hsr: add PRP RedBox test
net/hsr/hsr_device.c | 44 ++++++++-
net/hsr/hsr_forward.c | 49 +++++++--
net/hsr/hsr_framereg.c | 27 +++--
net/hsr/hsr_framereg.h | 2 +
net/hsr/hsr_main.h | 2 +-
net/hsr/hsr_netlink.c | 8 +-
tools/testing/selftests/net/hsr/Makefile | 1 +
.../selftests/net/hsr/hsr_prp_redbox.sh | 99 +++++++++++++++++++
8 files changed, 207 insertions(+), 25 deletions(-)
create mode 100755 tools/testing/selftests/net/hsr/hsr_prp_redbox.sh
base-commit: b73bc9ca3686b78b642fb35dcc1fdf874ecb74a1
--
2.53.0
^ permalink raw reply
* Re: [PATCH nf v2 0/3] ipvs: use parsed transport offsets in state handlers
From: Julian Anastasov @ 2026-07-07 13:51 UTC (permalink / raw)
To: Yizhou Zhao
Cc: netdev, coreteam, davem, edumazet, fengxw06, fw, horms, kuba,
linux-kernel, lvs-devel, netfilter-devel, pabeni, pablo, phil,
qli01, stable, wangao, xuke, yangyx22
In-Reply-To: <20260706101624.69471-1-zhaoyz24@mails.tsinghua.edu.cn>
Hello,
On Mon, 6 Jul 2026, Yizhou Zhao wrote:
> IPVS parses packets into struct ip_vs_iphdr before scheduling and state
> handling. For IPv6, iph.len contains the real transport-header offset
> after ipv6_find_hdr() has skipped any extension headers.
>
> TCP and SCTP state handlers still recompute their own transport offsets.
> They use sizeof(struct ipv6hdr) for IPv6, so packets with extension
> headers make the state machines read the wrong bytes.
>
> Pass the parsed transport offset through the common IPVS state handling
> callback, then use it in the TCP and SCTP state lookups.
>
> Changes in v2:
> - Pass the parsed transport offset through ip_vs_set_state() and the
> protocol callbacks.
> - Fix TCP state handling as well as SCTP.
> - Avoid reparsing the skb in SCTP state handling.
> - Split the common plumbing, TCP fix and SCTP fix into a 3-patch series.
>
> Yizhou Zhao (3):
> ipvs: pass parsed transport offset to state handlers
> ipvs: use parsed transport offset in TCP state lookup
> ipvs: use parsed transport offset in SCTP state lookup
>
> include/net/ip_vs.h | 3 ++-
> net/netfilter/ipvs/ip_vs_core.c | 10 +++++-----
> net/netfilter/ipvs/ip_vs_proto_sctp.c | 18 +++++++-----------
> net/netfilter/ipvs/ip_vs_proto_tcp.c | 11 +++--------
> net/netfilter/ipvs/ip_vs_proto_udp.c | 3 ++-
> 5 files changed, 19 insertions(+), 26 deletions(-)
The patchset looks good to me, thanks!
Acked-by: Julian Anastasov <ja@ssi.bg>
The Sashiko comments need additional fixes:
https://sashiko.dev/#/patchset/20260706101624.69471-1-zhaoyz24%40mails.tsinghua.edu.cn
Regards
--
Julian Anastasov <ja@ssi.bg>
^ permalink raw reply
* Re: [PATCH 1/2] af_unix: Do not wait for garbage collector in sendmsg()
From: Nam Cao @ 2026-07-07 13:49 UTC (permalink / raw)
To: Sebastian Andrzej Siewior
Cc: Kuniyuki Iwashima, sashiko-reviews, David S . Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman, netdev,
linux-kernel, linux-rt-devel
In-Reply-To: <20260707114225.4oj9SF_0@linutronix.de>
Sebastian Andrzej Siewior <bigeasy@linutronix.de> writes:
> On 2026-07-04 08:03:56 [+0200], Nam Cao wrote:
>> Kuniyuki Iwashima <kuniyu@google.com> writes:
>> > your patch makes it much easier to abuse.
>> > UNIX_INFLIGHT_SANE_USER is usually much smaller than
>> > RLIMIT_NOFILE.
>> >
>> > unix_schedule_gc() in sendmsg() is to self-regulate malicious users,
>> > otherwise GC relies on unrelated AF_UNIX socket's close() and could
>> > be triggered too late since GC is system-wide.
>>
>> About the abuse, the scenario where inflight sockets bypass
>> UNIX_INFLIGHT_SANE_USER and delay GC until an unrelated AF_UNIX socket
>> closes actually exists today.
>
> We don't bypass the limit for an ordinary user. That one gets blocked in
> too_many_unix_fds(). But for the CAP_SYS_RESOURCE + CAP_SYS_ADMIN it is
> a different story.
> In that case we cross the UNIX_INFLIGHT_SANE_USER and schedule the GC,
> it is not delayed. The worker is triggered regularity and the thread
> waits for its completion it is just the GC worker does not clean up
> anything so it continues to increase. The only thing that actually
> limits the sender is if it runs out of socket memory and needs to wait.
That's also my understanding. But tasks that have
CAP_SYS_RESOURCE|CAP_SYS_ADMIN should be trustworthy to not burn
system's resources.
> So it kind of works for a single thread.
>
> …
>> To address this properly, we can schedule the GC at task exit. I can
>> include that patch in my series, if that sounds good to you.
>
> task exit or closing the socket?
I meant task exit, but closing the socket also makes sense because that
is when dead cyclic reference can appear. However, unless the file
descriptor's refcount reaches 0, the fs layer will not call us. We could
change fs/, but I am not sure if we should invade into fs/ just for this
one.
For the "resource is still consumed indefinitely after task exit" issue,
then scheduling GC at task exit is good enough.
If the task does not exit, those dead cyclic references can sit there
indefinitely. But this is not really critical as it is capped by
RLIMIT_NOFILE. Additionally it is impossible to prevent a "malicious"
task from creating RLIMIT_NOFILE inflight sockets and just leave them
there.
> Either way, in your PoC it hardly makes any sense to schedule the worker
> over and over and wait for it since it does not do anything. Sure it is
> the system as a whole so triggering might make sense but I'm not sure
> about waiting for its completion.
Agree. For the GC triggering thingy, it is a trade-off between CPU
consumption and how early garbage gets cleared, so that can arguably
stay. But the waiting part has to go.
> Side note: gc_in_progress is redundant since you can't schedule a worker
> twice and work_pending(&unix_gc_work) would provide the same
> information. The only difference is that you avoid scheduling the worker
> while it is running but I don't think this is a problem.
Yep. Additionally gc_in_progress is not read/write under any lock, so
it is possible to read a stale gc_in_progress and the GC gets delayed
indefinitely. That is already on my todo list, among a few other
things. But let's get this most important piece done first.
Nam
^ permalink raw reply
* Re: [PATCH net-next v13 09/10] net: ethtool: Introduce ethtool command to list ports
From: Paolo Abeni @ 2026-07-07 13:46 UTC (permalink / raw)
To: Maxime Chevallier, davem, Andrew Lunn, Jakub Kicinski,
Eric Dumazet, Russell King, Heiner Kallweit
Cc: netdev, linux-kernel, thomas.petazzoni, Christophe Leroy,
Herve Codina, Florian Fainelli, Vladimir Oltean,
Köry Maincent, Marek Behún, Oleksij Rempel,
Nicolò Veronese, Simon Horman, mwojtas, Romain Gantois,
Daniel Golle, Dimitri Fedrau, Frank Wunderlich
In-Reply-To: <7f47104f-8333-4c10-aab6-90552daabefe@bootlin.com>
On 7/7/26 12:47 PM, Maxime Chevallier wrote:
> On 7/7/26 12:12, Paolo Abeni wrote:
>>
>> Both sashikos instances points to multiple races with dumps. I suspect
>> some explicit locking is required.
>>
>> https://sashiko.dev/#/patchset/20260701110427.143945-1-maxime.chevallier%40bootlin.com
>> https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260701110427.143945-1-maxime.chevallier%40bootlin.com
>>
>> I *think* this is hopefully the last pending issue.
>
> True indeed, the other issues are sashiko saying "what if we detach a PHY and attach it
> to another netdev", which can't happen :) I agree with some of the locking points that
> were found, I'll address that likely as a separate cleanup.
I'm sorry, but I think it's better to address the above problems with
the main series to avoid a window of opportunity that could cause a lot
of quite randomic/drop by submissions to try to addresses them with a
lot of noise on the ML.
I set the series to CR.
/P
^ permalink raw reply
* Re: [PATCH v2 7/7] usb: fix UAF when probe runs concurrent to dyn ID removal
From: Danilo Krummrich @ 2026-07-07 13:41 UTC (permalink / raw)
To: Gary Guo
Cc: Greg Kroah-Hartman, Rafael J. Wysocki,
Toke Høiland-Jørgensen, Johan Hovold,
Mauro Carvalho Chehab, Petko Manolov, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Chas Williams, Alan Stern, linux-usb, driver-core, linux-wireless,
linux-media, linux-atm-general, netdev, usb-storage, linux-kernel
In-Reply-To: <20260707-usb_dyn_id_uaf-v2-7-632dcf3adfba@garyguo.net>
On 7/7/26 2:26 PM, Gary Guo wrote:
> Dynamic IDs are only guaranteed to be valid when usb_dynids_lock is held,
> as remove_id_store can free the node. Thus, make a copy in
> usb_probe_interface. Clarify the documentation that the id parameter is
> only valid during the probe.
>
> USB serial has the same pattern, but it does not need fixing as the IDs
> cannot be removed via sysfs.
>
> Fixes: 0c7a2b72746a ("USB: add remove_id sysfs attr for usb drivers")
> Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Danilo Krummrich <dakr@kernel.org>
^ permalink raw reply
* Re: [PATCH net 2/2] net: macb: mask TXUBR during TX NAPI poll to prevent IRQ storms
From: Taedcke, Christian @ 2026-07-07 13:41 UTC (permalink / raw)
To: Sebastian Andrzej Siewior, christian.taedcke
Cc: Théo Lebrun, Conor Dooley, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Kevin Hao,
Simon Horman, Clark Williams, Steven Rostedt, Robert Hancock,
netdev, linux-kernel, linux-rt-devel, stable
In-Reply-To: <20260706150552.EomovsBn@linutronix.de>
On 7/6/2026 5:05 PM, Sebastian Andrzej Siewior wrote:
> On 2026-07-06 16:02:15 [+0200], Christian Taedcke via B4 Relay wrote:
>> From: Christian Taedcke <christian.taedcke@weidmueller.com>
>>
>> macb_interrupt() defers TX completion handling to NAPI, but when it
>> schedules the poll it only masks TCOMP, even though TXUBR is enabled
>> alongside it (both are part of MACB_TX_INT_FLAGS). macb_tx_poll() is
>> asymmetric in the same way and only re-enables TCOMP. TXUBR is thus
>> left unmasked while responsibility for handling it has been deferred
>> to NAPI.
>
> So this is not a race condition, this is always a failure?
As far as in understand it: yes
>
> Sebastian
Christian
^ permalink raw reply
* Re: [PATCH net-next v2 0/6] net: hold instance lock around NETDEV_DOWN and NETDEV_GOING_DOWN
From: patchwork-bot+netdevbpf @ 2026-07-07 13:40 UTC (permalink / raw)
To: Stanislav Fomichev; +Cc: netdev, davem, edumazet, kuba, pabeni
In-Reply-To: <20260702224150.3730033-1-sdf@fomichev.me>
Hello:
This series was applied to netdev/net-next.git (main)
by Paolo Abeni <pabeni@redhat.com>:
On Thu, 2 Jul 2026 15:41:44 -0700 you wrote:
> NETDEV_UP and NETDEV_REGISTER already run under the per-device
> instance lock. The teardown side does not. Make it symmetric so
> ops-locked drivers can rely on the lock being held in both
> directions.
>
> v2:
> - reword NETDEV_UNREGISTER unlocked rationale (Jakub)
>
> [...]
Here is the summary with links:
- [net-next,v2,1/6] net: hold instance lock around NETDEV_DOWN/GOING_DOWN
https://git.kernel.org/netdev/net-next/c/5326fefb9fe8
- [net-next,v2,2/6] net: dsa: hold instance lock on close-on-shutdown paths
https://git.kernel.org/netdev/net-next/c/cefa18fab29c
- [net-next,v2,3/6] net: mtk_eth_soc: hold instance lock around DMA-device-swap close
https://git.kernel.org/netdev/net-next/c/6034bc4febc9
- [net-next,v2,4/6] net: rtnetlink: take instance lock inside rtnl_configure_link
https://git.kernel.org/netdev/net-next/c/b8d2262b966a
- [net-next,v2,5/6] net: require instance lock for NETDEV_DOWN/GOING_DOWN notifiers
https://git.kernel.org/netdev/net-next/c/f540caaaca8d
- [net-next,v2,6/6] net: document NETDEV_UNREGISTER unlocked rationale
https://git.kernel.org/netdev/net-next/c/538d89fd9146
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH v5 net 4/7] i40e: avoid deadlock when calling unregister_netdev()
From: Loktionov, Aleksandr @ 2026-07-07 13:38 UTC (permalink / raw)
To: Fijalkowski, Maciej, intel-wired-lan@lists.osuosl.org
Cc: netdev@vger.kernel.org, Karlsson, Magnus, kuba@kernel.org,
pabeni@redhat.com, horms@kernel.org, Kitszel, Przemyslaw,
Keller, Jacob E, Fijalkowski, Maciej, Sashiko AI Review
In-Reply-To: <20260701124524.13644-5-maciej.fijalkowski@intel.com>
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> Of Maciej Fijalkowski
> Sent: Wednesday, July 1, 2026 2:45 PM
> To: intel-wired-lan@lists.osuosl.org
> Cc: netdev@vger.kernel.org; Karlsson, Magnus
> <magnus.karlsson@intel.com>; kuba@kernel.org; pabeni@redhat.com;
> horms@kernel.org; Kitszel, Przemyslaw <przemyslaw.kitszel@intel.com>;
> Keller, Jacob E <jacob.e.keller@intel.com>; Fijalkowski, Maciej
> <maciej.fijalkowski@intel.com>; Sashiko AI Review <sashiko-
> bot@kernel.org>
> Subject: [Intel-wired-lan] [PATCH v5 net 4/7] i40e: avoid deadlock
> when calling unregister_netdev()
>
> Sashiko reports:
> ***
> > +err_netdev:
> > if (vsi->netdev_registered) {
> > vsi->netdev_registered = false;
> > unregister_netdev(vsi->netdev);
> Could this result in a deadlock when called during a device rebuild?
> Looking at i40e_rebuild(), it explicitly acquires the RTNL lock before
> proceeding:
> drivers/net/ethernet/intel/i40e/i40e_main.c:i40e_rebuild() {
> ...
> if (!lock_acquired)
> rtnl_lock();
> ret = i40e_setup_pf_switch(pf, reinit, true);
> ...
> }
> If i40e_setup_pf_switch() calls i40e_vsi_reinit_setup() and takes this
> new err_netdev path, unregister_netdev() will unconditionally attempt
> to acquire rtnl_lock(), leading to a deadlock on the non-recursive
> mutex.
> ***
>
> Use unregister_netdevice() when the rebuild path already holds RTNL,
> and keep unregister_netdev() for callers that do not. This avoids both
> recursive RTNL locking and dropping RTNL in the middle of the VSI
> unwind path.
>
> Fixes: bc7d338fbb3f ("i40e: reinit flow for the main VSI")
> Reported-by: Sashiko AI Review <sashiko-bot@kernel.org>
> Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
> ---
> drivers/net/ethernet/intel/i40e/i40e_main.c | 10 +++++++---
> 1 file changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c
> b/drivers/net/ethernet/intel/i40e/i40e_main.c
> index a29a89192a7a..e88cf7cfbd84 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
> @@ -14257,7 +14257,8 @@ static int i40e_vsi_setup_vectors(struct
> i40e_vsi *vsi)
> * Returns pointer to the successfully allocated and configured VSI
> sw struct
> * on success, otherwise returns NULL on failure.
> **/
> -static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
> +static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi,
> + bool lock_acquired)
> {
> struct i40e_vsi *main_vsi;
> u16 alloc_queue_pairs;
> @@ -14314,7 +14315,10 @@ static struct i40e_vsi
> *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
> err_netdev:
> if (vsi->netdev_registered) {
> vsi->netdev_registered = false;
> - unregister_netdev(vsi->netdev);
> + if (lock_acquired)
> + unregister_netdevice(vsi->netdev);
> + else
> + unregister_netdev(vsi->netdev);
> free_netdev(vsi->netdev);
> vsi->netdev = NULL;
> }
> @@ -15036,7 +15040,7 @@ static int i40e_setup_pf_switch(struct i40e_pf
> *pf, bool reinit, bool lock_acqui
> main_vsi = i40e_vsi_setup(pf, I40E_VSI_MAIN,
> uplink_seid, 0);
> else if (reinit)
> - main_vsi = i40e_vsi_reinit_setup(main_vsi);
> + main_vsi = i40e_vsi_reinit_setup(main_vsi,
> lock_acquired);
> if (!main_vsi) {
> dev_info(&pf->pdev->dev, "setup of MAIN VSI
> failed\n");
> i40e_cloud_filter_exit(pf);
> --
> 2.43.0
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
^ permalink raw reply
* Re: [PATCH net] e1000e: fix IRQ leak when request_irq() fails in e1000_request_msix()
From: Simon Horman @ 2026-07-07 13:38 UTC (permalink / raw)
To: Jiayuan Chen
Cc: netdev, Tony Nguyen, Przemek Kitszel, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Jeff Garzik, Bruce Allan, intel-wired-lan, linux-kernel
In-Reply-To: <20260626083917.49745-1-jiayuan.chen@linux.dev>
On Fri, Jun 26, 2026 at 04:39:16PM +0800, Jiayuan Chen wrote:
> An internal syzbot instance reported the warning below.
>
> comedi (comedi_parport) lets userspace request_irq() an arbitrary IRQ
> number and can thus grab one of e1000e's MSI-X vectors. When
> e1000_request_msix() then fails partway through, it returned without
> freeing the vectors it had already requested; pci_disable_msix() later
> tears those descriptors down while their irqaction is still attached,
> leaking the /proc/irq entry.
>
> Free the already requested IRQs on the error path.
>
> genirq: Flags mismatch irq 28. 00200000 (eth1-tx-0) vs. 00200000 (comedi_parport)
>
> remove_proc_entry: removing non-empty directory 'irq/27', leaking at least 'eth1-rx-0'
> WARNING: fs/proc/generic.c:742 at remove_proc_entry+0x436/0x560, CPU#3: ip/445
> Modules linked in:
> CPU: 3 UID: 0 PID: 445 Comm: ip Not tainted 7.1.0+ #284 PREEMPT
> RIP: 0010:remove_proc_entry (fs/proc/generic.c:742 (discriminator 4))
> PKRU: 55555554
> Call Trace:
> <TASK>
> unregister_irq_proc (kernel/irq/proc.c:406)
> free_desc (kernel/irq/irqdesc.c:482)
> irq_free_descs (kernel/irq/irqdesc.c:874 kernel/irq/irqdesc.c:865)
> irq_domain_free_irqs (kernel/irq/irqdomain.c:1917)
> msi_domain_free_locked.part.0 (kernel/irq/msi.c:1619 kernel/irq/msi.c:1645)
> msi_domain_free_irqs_all_locked (kernel/irq/msi.c:1632)
> pci_msi_teardown_msi_irqs (drivers/pci/msi/irqdomain.c:28)
> pci_free_msi_irqs (drivers/pci/msi/msi.c:925)
> pci_disable_msix (drivers/pci/msi/api.c:200 drivers/pci/msi/api.c:193)
> e1000_request_irq (drivers/net/ethernet/intel/e1000e/netdev.c:2028)
> e1000e_open (drivers/net/ethernet/intel/e1000e/netdev.c:4681)
> __dev_open (net/core/dev.c:1702)
> netif_change_flags (net/core/dev.c:9806)
> do_setlink.isra.0 (net/core/rtnetlink.c:3207 (discriminator 1))
> rtnetlink_rcv_msg (net/core/rtnetlink.c:7068)
> netlink_rcv_skb (net/netlink/af_netlink.c:2556)
>
> Fixes: 4662e82b2cb4 ("e1000e: add support for new 82574L part")
> Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
> Assisted-by: Claude:claude-opus-4-8
Reviewed-by: Simon Horman <horms@kernel.org>
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH v5 net 3/7] i40e: make ring pointers unreachable before freeing via rcu
From: Loktionov, Aleksandr @ 2026-07-07 13:37 UTC (permalink / raw)
To: Fijalkowski, Maciej, intel-wired-lan@lists.osuosl.org
Cc: netdev@vger.kernel.org, Karlsson, Magnus, kuba@kernel.org,
pabeni@redhat.com, horms@kernel.org, Kitszel, Przemyslaw,
Keller, Jacob E, Fijalkowski, Maciej, Sashiko AI Review
In-Reply-To: <20260701124524.13644-4-maciej.fijalkowski@intel.com>
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> Of Maciej Fijalkowski
> Sent: Wednesday, July 1, 2026 2:45 PM
> To: intel-wired-lan@lists.osuosl.org
> Cc: netdev@vger.kernel.org; Karlsson, Magnus
> <magnus.karlsson@intel.com>; kuba@kernel.org; pabeni@redhat.com;
> horms@kernel.org; Kitszel, Przemyslaw <przemyslaw.kitszel@intel.com>;
> Keller, Jacob E <jacob.e.keller@intel.com>; Fijalkowski, Maciej
> <maciej.fijalkowski@intel.com>; Sashiko AI Review <sashiko-
> bot@kernel.org>
> Subject: [Intel-wired-lan] [PATCH v5 net 3/7] i40e: make ring pointers
> unreachable before freeing via rcu
>
> Sashiko reports:
> ***
> > err_config:
> > + i40e_vsi_free_q_vectors(vsi);
> > +err_qvec:
> > i40e_vsi_clear_rings(vsi);
> This is a pre-existing issue, but can the sequence in
> i40e_vsi_clear_rings() lead to an RCU ordering violation?
> In i40e_vsi_clear_rings(), the rings are freed before the array
> pointers are
> nullified:
> kfree_rcu(vsi->tx_rings[i], rcu);
> WRITE_ONCE(vsi->tx_rings[i], NULL);
> Under RCU rules, a pointer must be made unreachable to new readers
> before it is handed off to kfree_rcu(). Could a new RCU reader (like
> i40e_get_netdev_stats_struct_tx()) fetch the pointer after kfree_rcu()
> is invoked, and access freed memory if the grace period expires while
> the reader is still active?
> ***
>
> Save the Tx ring pointer before clearing the published ring array
> slots and pass the saved pointer to kfree_rcu(). This preserves the
> intended RCU ordering, where new readers can no longer discover the
> ring through
> vsi->tx_rings/rx_rings/xdp_rings before the object is queued for
> deferred freeing, while avoiding a NULL kfree_rcu() argument after the
> slot has already been cleared. Since the Tx pointer is the base of the
> per-queue-pair allocation block, re-reading vsi->tx_rings[i] after
> WRITE_ONCE(..., NULL) would otherwise turn the free into a no-op and
> leak the whole ring block.
>
> Fixes: 9f65e15b4f98 ("i40e: Move rings from pointer to array to array
> of pointers")
> Reported-by: Sashiko AI Review <sashiko-bot@kernel.org>
> Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
> ---
> drivers/net/ethernet/intel/i40e/i40e_main.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c
> b/drivers/net/ethernet/intel/i40e/i40e_main.c
> index 471fa7f7b643..a29a89192a7a 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
> @@ -11699,11 +11699,13 @@ static void i40e_vsi_clear_rings(struct
> i40e_vsi *vsi)
>
> if (vsi->tx_rings && vsi->tx_rings[0]) {
> for (i = 0; i < vsi->alloc_queue_pairs; i++) {
> - kfree_rcu(vsi->tx_rings[i], rcu);
> + struct i40e_ring *tx_ring = vsi->tx_rings[i];
> +
> WRITE_ONCE(vsi->tx_rings[i], NULL);
> WRITE_ONCE(vsi->rx_rings[i], NULL);
> if (vsi->xdp_rings)
> WRITE_ONCE(vsi->xdp_rings[i], NULL);
> + kfree_rcu(tx_ring, rcu);
> }
> }
> }
> --
> 2.43.0
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH v5 net 2/7] i40e: avoid null ptr dereference in i40e_ptp_stop()
From: Loktionov, Aleksandr @ 2026-07-07 13:36 UTC (permalink / raw)
To: Fijalkowski, Maciej, intel-wired-lan@lists.osuosl.org
Cc: netdev@vger.kernel.org, Karlsson, Magnus, kuba@kernel.org,
pabeni@redhat.com, horms@kernel.org, Kitszel, Przemyslaw,
Keller, Jacob E, Fijalkowski, Maciej, Sashiko AI Review
In-Reply-To: <20260701124524.13644-3-maciej.fijalkowski@intel.com>
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> Of Maciej Fijalkowski
> Sent: Wednesday, July 1, 2026 2:45 PM
> To: intel-wired-lan@lists.osuosl.org
> Cc: netdev@vger.kernel.org; Karlsson, Magnus
> <magnus.karlsson@intel.com>; kuba@kernel.org; pabeni@redhat.com;
> horms@kernel.org; Kitszel, Przemyslaw <przemyslaw.kitszel@intel.com>;
> Keller, Jacob E <jacob.e.keller@intel.com>; Fijalkowski, Maciej
> <maciej.fijalkowski@intel.com>; Sashiko AI Review <sashiko-
> bot@kernel.org>
> Subject: [Intel-wired-lan] [PATCH v5 net 2/7] i40e: avoid null ptr
> dereference in i40e_ptp_stop()
>
> Sashiko reports:
> ***
> If an allocation fails here during i40e_rebuild(), i40e_vsi_clear()
> frees the main VSI and sets pf->vsi[vsi->idx] = NULL, and the rebuild
> will abort without stopping the PTP clock.
> Later, if the device is removed or unbound, i40e_remove()
> unconditionally calls i40e_ptp_stop(), which does:
> drivers/net/ethernet/intel/i40e/i40e_ptp.c:i40e_ptp_stop() {
> ...
> struct i40e_vsi *main_vsi = i40e_pf_get_main_vsi(pf);
> ...
> dev_info(&pf->pdev->dev, "%s: removed PHC on %s\n", __func__,
> main_vsi->netdev->name);
> ...
> }
> Would this cause a NULL pointer dereference since main_vsi is now
> NULL?
> ***
>
> Check if main_vsi is not null before calling dev_info().
>
> Fixes: beb0dff1251d ("i40e: enable PTP")
> Reported-by: Sashiko AI Review <sashiko-bot@kernel.org>
> Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
> ---
> drivers/net/ethernet/intel/i40e/i40e_ptp.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_ptp.c
> b/drivers/net/ethernet/intel/i40e/i40e_ptp.c
> index ff62b5f2c815..ca93df4d6785 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_ptp.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_ptp.c
> @@ -1556,8 +1556,9 @@ void i40e_ptp_stop(struct i40e_pf *pf)
> if (pf->ptp_clock) {
> ptp_clock_unregister(pf->ptp_clock);
> pf->ptp_clock = NULL;
> - dev_info(&pf->pdev->dev, "%s: removed PHC on %s\n",
> __func__,
> - main_vsi->netdev->name);
> + if (main_vsi)
> + dev_info(&pf->pdev->dev, "%s: removed PHC on
> %s\n", __func__,
> + main_vsi->netdev->name);
> }
>
> if (i40e_is_ptp_pin_dev(&pf->hw)) {
> --
> 2.43.0
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
^ permalink raw reply
* Re: [PATCH net 1/2] net: macb: reprogram TBQP after shuffling the TX ring on link-up
From: Taedcke, Christian @ 2026-07-07 13:36 UTC (permalink / raw)
To: Sebastian Andrzej Siewior, christian.taedcke
Cc: Théo Lebrun, Conor Dooley, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Kevin Hao,
Simon Horman, Clark Williams, Steven Rostedt, Robert Hancock,
netdev, linux-kernel, linux-rt-devel, stable
In-Reply-To: <20260706150422.-wYiCBuE@linutronix.de>
Thank you for the quick review! This is my first Linux kernel
contribution, so I appreciate your feedback here.
On 7/6/2026 5:04 PM, Sebastian Andrzej Siewior wrote:
> On 2026-07-06 16:02:14 [+0200], Christian Taedcke via B4 Relay wrote:
>> From: Christian Taedcke <christian.taedcke@weidmueller.com>
>>
>> gem_shuffle_tx_one_ring() rotates the software TX ring so that the
>> tail sits at index 0 and resets queue->tx_tail to 0, but it never
>> reprograms the hardware transmit buffer queue pointer (TBQP). Other
>> paths that reset tx_tail to the ring base (macb_init_buffers() and
>> macb_tx_error_task()) also reprogram TBQP to queue->tx_ring_dma; this
>> path does not, leaving TBQP pointing at a stale descriptor.
>>
>> gem_shuffle_tx_rings() runs on every link-up from
>> macb_mac_link_up(). After a few link up/down flaps that leave
>> un-completed descriptors in the ring, the stale TBQP keeps pointing at
>> a descriptor whose used bit is set. When TX is re-enabled on link-up,
>> the GEM reads that used descriptor and raises TXUBR. macb_interrupt()
>> schedules the TX NAPI, macb_tx_poll() makes no progress (work_done ==
>> 0) and macb_tx_restart() re-issues TSTART, which makes the controller
>> read the same used descriptor again and re-assert TXUBR. As the MAC
>> interrupt is level-triggered, it never deasserts and one CPU is pegged
>> at 100% in the threaded handler, eventually triggering "sched: RT
>> throttling activated" and a dead network interface.
>
> But this should also happen with !RT at which point the interrupt runs
> at 100% CPU and the softirq has hardly an chance to make progress, no?
Problably yes. I had issues reproducing the issue since it appeared only
on specific test setups when a lot packets where sent to another network
device and this device's power was cut. And even then on some test runs
the issue was not visible after a few hundred iterations. But after a
restart of the whole test setup (including cold reboot of all devices)
the issue sometimes appeared after 5 iterations.
I only metion RT here because it was the only thing i tested. I only ran
the RT kernel.
Should I change the description?
>
>> Fix it by reprogramming TBQP to the ring base on every path of
>> gem_shuffle_tx_one_ring() that resets tx_tail to 0, mirroring
>> macb_tx_error_task(). The early return for an already-aligned tail is
>> left untouched as TBQP is already consistent there. This is safe
>> because the shuffle runs from macb_mac_link_up() while TE is still
>> disabled, so the transmitter is halted.
>>
>> Fixes: 881a0263d502 ("net: macb: Shuffle the tx ring before enabling tx")
>
> This is v7.0-rc4. So that RT tree of yours has some backports or did you
> run into this while trying to reproduce it upstream?
There were some backports. I ran this on the linux-yocto kernel
https://git.yoctoproject.org/linux-yocto branch
v6.6/standard/preempt-rt/base.
The "Fixes:" commit was backported as 0a47c3889fcd before their version
of 6.6.130.
The kernel i reproduced the issue on was linux-yocto branch
v6.6/standard/preempt-rt/base after 6.6.142 was merged into it.
>
>> Cc: stable@vger.kernel.org
>> Assisted-by: Claude:claude-opus-4-8
>> Signed-off-by: Christian Taedcke <christian.taedcke@weidmueller.com>
>> ---
>> drivers/net/ethernet/cadence/macb_main.c | 9 ++++++++-
>> 1 file changed, 8 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
>> index fd282a1700fb..b11cb8f068b7 100644
>> --- a/drivers/net/ethernet/cadence/macb_main.c
>> +++ b/drivers/net/ethernet/cadence/macb_main.c
>> @@ -820,7 +820,7 @@ static void gem_shuffle_tx_one_ring(struct macb_queue *queue)
>> if (!count) {
>> queue->tx_head = 0;
>> queue->tx_tail = 0;
>> - goto unlock;
>> + goto reset_hw_ptr;
>
> This update is even needed for count == 0 case? I kind of do understand
> that you need to updated if you shuffled the descriptors around.
This was my understanding before researching more because of the email
from Kevin in this thread: count == 0 may happen anywhere within the ring
(e.g. when both the tail and the head point to the middle).
Resetting queue->tx_tail to 0 but not resetting TBQP results in them
being out-of-sync.
But as Kevin mentioned in his email TBQP is reset to the original
value when transmit is disabled (by setting bit 3 in NCR register).
I will investigate this further why my code change fixed the issue for
me, but according to the documentation in [1] it should be a no-op.
[1] https://docs.amd.com/v/u/en-US/ug1085-zynq-ultrascale-trm pg. 1040
>
>> }
>>
>> shift = tail % ring_size;
>> @@ -869,6 +869,13 @@ static void gem_shuffle_tx_one_ring(struct macb_queue *queue)
>> /* Make descriptor updates visible to hardware */
>> wmb();
>>
>> +reset_hw_ptr:
>> + /* tx_tail was reset to the ring base, so TBQP must be reprogrammed
>> + * to match; otherwise it keeps pointing at a stale descriptor. Safe
>> + * to write directly here as TX is still disabled (called from
>> + * macb_mac_link_up() before TE is set).
>> + */
>> + queue_writel(queue, TBQP, lower_32_bits(queue->tx_ring_dma));
>> unlock:
>> spin_unlock_irqrestore(&queue->tx_ptr_lock, flags);
>> }
>>
>
> Sebastian
Christian
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH v5 net 1/7] i40e: unregister netdev before clearing VSI on reinit failure
From: Loktionov, Aleksandr @ 2026-07-07 13:35 UTC (permalink / raw)
To: Fijalkowski, Maciej, intel-wired-lan@lists.osuosl.org
Cc: netdev@vger.kernel.org, Karlsson, Magnus, kuba@kernel.org,
pabeni@redhat.com, horms@kernel.org, Kitszel, Przemyslaw,
Keller, Jacob E, Fijalkowski, Maciej
In-Reply-To: <20260701124524.13644-2-maciej.fijalkowski@intel.com>
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> Of Maciej Fijalkowski
> Sent: Wednesday, July 1, 2026 2:45 PM
> To: intel-wired-lan@lists.osuosl.org
> Cc: netdev@vger.kernel.org; Karlsson, Magnus
> <magnus.karlsson@intel.com>; kuba@kernel.org; pabeni@redhat.com;
> horms@kernel.org; Kitszel, Przemyslaw <przemyslaw.kitszel@intel.com>;
> Keller, Jacob E <jacob.e.keller@intel.com>; Fijalkowski, Maciej
> <maciej.fijalkowski@intel.com>
> Subject: [Intel-wired-lan] [PATCH v5 net 1/7] i40e: unregister netdev
> before clearing VSI on reinit failure
>
> i40e_vsi_reinit_setup() tears down the existing VSI queue/ring backing
> state before allocating replacement arrays and queue tracking. If one
> of these early allocations fails, the function jumps directly to
> err_vsi and calls i40e_vsi_clear().
>
> For a registered netdev, this frees the VSI while netdev_priv(netdev)-
> >vsi can still point at it, leaving the registered netdev with
> dangling private driver state.
>
> Split the error path so failures after destructive reinit teardown
> first unregister and free the netdev before clearing the VSI.
>
> Fixes: d2a69fefd756 ("i40e: Fix changing previously set
> num_queue_pairs for PFs")
> Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
> ---
> drivers/net/ethernet/intel/i40e/i40e_main.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c
> b/drivers/net/ethernet/intel/i40e/i40e_main.c
> index a04683004a56..471fa7f7b643 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
> @@ -14274,7 +14274,7 @@ static struct i40e_vsi
> *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
> i40e_set_num_rings_in_vsi(vsi);
> ret = i40e_vsi_alloc_arrays(vsi, false);
> if (ret)
> - goto err_vsi;
> + goto err_netdev;
>
> alloc_queue_pairs = vsi->alloc_queue_pairs *
> (i40e_enabled_xdp_vsi(vsi) ? 2 : 1); @@ -
> 14284,7 +14284,7 @@ static struct i40e_vsi
> *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
> dev_info(&pf->pdev->dev,
> "failed to get tracking for %d queues for VSI %d
> err %d\n",
> alloc_queue_pairs, vsi->seid, ret);
> - goto err_vsi;
> + goto err_netdev;
> }
> vsi->base_queue = ret;
>
> @@ -14309,6 +14309,7 @@ static struct i40e_vsi
> *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
>
> err_rings:
> i40e_vsi_free_q_vectors(vsi);
> +err_netdev:
> if (vsi->netdev_registered) {
> vsi->netdev_registered = false;
> unregister_netdev(vsi->netdev);
> @@ -14318,7 +14319,6 @@ static struct i40e_vsi
> *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
> if (vsi->type == I40E_VSI_MAIN)
> i40e_devlink_destroy_port(pf);
> i40e_aq_delete_element(&pf->hw, vsi->seid, NULL);
> -err_vsi:
> i40e_vsi_clear(vsi);
> return NULL;
> }
> --
> 2.43.0
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH iwl-next v1 6/6] ixgbe: take rtnl lock before ixgbe_reset() is called
From: Loktionov, Aleksandr @ 2026-07-07 13:35 UTC (permalink / raw)
To: Jagielski, Jedrzej, intel-wired-lan@lists.osuosl.org
Cc: Nguyen, Anthony L, netdev@vger.kernel.org, Jagielski, Jedrzej
In-Reply-To: <20260702091553.57112-7-jedrzej.jagielski@intel.com>
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> Of Jedrzej Jagielski
> Sent: Thursday, July 2, 2026 11:16 AM
> To: intel-wired-lan@lists.osuosl.org
> Cc: Nguyen, Anthony L <anthony.l.nguyen@intel.com>;
> netdev@vger.kernel.org; Jagielski, Jedrzej
> <jedrzej.jagielski@intel.com>
> Subject: [Intel-wired-lan] [PATCH iwl-next v1 6/6] ixgbe: take rtnl
> lock before ixgbe_reset() is called
>
> Previous commit introduced ixgbe_mac_addr_refresh which touches netdev
> struct by updating mac addr. It should operate after taking rtnl lock.
> One of the callers is ixgbe_reset(). Most of scenarios when
> ixgbe_reset() is called met taking lock requirement, but there is a
> ixgbe_resume() path which calls ixgbe_reset() ->
> ixgbe_mac_addr_refresh() without taking the lock. So there is a risk
> of race.
>
> Move rtnl_lock() before ixgbe_reset() is called.
>
> Signed-off-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
> ---
> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> index ce2b1e208c0f..c7261eb0e9b0 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> @@ -7574,11 +7574,11 @@ static int ixgbe_resume(struct device *dev_d)
>
> device_wakeup_disable(dev_d);
>
> + rtnl_lock();
> ixgbe_reset(adapter);
>
> IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0);
>
> - rtnl_lock();
> err = ixgbe_init_interrupt_scheme(adapter);
> if (!err && netif_running(netdev))
> err = ixgbe_open(netdev);
> --
> 2.31.1
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH iwl-next v1 5/6] ixgbe: E610: add MAC address runtime refresh
From: Loktionov, Aleksandr @ 2026-07-07 13:34 UTC (permalink / raw)
To: Jagielski, Jedrzej, intel-wired-lan@lists.osuosl.org
Cc: Nguyen, Anthony L, netdev@vger.kernel.org, Jagielski, Jedrzej
In-Reply-To: <20260702091553.57112-6-jedrzej.jagielski@intel.com>
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> Of Jedrzej Jagielski
> Sent: Thursday, July 2, 2026 11:16 AM
> To: intel-wired-lan@lists.osuosl.org
> Cc: Nguyen, Anthony L <anthony.l.nguyen@intel.com>;
> netdev@vger.kernel.org; Jagielski, Jedrzej
> <jedrzej.jagielski@intel.com>
> Subject: [Intel-wired-lan] [PATCH iwl-next v1 5/6] ixgbe: E610: add
> MAC address runtime refresh
>
> Whenever MGMT requests MAC addr change and FW does it, driver does not
> get aligned to that change. Current - legacy approach doesn't handle
> such scenario.
>
> Poll RAR0 (Receive Address Register) each service task cycle and
> update driver and netdev structs once new MAC addr is detected. It may
> happen that FW updates MAC address stored in RAR0 during runtime so SW
> shall fetch the new address.
>
> Refresh addr also during reset path to ensure the address survives
> RAR0 clearing during init_hw().
>
> Signed-off-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
> ---
> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 37
> +++++++++++++++++++
> 1 file changed, 37 insertions(+)
>
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> index d1cfe913081f..ce2b1e208c0f 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> @@ -6499,6 +6499,36 @@ void ixgbe_disable_tx(struct ixgbe_adapter
> *adapter)
> }
> }
>
> +static void ixgbe_mac_addr_refresh(struct ixgbe_adapter *adapter) {
> + struct net_device *netdev = adapter->netdev;
> + struct ixgbe_hw *hw = &adapter->hw;
> + int err;
> +
> + if (hw->mac.type != ixgbe_mac_e610)
> + return;
> +
> + /* fetch address stored currently in RAR0 in case the addr has
> been
> + * altered by FW; if so, use it as the default one
> + */
> + err = hw->mac.ops.get_mac_addr(hw, hw->mac.addr);
> + if (err) {
> + e_dev_warn("Cannot get MAC address\n");
> + return;
> + }
> +
> + if (ether_addr_equal(netdev->dev_addr, hw->mac.addr) ||
> + !is_valid_ether_addr(hw->mac.addr))
> + return;
> +
> + ASSERT_RTNL();
> +
> + eth_hw_addr_set(netdev, hw->mac.addr);
> + ether_addr_copy(adapter->mac_table[0].addr, hw->mac.addr);
> +
> + call_netdevice_notifiers(NETDEV_CHANGEADDR, netdev); }
> +
> void ixgbe_reset(struct ixgbe_adapter *adapter) {
> struct ixgbe_hw *hw = &adapter->hw;
> @@ -6516,6 +6546,8 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)
> IXGBE_FLAG2_SFP_NEEDS_RESET);
> adapter->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG;
>
> + ixgbe_mac_addr_refresh(adapter);
> +
> err = hw->mac.ops.init_hw(hw);
> switch (err) {
> case 0:
> @@ -8701,6 +8733,11 @@ static void ixgbe_service_task(struct
> work_struct *work)
> ixgbe_handle_fw_event(adapter);
> ixgbe_check_media_subtask(adapter);
> }
> +
> + rtnl_lock();
> + ixgbe_mac_addr_refresh(adapter);
> + rtnl_unlock();
> +
> ixgbe_reset_subtask(adapter);
> ixgbe_phy_interrupt_subtask(adapter);
> ixgbe_sfp_detection_subtask(adapter);
> --
> 2.31.1
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH 2/4] ice: use kzalloc() to allocate staging buffer for reading from GNSS
From: Loktionov, Aleksandr @ 2026-07-07 13:33 UTC (permalink / raw)
To: Mike Rapoport (Microsoft), Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Manish Chopra, Paolo Abeni
Cc: Edward Cree, Kitszel, Przemyslaw, Sudarsana Kalluru,
Nguyen, Anthony L, intel-wired-lan@lists.osuosl.org,
linux-kernel@vger.kernel.org, linux-mm@kvack.org,
linux-net-drivers@amd.com, netdev@vger.kernel.org
In-Reply-To: <20260701-b4-drivers-ethernet-v1-2-58776615db6e@kernel.org>
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> Of Mike Rapoport (Microsoft)
> Sent: Wednesday, July 1, 2026 3:57 PM
> To: Andrew Lunn <andrew+netdev@lunn.ch>; David S. Miller
> <davem@davemloft.net>; Eric Dumazet <edumazet@google.com>; Jakub
> Kicinski <kuba@kernel.org>; Manish Chopra <manishc@marvell.com>; Paolo
> Abeni <pabeni@redhat.com>
> Cc: Edward Cree <ecree.xilinx@gmail.com>; Kitszel, Przemyslaw
> <przemyslaw.kitszel@intel.com>; Sudarsana Kalluru
> <skalluru@marvell.com>; Nguyen, Anthony L
> <anthony.l.nguyen@intel.com>; Mike Rapoport <rppt@kernel.org>; intel-
> wired-lan@lists.osuosl.org; linux-kernel@vger.kernel.org; linux-
> mm@kvack.org; linux-net-drivers@amd.com; netdev@vger.kernel.org
> Subject: [Intel-wired-lan] [PATCH 2/4] ice: use kzalloc() to allocate
> staging buffer for reading from GNSS
>
> ice_gnss_read() uses get_zeroed_page() to allocate a staging buffer
> for reading GNSS module data via I2C bus.
>
> This buffer can be allocated with kmalloc() as there's nothing special
> about it to go directly to the page allocator.
>
> kmalloc() provides a better API that does not require ugly casts and
> kfree() does not need to know the size of the freed object.
>
> Performance difference between kmalloc() and __get_free_pages() is not
> measurable as both allocators take an object/page from a per-CPU list
> for fast path allocations.
>
> For the slow path the performance is anyway determined by the amount
> of reclaim involved rather than by what allocator is used.
>
> Replace use of get_zeroed_page() with kzalloc() and free_page() with
> kfree().
>
> Link: https://lore.kernel.org/all/635405e4-9423-4a25-a6e7-
> e03c8ea0bcbe@redhat.com
> Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
> ---
> drivers/net/ethernet/intel/ice/ice_gnss.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/ice/ice_gnss.c
> b/drivers/net/ethernet/intel/ice/ice_gnss.c
> index 8fd954f1ebd6..7d21c3417b0b 100644
> --- a/drivers/net/ethernet/intel/ice/ice_gnss.c
> +++ b/drivers/net/ethernet/intel/ice/ice_gnss.c
> @@ -2,6 +2,7 @@
> /* Copyright (C) 2021-2022, Intel Corporation. */
>
> #include "ice.h"
> +#include <linux/slab.h>
> #include "ice_lib.h"
>
> /**
> @@ -124,7 +125,7 @@ static void ice_gnss_read(struct kthread_work
> *work)
>
> data_len = min_t(typeof(data_len), data_len, PAGE_SIZE);
>
> - buf = (char *)get_zeroed_page(GFP_KERNEL);
> + buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
> if (!buf) {
> err = -ENOMEM;
> goto requeue;
> @@ -151,7 +152,7 @@ static void ice_gnss_read(struct kthread_work
> *work)
> count, i);
> delay = ICE_GNSS_TIMER_DELAY_TIME;
> free_buf:
> - free_page((unsigned long)buf);
> + kfree(buf);
> requeue:
> kthread_queue_delayed_work(gnss->kworker, &gnss->read_work,
> delay);
> if (err)
>
> --
> 2.53.0
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH iwl-net v3 2/2] ice: preserve uplink DFLT Rx rule on switchdev release
From: Loktionov, Aleksandr @ 2026-07-07 13:32 UTC (permalink / raw)
To: Oros, Petr, netdev@vger.kernel.org
Cc: Vecera, Ivan, Alice Michael, Kitszel, Przemyslaw, Eric Dumazet,
linux-kernel@vger.kernel.org, Martyna Szapar-Mudlaw, Andrew Lunn,
Marcin Szycik, Nguyen, Anthony L, Simon Horman,
intel-wired-lan@lists.osuosl.org, Keller, Jacob E, Jakub Kicinski,
Paolo Abeni, David S. Miller
In-Reply-To: <20260701133601.2118382-3-poros@redhat.com>
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> Of Petr Oros
> Sent: Wednesday, July 1, 2026 3:36 PM
> To: netdev@vger.kernel.org
> Cc: Vecera, Ivan <ivecera@redhat.com>; Alice Michael
> <alice.michael@intel.com>; Kitszel, Przemyslaw
> <przemyslaw.kitszel@intel.com>; Eric Dumazet <edumazet@google.com>;
> linux-kernel@vger.kernel.org; Martyna Szapar-Mudlaw <martyna.szapar-
> mudlaw@linux.intel.com>; Andrew Lunn <andrew+netdev@lunn.ch>; Marcin
> Szycik <marcin.szycik@linux.intel.com>; Nguyen, Anthony L
> <anthony.l.nguyen@intel.com>; Simon Horman <horms@kernel.org>; intel-
> wired-lan@lists.osuosl.org; Keller, Jacob E
> <jacob.e.keller@intel.com>; Jakub Kicinski <kuba@kernel.org>; Paolo
> Abeni <pabeni@redhat.com>; David S. Miller <davem@davemloft.net>
> Subject: [Intel-wired-lan] [PATCH iwl-net v3 2/2] ice: preserve uplink
> DFLT Rx rule on switchdev release
>
> When the uplink PF is promiscuous, ice_vsi_sync_fltr() installs an
> ICE_SW_LKUP_DFLT catch-all Rx rule on the uplink VSI. Entering
> switchdev re-affirms it through the idempotent ice_set_dflt_vsi(), but
> ice_eswitch_release_env() removed both the Rx and Tx DFLT rules
> unconditionally on teardown. That clobbered a promisc-owned Rx rule:
> it disappeared while IFF_PROMISC was still set and the sync path was
> not retriggered, leaving the uplink without the catch-all the netdev
> requested.
>
> Skip the Rx DFLT removal when the uplink is promiscuous, both in
> ice_eswitch_release_env() and the err_def_tx unwind of
> ice_eswitch_setup_env(); the Tx leg, owned by switchdev, is still
> removed.
> Test the live netdev->flags, the same value ena_rx_filtering() ->
> ice_cfg_vlan_pruning() above already keys on, so the preserved rule
> and the pruning state stay consistent, including for a promisc change
> made while switchdev ran (which never reached the gated filter sync).
>
> Fixes: 5c07be96d8b3 ("ice: Avoid setting default Rx VSI twice in
> switchdev setup")
> Signed-off-by: Petr Oros <poros@redhat.com>
> ---
> v3:
> - Corrected the Fixes tag from 1a1c40df2e80 ("ice: set and release
> switchdev environment") to 5c07be96d8b3 ("ice: Avoid setting default
> Rx VSI twice in switchdev setup"), the commit that made
> ice_eswitch_setup_env() use the idempotent ice_set_dflt_vsi();
> before
> it a pre-existing promisc DFLT rule made setup fail with -EEXIST so
> the
> release path was never reached. No code change.
>
> v2: https://lore.kernel.org/all/20260622113428.2565255-3-
> poros@redhat.com/
> v1:
> https://lore.kernel.org/all/deef5756e534ef06c12d910c5305d3fd205d30a0.1
> 781786935.git.poros@redhat.com/
> ---
> drivers/net/ethernet/intel/ice/ice_eswitch.c | 18 ++++++++++++++----
> 1 file changed, 14 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/ice/ice_eswitch.c
> b/drivers/net/ethernet/intel/ice/ice_eswitch.c
> index c30e27bbfe6e25..07e2016fb9481f 100644
> --- a/drivers/net/ethernet/intel/ice/ice_eswitch.c
> +++ b/drivers/net/ethernet/intel/ice/ice_eswitch.c
> @@ -66,8 +66,10 @@ static int ice_eswitch_setup_env(struct ice_pf *pf)
> ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx, false,
> ICE_FLTR_TX);
> err_def_tx:
> - ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx, false,
> - ICE_FLTR_RX);
> + /* keep the Rx DFLT rule if the uplink is promiscuous (see
> release_env) */
> + if (!(uplink_vsi->netdev->flags & IFF_PROMISC))
> + ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx,
> + false, ICE_FLTR_RX);
> err_def_rx:
> ice_vsi_del_vlan_zero(uplink_vsi);
> err_vlan_zero:
> @@ -276,8 +278,16 @@ static void ice_eswitch_release_env(struct ice_pf
> *pf)
> vlan_ops->ena_rx_filtering(uplink_vsi);
> ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx, false,
> ICE_FLTR_TX);
> - ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx, false,
> - ICE_FLTR_RX);
> +
> + /* Keep the Rx DFLT rule if the uplink is promiscuous; it must
> outlive
> + * the session. Test the live netdev->flags, the same value
> + * ena_rx_filtering() -> ice_cfg_vlan_pruning() above keys its
> decision
> + * on, so the preserved DFLT rule and the pruning state stay
> consistent.
> + */
> + if (!(uplink_vsi->netdev->flags & IFF_PROMISC))
> + ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx,
> + false, ICE_FLTR_RX);
> +
> ice_fltr_add_mac_and_broadcast(uplink_vsi,
> uplink_vsi->port_info-
> >mac.perm_addr,
> ICE_FWD_TO_VSI);
> --
> 2.54.0
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH net v2] idpf: Fix mailbox IRQ name leak on request failure
From: Loktionov, Aleksandr @ 2026-07-07 13:31 UTC (permalink / raw)
To: Yuho Choi, Nguyen, Anthony L, Kitszel, Przemyslaw, Andrew Lunn,
David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: intel-wired-lan@lists.osuosl.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <20260703050332.121551-1-dbgh9129@gmail.com>
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> Of Yuho Choi
> Sent: Friday, July 3, 2026 7:04 AM
> To: Nguyen, Anthony L <anthony.l.nguyen@intel.com>; Kitszel,
> Przemyslaw <przemyslaw.kitszel@intel.com>; Andrew Lunn
> <andrew+netdev@lunn.ch>; David S . Miller <davem@davemloft.net>; Eric
> Dumazet <edumazet@google.com>; Jakub Kicinski <kuba@kernel.org>; Paolo
> Abeni <pabeni@redhat.com>
> Cc: intel-wired-lan@lists.osuosl.org; netdev@vger.kernel.org; linux-
> kernel@vger.kernel.org; Yuho Choi <dbgh9129@gmail.com>
> Subject: [Intel-wired-lan] [PATCH net v2] idpf: Fix mailbox IRQ name
> leak on request failure
>
> idpf_mb_intr_req_irq() allocates the mailbox IRQ name before calling
> request_irq(). On success, the name is released later through
> kfree(free_irq()), but request_irq() failure returns without freeing
> it.
>
> Free the allocated name on the request_irq() failure path.
>
> Fixes: 4930fbf419a7 ("idpf: add core init and interrupt request")
> Signed-off-by: Yuho Choi <dbgh9129@gmail.com>
> ---
> Changes in v2:
> - Add net tag for the patch subject line.
> drivers/net/ethernet/intel/idpf/idpf_lib.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/intel/idpf/idpf_lib.c
> b/drivers/net/ethernet/intel/idpf/idpf_lib.c
> index cf966fe6c759..bb81e620c5c8 100644
> --- a/drivers/net/ethernet/intel/idpf/idpf_lib.c
> +++ b/drivers/net/ethernet/intel/idpf/idpf_lib.c
> @@ -139,7 +139,7 @@ static int idpf_mb_intr_req_irq(struct
> idpf_adapter *adapter)
> if (err) {
> dev_err(&adapter->pdev->dev,
> "IRQ request for mailbox failed, error: %d\n",
> err);
> -
> + kfree(name);
> return err;
> }
>
> --
> 2.43.0
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH iwl-net v2] ice: add missing xa_destroy for sched_node_ids
From: Loktionov, Aleksandr @ 2026-07-07 13:31 UTC (permalink / raw)
To: Keller, Jacob E, Nguyen, Anthony L, Kitszel, Przemyslaw
Cc: intel-wired-lan@lists.osuosl.org, netdev@vger.kernel.org,
Keller, Jacob E
In-Reply-To: <20260706-jk-fix-missing-xa-destroy-v2-1-b83b0f02beef@intel.com>
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> Of Jacob Keller
> Sent: Tuesday, July 7, 2026 1:31 AM
> To: Nguyen, Anthony L <anthony.l.nguyen@intel.com>; Kitszel,
> Przemyslaw <przemyslaw.kitszel@intel.com>
> Cc: intel-wired-lan@lists.osuosl.org; netdev@vger.kernel.org; Keller,
> Jacob E <jacob.e.keller@intel.com>
> Subject: [Intel-wired-lan] [PATCH iwl-net v2] ice: add missing
> xa_destroy for sched_node_ids
>
> Commit 16dfa49406bc ("ice: Introduce new parameters in
> ice_sched_node") added a sched_node_ids xarray to the port info
> structure, but never called xa_destroy on it.
>
> Since xarrays can allocate internal memory, this can result in a
> memory leak even if every element in the xarray has been removed.
>
> The xarray is currently embedded in the port_info structure. This
> appears to have been done because its use is within functions that
> take the port_info as a primary argument.
>
> However, this complicates managing the lifecycle of the field. The
> port_info structure is allocated in ice_init_hw() using devm, and it
> is not released until the devm cleanup when the driver is unloaded.
>
> The ice_init_hw() function is called in many places, including devlink
> reload, and possibly during DDP load after updating the Tx scheduler
> layout.
>
> Adding a call of xa_destroy to the ice_deinit_hw() causes Sashiko to
> raise multiple concerns due to potential ordering issues and possible
> ways that port_info could be a dangling reference.
>
> To handle this, move the sched_node_ids out of port_info and into the
> hw structure. All users of the array already have a pointer to hw
> anyways, and there is only one sched_node_ids per adapter. While here,
> remove the overly verbose comment explaining the nature of the
> sched_node_ids xarray.
>
> Add the missing xa_destroy to the cleanup path and to ice_deinit_hw(),
> ensuring that we properly release the xarray memory.
>
> This was caught by Sashiko during development of unrelated code.
>
> Fixes: 16dfa49406bc ("ice: Introduce new parameters in
> ice_sched_node")
> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
> ---
> Changes in v2:
> - Move sched_node_ids out of port_into into hw.
> - Link to v1: https://patch.msgid.link/20260514-jk-fix-missing-xa-
> destroy-v1-1-de437bf52347@intel.com
> ---
> drivers/net/ethernet/intel/ice/ice_type.h | 2 +-
> drivers/net/ethernet/intel/ice/ice_common.c | 9 ++++++---
> drivers/net/ethernet/intel/ice/ice_sched.c | 4 ++--
> 3 files changed, 9 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/ice/ice_type.h
> b/drivers/net/ethernet/intel/ice/ice_type.h
> index d9a5c1aae7c2..cf147a212707 100644
> --- a/drivers/net/ethernet/intel/ice/ice_type.h
> +++ b/drivers/net/ethernet/intel/ice/ice_type.h
> @@ -765,7 +765,6 @@ struct ice_port_info {
> /* List contain profile ID(s) and other params per layer */
> struct list_head rl_prof_list[ICE_AQC_TOPO_MAX_LEVEL_NUM];
> struct ice_qos_cfg qos_cfg;
...
> GFP_KERNEL);
> if (status) {
> ice_debug(hw, ICE_DBG_SCHED, "xa_alloc failed for
> sched node status =%d\n",
>
> ---
> base-commit: 9e05e91a9a847ed57926414bd7c2c5e54d6c56c6
> change-id: 20260514-jk-fix-missing-xa-destroy-d3f90f3711be
>
> Best regards,
> --
> Jacob Keller <jacob.e.keller@intel.com>
^ permalink raw reply
* RE: [PATCH net] tipc: fix u16 MTU truncation in media and bearer MTU validation
From: Tung Quang Nguyen @ 2026-07-07 13:29 UTC (permalink / raw)
To: Cen Zhang
Cc: netdev@vger.kernel.org, tipc-discussion@lists.sourceforge.net,
linux-kernel@vger.kernel.org,
AutonomousCodeSecurity@microsoft.com,
tgopinath@linux.microsoft.com, kys@microsoft.com,
jmaloy@redhat.com, davem@davemloft.net, edumazet@google.com,
kuba@kernel.org, pabeni@redhat.com, horms@kernel.org
In-Reply-To: <CAB8m9WgETt0AjmFwE=F-CKjGXsK6_WDv0=kbYRcC8-noo+amnA@mail.gmail.com>
>Subject: [PATCH net] tipc: fix u16 MTU truncation in media and bearer MTU
>validation
>
Your patch cannot be applied cleanly to net tree. I cannot build and run test.
Please rebase you patch before I review it.
>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):
>
> 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
>Signed-off-by: Cen Zhang (Microsoft) <blbllhy@gmail.com>
>---
> net/tipc/bearer.c | 6 ++++++
> net/tipc/udp_media.h | 5 +++++
> 2 files changed, 11 insertions(+)
>
>diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 05dcd2f9e..0926692dd
>100644
>--- a/net/tipc/bearer.c
>+++ b/net/tipc/bearer.c
>@@ -1163,6 +1163,12 @@ int __tipc_nl_bearer_set(struct sk_buff *skb, struct
>genl_info *info)
> "MTU value is out-of-range");
> return -EINVAL;
> }
>+ if (nla_get_u32(props[TIPC_NLA_PROP_MTU]) >
>+ U16_MAX) {
>+ NL_SET_ERR_MSG(info->extack,
>+ "MTU value is out-of-range");
>+ return -EINVAL;
>+ }
> b->mtu = nla_get_u32(props[TIPC_NLA_PROP_MTU]);
> tipc_node_apply_property(net, b, TIPC_NLA_PROP_MTU); #endif
>diff --git a/net/tipc/udp_media.h b/net/tipc/udp_media.h index
>e7455cc73..0d62a57c8 100644
>--- a/net/tipc/udp_media.h
>+++ b/net/tipc/udp_media.h
>@@ -48,6 +48,11 @@ int tipc_udp_nl_dump_remoteip(struct sk_buff *skb,
>struct netlink_callback *cb);
> /* check if configured MTU is too low for tipc headers */ static inline bool
>tipc_udp_mtu_bad(u32 mtu) {
>+ if (mtu > U16_MAX) {
>+ pr_warn("MTU too large for tipc bearer\n");
>+ return true;
>+ }
>+
> if (mtu >= (TIPC_MIN_BEARER_MTU + sizeof(struct iphdr) +
> sizeof(struct udphdr)))
> return false;
>--
>2.43.0
^ permalink raw reply
* [PATCH] net: hns3: fix speed configuration residue after driver reload
From: Jijie Shao @ 2026-07-07 13:24 UTC (permalink / raw)
To: davem, edumazet, kuba, pabeni, andrew+netdev, horms
Cc: shenjian15, liuyonglong, chenhao418, yangshuaisong, netdev,
linux-kernel, shaojijie
After setting a 100G optical port to 40G via ethtool and reloading
the driver, the port remains at 40G instead of reverting to the
firmware default speed of 100G.
In hclge_init_ae_dev(), hclge_update_port_info() reads mac.speed
from hardware, which reflects the last user configuration (e.g.
ethtool changes), not the firmware default. When req_speed is
overwritten with this value, hclge_set_autoneg_speed_dup() re-applies
the stale speed instead of the firmware default on non-copper media.
Fix by removing the req_speed overwrite in hclge_init_ae_dev(),
keeping only the req_autoneg synchronization. This ensures req_speed
retains the firmware default value set during hclge_configure().
Fixes: d9d349c4e8a0 ("net: hns3: differentiate autoneg default values between copper and fiber")
Signed-off-by: Jijie Shao <shaojijie@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index fc8587c80813..164c3ecf195c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -9498,12 +9498,8 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
if (ret)
goto err_ptp_uninit;
- if (hdev->hw.mac.media_type != HNAE3_MEDIA_TYPE_COPPER) {
+ if (hdev->hw.mac.media_type != HNAE3_MEDIA_TYPE_COPPER)
hdev->hw.mac.req_autoneg = hdev->hw.mac.autoneg;
- if (hdev->hw.mac.autoneg == AUTONEG_DISABLE &&
- hdev->hw.mac.speed != SPEED_UNKNOWN)
- hdev->hw.mac.req_speed = hdev->hw.mac.speed;
- }
ret = hclge_set_autoneg_speed_dup(hdev);
if (ret) {
base-commit: 9e05e91a9a847ed57926414bd7c2c5e54d6c56c6
--
2.33.0
^ permalink raw reply related
* RE: [PATCH net] tipc: serialize udp bearer replicast list updates
From: Tung Quang Nguyen @ 2026-07-07 13:21 UTC (permalink / raw)
To: Weiming Shi
Cc: Jon Maloy, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, tipc-discussion@lists.sourceforge.net, Xiang Mei,
netdev@vger.kernel.org
In-Reply-To: <20260706134716.3879-2-bestswngs@gmail.com>
>Subject: [PATCH net] tipc: serialize udp bearer replicast list updates
>
>tipc_udp_rcast_add() and cleanup_bearer() both update ub->rcast.list with
>list_add_rcu() / list_del_rcu(), but nothing serializes them. The add runs from
>the encap receive softirq (via tipc_udp_rcast_disc()) without rtnl_lock(), so it
>can race the cleanup delete and corrupt the
>list:
>
> list_del corruption. prev->next should be ffff8880298d7ab8,
> but was ffff88802449ad38. (prev=ffff888027e3ec98) kernel BUG at
>lib/list_debug.c:62!
> RIP: __list_del_entry_valid_or_report+0x17a/0x200
> Workqueue: events cleanup_bearer
> Call Trace:
> cleanup_bearer (net/tipc/udp_media.c:811)
> process_one_work (kernel/workqueue.c:3302)
> worker_thread (kernel/workqueue.c:3466)
>
>The bearer can be enabled from an unprivileged user namespace, as the
>TIPCv2 generic-netlink ops carry no GENL_ADMIN_PERM.
>
>Add a spinlock and take it around both list updates. Re-check for the peer
>under the lock in the add path so the check-then-add in
>tipc_udp_rcast_disc() cannot insert a duplicate.
>
>Fixes: ef20cd4dd163 ("tipc: introduce UDP replicast")
>Reported-by: Xiang Mei <xmei5@asu.edu>
>Assisted-by: Claude:claude-opus-4-8
>Signed-off-by: Weiming Shi <bestswngs@gmail.com>
>---
> net/tipc/udp_media.c | 19 ++++++++++++++++++-
> 1 file changed, 18 insertions(+), 1 deletion(-)
>
>diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c index
>62ae7f5b5840..601174297a16 100644
>--- a/net/tipc/udp_media.c
>+++ b/net/tipc/udp_media.c
>@@ -94,6 +94,7 @@ struct udp_replicast {
> * @ifindex: local address scope
> * @work: used to schedule deferred work on a bearer
> * @rcast: associated udp_replicast container
>+ * @rcast_lock: serializes updates to @rcast.list
> */
> struct udp_bearer {
> struct tipc_bearer __rcu *bearer;
>@@ -101,6 +102,7 @@ struct udp_bearer {
> u32 ifindex;
> struct work_struct work;
> struct udp_replicast rcast;
>+ spinlock_t rcast_lock; /* protects rcast.list */
> };
>
> static int tipc_udp_is_mcast_addr(struct udp_media_addr *addr) @@ -301,7
>+303,7 @@ static bool tipc_udp_is_known_peer(struct tipc_bearer *b, static
>int tipc_udp_rcast_add(struct tipc_bearer *b,
> struct udp_media_addr *addr)
> {
>- struct udp_replicast *rcast;
>+ struct udp_replicast *rcast, *tmp;
> struct udp_bearer *ub;
>
> ub = rcu_dereference_rtnl(b->media_ptr);
>@@ -319,6 +321,17 @@ static int tipc_udp_rcast_add(struct tipc_bearer *b,
>
> memcpy(&rcast->addr, addr, sizeof(struct udp_media_addr));
>
>+ /* tipc_udp_rcast_disc() adds from softirq without rtnl_lock(). */
Remove above comment because it is vague. Caller of tipc_udp_rcv() already holds rcu_read_lock().
>+ spin_lock_bh(&ub->rcast_lock);
Move 'spin_lock_bh(&ub->rcast_lock)' to above 'list_add_rcu(&rcast->list, &ub->rcast.list);' because only 'ub->rcast.list' needs protection.
>+ list_for_each_entry(tmp, &ub->rcast.list, list) {
>+ if (!memcmp(&tmp->addr, addr, sizeof(struct
>udp_media_addr))) {
>+ spin_unlock_bh(&ub->rcast_lock);
>+ dst_cache_destroy(&rcast->dst_cache);
>+ kfree(rcast);
>+ return 0;
>+ }
>+ }
This is wrong because the code in the loop is never executed. tipc_udp_is_known_peer() already verifies address duplication.
Please remove above code and fix tipc_udp_is_known_peer() as below:
static bool tipc_udp_is_known_peer(struct tipc_bearer *b,
struct udp_media_addr *addr)
{
- struct udp_replicast *rcast, *tmp;
+ struct udp_replicast *rcast;
struct udp_bearer *ub;
ub = rcu_dereference_rtnl(b->media_ptr);
@@ -292,7 +292,7 @@ static bool tipc_udp_is_known_peer(struct tipc_bearer *b,
return false;
}
- list_for_each_entry_safe(rcast, tmp, &ub->rcast.list, list) {
+ list_for_each_entry_rcu(rcast, &ub->rcast.list, list) {
if (!memcmp(&rcast->addr, addr, sizeof(struct udp_media_addr)))
return true;
}
>+
> if (ntohs(addr->proto) == ETH_P_IP)
> pr_info("New replicast peer: %pI4\n", &rcast->addr.ipv4); #if
>IS_ENABLED(CONFIG_IPV6) @@ -327,6 +340,7 @@ static int
>tipc_udp_rcast_add(struct tipc_bearer *b, #endif
> b->bcast_addr.broadcast = TIPC_REPLICAST_SUPPORT;
> list_add_rcu(&rcast->list, &ub->rcast.list);
>+ spin_unlock_bh(&ub->rcast_lock);
> return 0;
> }
>
>@@ -679,6 +693,7 @@ static int tipc_udp_enable(struct net *net, struct
>tipc_bearer *b,
> return -ENOMEM;
>
> INIT_LIST_HEAD(&ub->rcast.list);
>+ spin_lock_init(&ub->rcast_lock);
>
> if (!attrs[TIPC_NLA_BEARER_UDP_OPTS])
> goto err;
>@@ -819,10 +834,12 @@ static void cleanup_bearer(struct work_struct
>*work)
> struct udp_replicast *rcast, *tmp;
> struct tipc_net *tn;
>
>+ spin_lock_bh(&ub->rcast_lock);
> list_for_each_entry_safe(rcast, tmp, &ub->rcast.list, list) {
> list_del_rcu(&rcast->list);
> call_rcu_hurry(&rcast->rcu, rcast_free_rcu);
> }
>+ spin_unlock_bh(&ub->rcast_lock);
>
> tn = tipc_net(sock_net(ub->sk));
>
>--
>2.43.0
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox