Skip to content

Commit d04d9d1

Browse files
liuhangbingregkh
authored andcommitted
hsr: use rtnl lock when iterating over ports
[ Upstream commit 8884c69 ] hsr_for_each_port is called in many places without holding the RCU read lock, this may trigger warnings on debug kernels. Most of the callers are actually hold rtnl lock. So add a new helper hsr_for_each_port_rtnl to allow callers in suitable contexts to iterate ports safely without explicit RCU locking. This patch only fixed the callers that is hold rtnl lock. Other caller issues will be fixed in later patches. Fixes: c5a7591 ("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-2-liuhangbin@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent c707d2c commit d04d9d1

File tree

3 files changed

+13
-10
lines changed

3 files changed

+13
-10
lines changed

net/hsr/hsr_device.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ static bool hsr_check_carrier(struct hsr_port *master)
4949

5050
ASSERT_RTNL();
5151

52-
hsr_for_each_port(master->hsr, port) {
52+
hsr_for_each_port_rtnl(master->hsr, port) {
5353
if (port->type != HSR_PT_MASTER && is_slave_up(port->dev)) {
5454
netif_carrier_on(master->dev);
5555
return true;
@@ -105,7 +105,7 @@ int hsr_get_max_mtu(struct hsr_priv *hsr)
105105
struct hsr_port *port;
106106

107107
mtu_max = ETH_DATA_LEN;
108-
hsr_for_each_port(hsr, port)
108+
hsr_for_each_port_rtnl(hsr, port)
109109
if (port->type != HSR_PT_MASTER)
110110
mtu_max = min(port->dev->mtu, mtu_max);
111111

@@ -139,7 +139,7 @@ static int hsr_dev_open(struct net_device *dev)
139139

140140
hsr = netdev_priv(dev);
141141

142-
hsr_for_each_port(hsr, port) {
142+
hsr_for_each_port_rtnl(hsr, port) {
143143
if (port->type == HSR_PT_MASTER)
144144
continue;
145145
switch (port->type) {
@@ -172,7 +172,7 @@ static int hsr_dev_close(struct net_device *dev)
172172
struct hsr_priv *hsr;
173173

174174
hsr = netdev_priv(dev);
175-
hsr_for_each_port(hsr, port) {
175+
hsr_for_each_port_rtnl(hsr, port) {
176176
if (port->type == HSR_PT_MASTER)
177177
continue;
178178
switch (port->type) {
@@ -205,7 +205,7 @@ static netdev_features_t hsr_features_recompute(struct hsr_priv *hsr,
205205
* may become enabled.
206206
*/
207207
features &= ~NETIF_F_ONE_FOR_ALL;
208-
hsr_for_each_port(hsr, port)
208+
hsr_for_each_port_rtnl(hsr, port)
209209
features = netdev_increment_features(features,
210210
port->dev->features,
211211
mask);
@@ -483,7 +483,7 @@ static void hsr_set_rx_mode(struct net_device *dev)
483483

484484
hsr = netdev_priv(dev);
485485

486-
hsr_for_each_port(hsr, port) {
486+
hsr_for_each_port_rtnl(hsr, port) {
487487
if (port->type == HSR_PT_MASTER)
488488
continue;
489489
switch (port->type) {
@@ -505,7 +505,7 @@ static void hsr_change_rx_flags(struct net_device *dev, int change)
505505

506506
hsr = netdev_priv(dev);
507507

508-
hsr_for_each_port(hsr, port) {
508+
hsr_for_each_port_rtnl(hsr, port) {
509509
if (port->type == HSR_PT_MASTER)
510510
continue;
511511
switch (port->type) {
@@ -533,7 +533,7 @@ static int hsr_ndo_vlan_rx_add_vid(struct net_device *dev,
533533

534534
hsr = netdev_priv(dev);
535535

536-
hsr_for_each_port(hsr, port) {
536+
hsr_for_each_port_rtnl(hsr, port) {
537537
if (port->type == HSR_PT_MASTER ||
538538
port->type == HSR_PT_INTERLINK)
539539
continue;
@@ -579,7 +579,7 @@ static int hsr_ndo_vlan_rx_kill_vid(struct net_device *dev,
579579

580580
hsr = netdev_priv(dev);
581581

582-
hsr_for_each_port(hsr, port) {
582+
hsr_for_each_port_rtnl(hsr, port) {
583583
switch (port->type) {
584584
case HSR_PT_SLAVE_A:
585585
case HSR_PT_SLAVE_B:

net/hsr/hsr_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ static bool hsr_slave_empty(struct hsr_priv *hsr)
2222
{
2323
struct hsr_port *port;
2424

25-
hsr_for_each_port(hsr, port)
25+
hsr_for_each_port_rtnl(hsr, port)
2626
if (port->type != HSR_PT_MASTER)
2727
return false;
2828
return true;

net/hsr/hsr_main.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,9 @@ struct hsr_priv {
231231
#define hsr_for_each_port(hsr, port) \
232232
list_for_each_entry_rcu((port), &(hsr)->ports, port_list)
233233

234+
#define hsr_for_each_port_rtnl(hsr, port) \
235+
list_for_each_entry_rcu((port), &(hsr)->ports, port_list, lockdep_rtnl_is_held())
236+
234237
struct hsr_port *hsr_port_get_hsr(struct hsr_priv *hsr, enum hsr_port_type pt);
235238

236239
/* Caller must ensure skb is a valid HSR frame */

0 commit comments

Comments
 (0)