Skip to content

Commit c9ac729

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 a2accc0 commit c9ac729

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
@@ -59,7 +59,7 @@ static bool hsr_check_carrier(struct hsr_port *master)
5959

6060
ASSERT_RTNL();
6161

62-
hsr_for_each_port(master->hsr, port) {
62+
hsr_for_each_port_rtnl(master->hsr, port) {
6363
if (port->type != HSR_PT_MASTER && is_slave_up(port->dev)) {
6464
netif_carrier_on(master->dev);
6565
return true;
@@ -109,7 +109,7 @@ int hsr_get_max_mtu(struct hsr_priv *hsr)
109109
struct hsr_port *port;
110110

111111
mtu_max = ETH_DATA_LEN;
112-
hsr_for_each_port(hsr, port)
112+
hsr_for_each_port_rtnl(hsr, port)
113113
if (port->type != HSR_PT_MASTER)
114114
mtu_max = min(port->dev->mtu, mtu_max);
115115

@@ -144,7 +144,7 @@ static int hsr_dev_open(struct net_device *dev)
144144
hsr = netdev_priv(dev);
145145
designation = '\0';
146146

147-
hsr_for_each_port(hsr, port) {
147+
hsr_for_each_port_rtnl(hsr, port) {
148148
if (port->type == HSR_PT_MASTER)
149149
continue;
150150
switch (port->type) {
@@ -174,7 +174,7 @@ static int hsr_dev_close(struct net_device *dev)
174174
struct hsr_priv *hsr;
175175

176176
hsr = netdev_priv(dev);
177-
hsr_for_each_port(hsr, port) {
177+
hsr_for_each_port_rtnl(hsr, port) {
178178
if (port->type == HSR_PT_MASTER)
179179
continue;
180180
switch (port->type) {
@@ -207,7 +207,7 @@ static netdev_features_t hsr_features_recompute(struct hsr_priv *hsr,
207207
* may become enabled.
208208
*/
209209
features &= ~NETIF_F_ONE_FOR_ALL;
210-
hsr_for_each_port(hsr, port)
210+
hsr_for_each_port_rtnl(hsr, port)
211211
features = netdev_increment_features(features,
212212
port->dev->features,
213213
mask);
@@ -425,7 +425,7 @@ static void hsr_set_rx_mode(struct net_device *dev)
425425

426426
hsr = netdev_priv(dev);
427427

428-
hsr_for_each_port(hsr, port) {
428+
hsr_for_each_port_rtnl(hsr, port) {
429429
if (port->type == HSR_PT_MASTER)
430430
continue;
431431
switch (port->type) {
@@ -447,7 +447,7 @@ static void hsr_change_rx_flags(struct net_device *dev, int change)
447447

448448
hsr = netdev_priv(dev);
449449

450-
hsr_for_each_port(hsr, port) {
450+
hsr_for_each_port_rtnl(hsr, port) {
451451
if (port->type == HSR_PT_MASTER)
452452
continue;
453453
switch (port->type) {
@@ -475,7 +475,7 @@ static int hsr_ndo_vlan_rx_add_vid(struct net_device *dev,
475475

476476
hsr = netdev_priv(dev);
477477

478-
hsr_for_each_port(hsr, port) {
478+
hsr_for_each_port_rtnl(hsr, port) {
479479
if (port->type == HSR_PT_MASTER ||
480480
port->type == HSR_PT_INTERLINK)
481481
continue;
@@ -521,7 +521,7 @@ static int hsr_ndo_vlan_rx_kill_vid(struct net_device *dev,
521521

522522
hsr = netdev_priv(dev);
523523

524-
hsr_for_each_port(hsr, port) {
524+
hsr_for_each_port_rtnl(hsr, port) {
525525
switch (port->type) {
526526
case HSR_PT_SLAVE_A:
527527
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
@@ -215,6 +215,9 @@ struct hsr_priv {
215215
#define hsr_for_each_port(hsr, port) \
216216
list_for_each_entry_rcu((port), &(hsr)->ports, port_list)
217217

218+
#define hsr_for_each_port_rtnl(hsr, port) \
219+
list_for_each_entry_rcu((port), &(hsr)->ports, port_list, lockdep_rtnl_is_held())
220+
218221
struct hsr_port *hsr_port_get_hsr(struct hsr_priv *hsr, enum hsr_port_type pt);
219222

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

0 commit comments

Comments
 (0)