hv_netvsc: protect module refcount by checking net_device_ctx->vf_netdev
authorVitaly Kuznetsov <vkuznets@redhat.com>
Mon, 15 Aug 2016 15:48:42 +0000 (17:48 +0200)
committerDavid S. Miller <davem@davemloft.net>
Mon, 15 Aug 2016 20:48:07 +0000 (13:48 -0700)
We're not guaranteed to see NETDEV_REGISTER/NETDEV_UNREGISTER notifications
only once per VF but we increase/decrease module refcount unconditionally.
Check vf_netdev to make sure we don't take/release it twice. We presume
that only one VF per netvsc device may exist.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Acked-by: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/hyperv/netvsc_drv.c

index 2c90883d089e9e1ef0a404c908029dabf5cc661e..62a4e6e3c63ed1aad4d4e1c6fb67245b51450628 100644 (file)
@@ -1193,7 +1193,7 @@ static int netvsc_register_vf(struct net_device *vf_netdev)
 
        net_device_ctx = netdev_priv(ndev);
        netvsc_dev = net_device_ctx->nvdev;
-       if (netvsc_dev == NULL)
+       if (!netvsc_dev || net_device_ctx->vf_netdev)
                return NOTIFY_DONE;
 
        netdev_info(ndev, "VF registering: %s\n", vf_netdev->name);
@@ -1312,7 +1312,7 @@ static int netvsc_unregister_vf(struct net_device *vf_netdev)
 
        net_device_ctx = netdev_priv(ndev);
        netvsc_dev = net_device_ctx->nvdev;
-       if (netvsc_dev == NULL)
+       if (!netvsc_dev || !net_device_ctx->vf_netdev)
                return NOTIFY_DONE;
        netdev_info(ndev, "VF unregistering: %s\n", vf_netdev->name);
        netvsc_inject_disable(net_device_ctx);