Skip to content

Commit 6da7225

Browse files
vittyvkdavem330
authored andcommitted
hv_netvsc: synchronize netvsc_change_mtu()/netvsc_set_channels() with netvsc_remove()
When netvsc device is removed during mtu change or channels setup we get into troubles as both paths are trying to remove the device. Synchronize them with start_remove flag and rtnl lock. Signed-off-by: Vitaly Kuznetsov <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 0a1275c commit 6da7225

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

drivers/net/hyperv/netvsc_drv.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -759,7 +759,7 @@ static int netvsc_set_channels(struct net_device *net,
759759
int ret = 0;
760760
bool recovering = false;
761761

762-
if (!nvdev || nvdev->destroy)
762+
if (net_device_ctx->start_remove || !nvdev || nvdev->destroy)
763763
return -ENODEV;
764764

765765
num_chn = nvdev->num_chn;
@@ -907,7 +907,7 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
907907
u32 num_chn;
908908
int ret = 0;
909909

910-
if (nvdev == NULL || nvdev->destroy)
910+
if (ndevctx->start_remove || !nvdev || nvdev->destroy)
911911
return -ENODEV;
912912

913913
if (nvdev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
@@ -1445,7 +1445,12 @@ static int netvsc_remove(struct hv_device *dev)
14451445
ndev_ctx = netdev_priv(net);
14461446
net_device = ndev_ctx->nvdev;
14471447

1448+
/* Avoid racing with netvsc_change_mtu()/netvsc_set_channels()
1449+
* removing the device.
1450+
*/
1451+
rtnl_lock();
14481452
ndev_ctx->start_remove = true;
1453+
rtnl_unlock();
14491454

14501455
cancel_delayed_work_sync(&ndev_ctx->dwork);
14511456
cancel_work_sync(&ndev_ctx->work);

0 commit comments

Comments
 (0)