[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20170426235830.14801-1-sthemmin@microsoft.com>
Date: Wed, 26 Apr 2017 16:58:30 -0700
From: Stephen Hemminger <stephen@...workplumber.org>
To: davem@...emloft.net
Cc: netdev@...r.kernel.org, Stephen Hemminger <sthemmin@...rosoft.com>
Subject: [PATCH] netvsc: make sure napi enabled before vmbus_open
This fixes a race where vmbus callback for new packet arriving
could occur before NAPI is initialized. Happens more on WS2008
which takes longer to setup channel.
Signed-off-by: Stephen Hemminger <sthemmin@...rosoft.com>
---
drivers/net/hyperv/netvsc.c | 8 +++++---
drivers/net/hyperv/rndis_filter.c | 4 +++-
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index f99651c03e0a..8150febb86d6 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -1323,6 +1323,10 @@ int netvsc_device_add(struct hv_device *device,
nvchan->channel = device->channel;
}
+ /* Enable NAPI handler before init callbacks */
+ netif_napi_add(ndev, &net_device->chan_table[0].napi,
+ netvsc_poll, NAPI_POLL_WEIGHT);
+
/* Open the channel */
ret = vmbus_open(device->channel, ring_size * PAGE_SIZE,
ring_size * PAGE_SIZE, NULL, 0,
@@ -1330,6 +1334,7 @@ int netvsc_device_add(struct hv_device *device,
net_device->chan_table);
if (ret != 0) {
+ netif_napi_del(&net_device->chan_table[0].napi);
netdev_err(ndev, "unable to open channel: %d\n", ret);
goto cleanup;
}
@@ -1337,9 +1342,6 @@ int netvsc_device_add(struct hv_device *device,
/* Channel is opened */
netdev_dbg(ndev, "hv_netvsc channel opened successfully\n");
- /* Enable NAPI handler for init callbacks */
- netif_napi_add(ndev, &net_device->chan_table[0].napi,
- netvsc_poll, NAPI_POLL_WEIGHT);
napi_enable(&net_device->chan_table[0].napi);
/* Writing nvdev pointer unlocks netvsc_send(), make sure chn_table is
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index ab92c3c95951..a9e9fb4bb9c5 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -1017,8 +1017,10 @@ static void netvsc_sc_open(struct vmbus_channel *new_sc)
netvsc_channel_cb, nvchan);
if (ret == 0)
napi_enable(&nvchan->napi);
- else
+ else {
+ netif_napi_del(&nvchan->napi);
netdev_err(ndev, "sub channel open failed (%d)\n", ret);
+ }
if (refcount_dec_and_test(&nvscdev->sc_offered))
complete(&nvscdev->channel_init_wait);
--
2.11.0
Powered by blists - more mailing lists