Commit 393c841f authored by Hangbin Liu's avatar Hangbin Liu Committed by Paolo Abeni
Browse files

hsr: use hsr_for_each_port_rtnl in hsr_port_get_hsr



hsr_port_get_hsr() iterates over ports using hsr_for_each_port(),
but many of its callers do not hold the required RCU lock.

Switch to hsr_for_each_port_rtnl(), since most callers already hold
the rtnl lock. After review, all callers are covered by either the rtnl
lock or the RCU lock, except hsr_dev_xmit(). Fix this by adding an
RCU read lock there.

Fixes: c5a75911 ("net/hsr: Use list_head (and rcu) instead of array for slave devices.")
Signed-off-by: default avatarHangbin Liu <liuhangbin@gmail.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250905091533.377443-3-liuhangbin@gmail.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 8884c693
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -226,6 +226,7 @@ static netdev_tx_t hsr_dev_xmit(struct sk_buff *skb, struct net_device *dev)
	struct hsr_priv *hsr = netdev_priv(dev);
	struct hsr_port *master;

	rcu_read_lock();
	master = hsr_port_get_hsr(hsr, HSR_PT_MASTER);
	if (master) {
		skb->dev = master->dev;
@@ -238,6 +239,8 @@ static netdev_tx_t hsr_dev_xmit(struct sk_buff *skb, struct net_device *dev)
		dev_core_stats_tx_dropped_inc(dev);
		dev_kfree_skb_any(skb);
	}
	rcu_read_unlock();

	return NETDEV_TX_OK;
}

+1 −1
Original line number Diff line number Diff line
@@ -134,7 +134,7 @@ struct hsr_port *hsr_port_get_hsr(struct hsr_priv *hsr, enum hsr_port_type pt)
{
	struct hsr_port *port;

	hsr_for_each_port(hsr, port)
	hsr_for_each_port_rtnl(hsr, port)
		if (port->type == pt)
			return port;
	return NULL;