Skip to content

Commit 6afcf0f

Browse files
committed
Revert "net: team: do not use dynamic lockdep key"
This reverts commit 39285e1. Looks like the change has unintended consequences in exposing objects before they are initialized. Let's drop this patch and try again in net-next. Reported-by: syzbot+44ae022028805f4600fc@syzkaller.appspotmail.com Fixes: 39285e1 ("net: team: do not use dynamic lockdep key") Link: https://lore.kernel.org/all/20230907103124.6adb7256@kernel.org/ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 7153a40 commit 6afcf0f

File tree

3 files changed

+60
-85
lines changed

3 files changed

+60
-85
lines changed

drivers/net/team/team.c

Lines changed: 57 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,8 +1135,8 @@ static int team_port_add(struct team *team, struct net_device *port_dev,
11351135
struct netlink_ext_ack *extack)
11361136
{
11371137
struct net_device *dev = team->dev;
1138-
char *portname = port_dev->name;
11391138
struct team_port *port;
1139+
char *portname = port_dev->name;
11401140
int err;
11411141

11421142
if (port_dev->flags & IFF_LOOPBACK) {
@@ -1203,31 +1203,18 @@ static int team_port_add(struct team *team, struct net_device *port_dev,
12031203

12041204
memcpy(port->orig.dev_addr, port_dev->dev_addr, port_dev->addr_len);
12051205

1206-
err = dev_open(port_dev, extack);
1207-
if (err) {
1208-
netdev_dbg(dev, "Device %s opening failed\n",
1209-
portname);
1210-
goto err_dev_open;
1211-
}
1212-
1213-
err = team_upper_dev_link(team, port, extack);
1206+
err = team_port_enter(team, port);
12141207
if (err) {
1215-
netdev_err(dev, "Device %s failed to set upper link\n",
1208+
netdev_err(dev, "Device %s failed to enter team mode\n",
12161209
portname);
1217-
goto err_set_upper_link;
1210+
goto err_port_enter;
12181211
}
12191212

1220-
/* lockdep subclass variable(dev->nested_level) was updated by
1221-
* team_upper_dev_link().
1222-
*/
1223-
team_unlock(team);
1224-
team_lock(team);
1225-
1226-
err = team_port_enter(team, port);
1213+
err = dev_open(port_dev, extack);
12271214
if (err) {
1228-
netdev_err(dev, "Device %s failed to enter team mode\n",
1215+
netdev_dbg(dev, "Device %s opening failed\n",
12291216
portname);
1230-
goto err_port_enter;
1217+
goto err_dev_open;
12311218
}
12321219

12331220
err = vlan_vids_add_by_dev(port_dev, dev);
@@ -1255,6 +1242,13 @@ static int team_port_add(struct team *team, struct net_device *port_dev,
12551242
goto err_handler_register;
12561243
}
12571244

1245+
err = team_upper_dev_link(team, port, extack);
1246+
if (err) {
1247+
netdev_err(dev, "Device %s failed to set upper link\n",
1248+
portname);
1249+
goto err_set_upper_link;
1250+
}
1251+
12581252
err = __team_option_inst_add_port(team, port);
12591253
if (err) {
12601254
netdev_err(dev, "Device %s failed to add per-port options\n",
@@ -1301,6 +1295,9 @@ static int team_port_add(struct team *team, struct net_device *port_dev,
13011295
__team_option_inst_del_port(team, port);
13021296

13031297
err_option_port_add:
1298+
team_upper_dev_unlink(team, port);
1299+
1300+
err_set_upper_link:
13041301
netdev_rx_handler_unregister(port_dev);
13051302

13061303
err_handler_register:
@@ -1310,16 +1307,13 @@ static int team_port_add(struct team *team, struct net_device *port_dev,
13101307
vlan_vids_del_by_dev(port_dev, dev);
13111308

13121309
err_vids_add:
1313-
team_port_leave(team, port);
1314-
1315-
err_port_enter:
1316-
team_upper_dev_unlink(team, port);
1317-
1318-
err_set_upper_link:
13191310
dev_close(port_dev);
13201311

13211312
err_dev_open:
1313+
team_port_leave(team, port);
13221314
team_port_set_orig_dev_addr(port);
1315+
1316+
err_port_enter:
13231317
dev_set_mtu(port_dev, port->orig.mtu);
13241318

13251319
err_set_mtu:
@@ -1622,7 +1616,6 @@ static int team_init(struct net_device *dev)
16221616
int err;
16231617

16241618
team->dev = dev;
1625-
mutex_init(&team->lock);
16261619
team_set_no_mode(team);
16271620
team->notifier_ctx = false;
16281621

@@ -1650,6 +1643,8 @@ static int team_init(struct net_device *dev)
16501643
goto err_options_register;
16511644
netif_carrier_off(dev);
16521645

1646+
lockdep_register_key(&team->team_lock_key);
1647+
__mutex_init(&team->lock, "team->team_lock_key", &team->team_lock_key);
16531648
netdev_lockdep_set_classes(dev);
16541649

16551650
return 0;
@@ -1670,7 +1665,7 @@ static void team_uninit(struct net_device *dev)
16701665
struct team_port *port;
16711666
struct team_port *tmp;
16721667

1673-
team_lock(team);
1668+
mutex_lock(&team->lock);
16741669
list_for_each_entry_safe(port, tmp, &team->port_list, list)
16751670
team_port_del(team, port->dev);
16761671

@@ -1679,8 +1674,9 @@ static void team_uninit(struct net_device *dev)
16791674
team_mcast_rejoin_fini(team);
16801675
team_notify_peers_fini(team);
16811676
team_queue_override_fini(team);
1682-
team_unlock(team);
1677+
mutex_unlock(&team->lock);
16831678
netdev_change_features(dev);
1679+
lockdep_unregister_key(&team->team_lock_key);
16841680
}
16851681

16861682
static void team_destructor(struct net_device *dev)
@@ -1794,18 +1790,18 @@ static void team_set_rx_mode(struct net_device *dev)
17941790

17951791
static int team_set_mac_address(struct net_device *dev, void *p)
17961792
{
1797-
struct team *team = netdev_priv(dev);
17981793
struct sockaddr *addr = p;
1794+
struct team *team = netdev_priv(dev);
17991795
struct team_port *port;
18001796

18011797
if (dev->type == ARPHRD_ETHER && !is_valid_ether_addr(addr->sa_data))
18021798
return -EADDRNOTAVAIL;
18031799
dev_addr_set(dev, addr->sa_data);
1804-
team_lock(team);
1800+
mutex_lock(&team->lock);
18051801
list_for_each_entry(port, &team->port_list, list)
18061802
if (team->ops.port_change_dev_addr)
18071803
team->ops.port_change_dev_addr(team, port);
1808-
team_unlock(team);
1804+
mutex_unlock(&team->lock);
18091805
return 0;
18101806
}
18111807

@@ -1819,7 +1815,7 @@ static int team_change_mtu(struct net_device *dev, int new_mtu)
18191815
* Alhough this is reader, it's guarded by team lock. It's not possible
18201816
* to traverse list in reverse under rcu_read_lock
18211817
*/
1822-
team_lock(team);
1818+
mutex_lock(&team->lock);
18231819
team->port_mtu_change_allowed = true;
18241820
list_for_each_entry(port, &team->port_list, list) {
18251821
err = dev_set_mtu(port->dev, new_mtu);
@@ -1830,7 +1826,7 @@ static int team_change_mtu(struct net_device *dev, int new_mtu)
18301826
}
18311827
}
18321828
team->port_mtu_change_allowed = false;
1833-
team_unlock(team);
1829+
mutex_unlock(&team->lock);
18341830

18351831
dev->mtu = new_mtu;
18361832

@@ -1840,7 +1836,7 @@ static int team_change_mtu(struct net_device *dev, int new_mtu)
18401836
list_for_each_entry_continue_reverse(port, &team->port_list, list)
18411837
dev_set_mtu(port->dev, dev->mtu);
18421838
team->port_mtu_change_allowed = false;
1843-
team_unlock(team);
1839+
mutex_unlock(&team->lock);
18441840

18451841
return err;
18461842
}
@@ -1894,20 +1890,20 @@ static int team_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid)
18941890
* Alhough this is reader, it's guarded by team lock. It's not possible
18951891
* to traverse list in reverse under rcu_read_lock
18961892
*/
1897-
team_lock(team);
1893+
mutex_lock(&team->lock);
18981894
list_for_each_entry(port, &team->port_list, list) {
18991895
err = vlan_vid_add(port->dev, proto, vid);
19001896
if (err)
19011897
goto unwind;
19021898
}
1903-
team_unlock(team);
1899+
mutex_unlock(&team->lock);
19041900

19051901
return 0;
19061902

19071903
unwind:
19081904
list_for_each_entry_continue_reverse(port, &team->port_list, list)
19091905
vlan_vid_del(port->dev, proto, vid);
1910-
team_unlock(team);
1906+
mutex_unlock(&team->lock);
19111907

19121908
return err;
19131909
}
@@ -1917,10 +1913,10 @@ static int team_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid)
19171913
struct team *team = netdev_priv(dev);
19181914
struct team_port *port;
19191915

1920-
team_lock(team);
1916+
mutex_lock(&team->lock);
19211917
list_for_each_entry(port, &team->port_list, list)
19221918
vlan_vid_del(port->dev, proto, vid);
1923-
team_unlock(team);
1919+
mutex_unlock(&team->lock);
19241920

19251921
return 0;
19261922
}
@@ -1942,9 +1938,9 @@ static void team_netpoll_cleanup(struct net_device *dev)
19421938
{
19431939
struct team *team = netdev_priv(dev);
19441940

1945-
team_lock(team);
1941+
mutex_lock(&team->lock);
19461942
__team_netpoll_cleanup(team);
1947-
team_unlock(team);
1943+
mutex_unlock(&team->lock);
19481944
}
19491945

19501946
static int team_netpoll_setup(struct net_device *dev,
@@ -1954,15 +1950,15 @@ static int team_netpoll_setup(struct net_device *dev,
19541950
struct team_port *port;
19551951
int err = 0;
19561952

1957-
team_lock(team);
1953+
mutex_lock(&team->lock);
19581954
list_for_each_entry(port, &team->port_list, list) {
19591955
err = __team_port_enable_netpoll(port);
19601956
if (err) {
19611957
__team_netpoll_cleanup(team);
19621958
break;
19631959
}
19641960
}
1965-
team_unlock(team);
1961+
mutex_unlock(&team->lock);
19661962
return err;
19671963
}
19681964
#endif
@@ -1973,9 +1969,9 @@ static int team_add_slave(struct net_device *dev, struct net_device *port_dev,
19731969
struct team *team = netdev_priv(dev);
19741970
int err;
19751971

1976-
team_lock(team);
1972+
mutex_lock(&team->lock);
19771973
err = team_port_add(team, port_dev, extack);
1978-
team_unlock(team);
1974+
mutex_unlock(&team->lock);
19791975

19801976
if (!err)
19811977
netdev_change_features(dev);
@@ -1988,12 +1984,19 @@ static int team_del_slave(struct net_device *dev, struct net_device *port_dev)
19881984
struct team *team = netdev_priv(dev);
19891985
int err;
19901986

1991-
team_lock(team);
1987+
mutex_lock(&team->lock);
19921988
err = team_port_del(team, port_dev);
1993-
team_unlock(team);
1989+
mutex_unlock(&team->lock);
19941990

1995-
if (!err)
1996-
netdev_change_features(dev);
1991+
if (err)
1992+
return err;
1993+
1994+
if (netif_is_team_master(port_dev)) {
1995+
lockdep_unregister_key(&team->team_lock_key);
1996+
lockdep_register_key(&team->team_lock_key);
1997+
lockdep_set_class(&team->lock, &team->team_lock_key);
1998+
}
1999+
netdev_change_features(dev);
19972000

19982001
return err;
19992002
}
@@ -2313,13 +2316,13 @@ static struct team *team_nl_team_get(struct genl_info *info)
23132316
}
23142317

23152318
team = netdev_priv(dev);
2316-
__team_lock(team);
2319+
mutex_lock(&team->lock);
23172320
return team;
23182321
}
23192322

23202323
static void team_nl_team_put(struct team *team)
23212324
{
2322-
team_unlock(team);
2325+
mutex_unlock(&team->lock);
23232326
dev_put(team->dev);
23242327
}
23252328

@@ -2981,9 +2984,9 @@ static void team_port_change_check(struct team_port *port, bool linkup)
29812984
{
29822985
struct team *team = port->team;
29832986

2984-
team_lock(team);
2987+
mutex_lock(&team->lock);
29852988
__team_port_change_check(port, linkup);
2986-
team_unlock(team);
2989+
mutex_unlock(&team->lock);
29872990
}
29882991

29892992

drivers/net/team/team_mode_loadbalance.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ static void lb_stats_refresh(struct work_struct *work)
478478
team = lb_priv_ex->team;
479479
lb_priv = get_lb_priv(team);
480480

481-
if (!team_trylock(team)) {
481+
if (!mutex_trylock(&team->lock)) {
482482
schedule_delayed_work(&lb_priv_ex->stats.refresh_dw, 0);
483483
return;
484484
}
@@ -515,7 +515,7 @@ static void lb_stats_refresh(struct work_struct *work)
515515
schedule_delayed_work(&lb_priv_ex->stats.refresh_dw,
516516
(lb_priv_ex->stats.refresh_interval * HZ) / 10);
517517

518-
team_unlock(team);
518+
mutex_unlock(&team->lock);
519519
}
520520

521521
static void lb_stats_refresh_interval_get(struct team *team,

include/linux/if_team.h

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -221,38 +221,10 @@ struct team {
221221
atomic_t count_pending;
222222
struct delayed_work dw;
223223
} mcast_rejoin;
224+
struct lock_class_key team_lock_key;
224225
long mode_priv[TEAM_MODE_PRIV_LONGS];
225226
};
226227

227-
static inline void __team_lock(struct team *team)
228-
{
229-
mutex_lock(&team->lock);
230-
}
231-
232-
static inline int team_trylock(struct team *team)
233-
{
234-
return mutex_trylock(&team->lock);
235-
}
236-
237-
#ifdef CONFIG_LOCKDEP
238-
static inline void team_lock(struct team *team)
239-
{
240-
ASSERT_RTNL();
241-
mutex_lock_nested(&team->lock, team->dev->nested_level);
242-
}
243-
244-
#else
245-
static inline void team_lock(struct team *team)
246-
{
247-
__team_lock(team);
248-
}
249-
#endif
250-
251-
static inline void team_unlock(struct team *team)
252-
{
253-
mutex_unlock(&team->lock);
254-
}
255-
256228
static inline int team_dev_queue_xmit(struct team *team, struct team_port *port,
257229
struct sk_buff *skb)
258230
{

0 commit comments

Comments
 (0)