diff options
| author | Hangbin Liu <liuhangbin@gmail.com> | 2025-09-05 09:15:32 +0000 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2025-10-02 13:39:04 +0200 |
| commit | 810167fa6f34adcebba8277f4f99faf53d2a5c76 (patch) | |
| tree | 22344823f0ae9f7a41c93a5dc919cf40d5afc353 /net/hsr | |
| parent | cedfcd09a338ed399d8d0e781cb5b910fa434a18 (diff) | |
| download | linux-810167fa6f34adcebba8277f4f99faf53d2a5c76.tar.gz linux-810167fa6f34adcebba8277f4f99faf53d2a5c76.tar.bz2 linux-810167fa6f34adcebba8277f4f99faf53d2a5c76.zip | |
hsr: use hsr_for_each_port_rtnl in hsr_port_get_hsr
[ Upstream commit 393c841fe4333cdd856d0ca37b066d72746cfaa6 ]
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: c5a759117210 ("net/hsr: Use list_head (and rcu) instead of array for slave devices.")
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250905091533.377443-3-liuhangbin@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'net/hsr')
| -rw-r--r-- | net/hsr/hsr_device.c | 3 | ||||
| -rw-r--r-- | net/hsr/hsr_main.c | 2 |
2 files changed, 4 insertions, 1 deletions
diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c index ff27935a2952..503f2064e732 100644 --- a/net/hsr/hsr_device.c +++ b/net/hsr/hsr_device.c @@ -231,6 +231,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; @@ -243,6 +244,8 @@ static netdev_tx_t hsr_dev_xmit(struct sk_buff *skb, struct net_device *dev) atomic_long_inc(&dev->tx_dropped); dev_kfree_skb_any(skb); } + rcu_read_unlock(); + return NETDEV_TX_OK; } diff --git a/net/hsr/hsr_main.c b/net/hsr/hsr_main.c index c325ddad539a..76a1958609e2 100644 --- a/net/hsr/hsr_main.c +++ b/net/hsr/hsr_main.c @@ -125,7 +125,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; |
