hv_netvsc: Fix the order of num_sc_offered decrement
authorHaiyang Zhang <haiyangz@microsoft.com>
Wed, 23 Mar 2016 21:54:48 +0000 (14:54 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 24 Mar 2016 01:51:08 +0000 (21:51 -0400)
Reorder the code in netvsc_sc_open(), so num_sc_offered is only decremented
after vmbus_open() is called. This avoid pontential race of removing device
before all channels are setup.

Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/hyperv/rndis_filter.c

index d5a54da..c4e1e04 100644 (file)
@@ -986,12 +986,6 @@ static void netvsc_sc_open(struct vmbus_channel *new_sc)
 
        nvscdev = hv_get_drvdata(new_sc->primary_channel->device_obj);
 
-       spin_lock_irqsave(&nvscdev->sc_lock, flags);
-       nvscdev->num_sc_offered--;
-       spin_unlock_irqrestore(&nvscdev->sc_lock, flags);
-       if (nvscdev->num_sc_offered == 0)
-               complete(&nvscdev->channel_init_wait);
-
        if (chn_index >= nvscdev->num_chn)
                return;
 
@@ -1004,6 +998,12 @@ static void netvsc_sc_open(struct vmbus_channel *new_sc)
 
        if (ret == 0)
                nvscdev->chn_table[chn_index] = new_sc;
+
+       spin_lock_irqsave(&nvscdev->sc_lock, flags);
+       nvscdev->num_sc_offered--;
+       spin_unlock_irqrestore(&nvscdev->sc_lock, flags);
+       if (nvscdev->num_sc_offered == 0)
+               complete(&nvscdev->channel_init_wait);
 }
 
 int rndis_filter_device_add(struct hv_device *dev,