team: call netdev_change_features out of team lock
Commit f6988cb63a
("team: don't call netdev_change_features under
team->lock") fixed the issue calling netdev_change_features under
team->lock for team_compute_features.
But there are still two places where it calls netdev_change_features
under team->lock, team_port_add and team_port_del. It may cause a
dead lock when the slave port with LRO enabled is added.
This patch is to fix this dead lock by moving netdev_change_features
out of team_port_add and team_port_del, and call it after unlocking
the team lock.
Reported-by: Patrick Talbert <ptalbert@redhat.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
34b2789f1d
commit
16cf72bb08
|
@ -990,7 +990,7 @@ static void team_port_disable(struct team *team,
|
|||
#define TEAM_ENC_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \
|
||||
NETIF_F_RXCSUM | NETIF_F_ALL_TSO)
|
||||
|
||||
static void ___team_compute_features(struct team *team)
|
||||
static void __team_compute_features(struct team *team)
|
||||
{
|
||||
struct team_port *port;
|
||||
u32 vlan_features = TEAM_VLAN_FEATURES & NETIF_F_ALL_FOR_ALL;
|
||||
|
@ -1023,16 +1023,10 @@ static void ___team_compute_features(struct team *team)
|
|||
team->dev->priv_flags |= IFF_XMIT_DST_RELEASE;
|
||||
}
|
||||
|
||||
static void __team_compute_features(struct team *team)
|
||||
{
|
||||
___team_compute_features(team);
|
||||
netdev_change_features(team->dev);
|
||||
}
|
||||
|
||||
static void team_compute_features(struct team *team)
|
||||
{
|
||||
mutex_lock(&team->lock);
|
||||
___team_compute_features(team);
|
||||
__team_compute_features(team);
|
||||
mutex_unlock(&team->lock);
|
||||
netdev_change_features(team->dev);
|
||||
}
|
||||
|
@ -1641,6 +1635,7 @@ static void team_uninit(struct net_device *dev)
|
|||
team_notify_peers_fini(team);
|
||||
team_queue_override_fini(team);
|
||||
mutex_unlock(&team->lock);
|
||||
netdev_change_features(dev);
|
||||
}
|
||||
|
||||
static void team_destructor(struct net_device *dev)
|
||||
|
@ -1928,6 +1923,10 @@ static int team_add_slave(struct net_device *dev, struct net_device *port_dev)
|
|||
mutex_lock(&team->lock);
|
||||
err = team_port_add(team, port_dev);
|
||||
mutex_unlock(&team->lock);
|
||||
|
||||
if (!err)
|
||||
netdev_change_features(dev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -1939,6 +1938,10 @@ static int team_del_slave(struct net_device *dev, struct net_device *port_dev)
|
|||
mutex_lock(&team->lock);
|
||||
err = team_port_del(team, port_dev);
|
||||
mutex_unlock(&team->lock);
|
||||
|
||||
if (!err)
|
||||
netdev_change_features(dev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue