Skip to content

Commit 7b2ee50

Browse files
shemmingerdavem330
authored andcommitted
hv_netvsc: common detach logic
Make common function for detaching internals of device during changes to MTU and RSS. Make sure no more packets are transmitted and all packets have been received before doing device teardown. Change the wait logic to be common and use usleep_range(). Changes transmit enabling logic so that transmit queues are disabled during the period when lower device is being changed. And enabled only after sub channels are setup. This avoids issue where it could be that a packet was being sent while subchannel was not initialized. Fixes: 8195b13 ("hv_netvsc: fix deadlock on hotplug") Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 0ef58b0 commit 7b2ee50

File tree

4 files changed

+173
-143
lines changed

4 files changed

+173
-143
lines changed

drivers/net/hyperv/hyperv_net.h

-1
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,6 @@ void netvsc_channel_cb(void *context);
212212
int netvsc_poll(struct napi_struct *napi, int budget);
213213

214214
void rndis_set_subchannel(struct work_struct *w);
215-
bool rndis_filter_opened(const struct netvsc_device *nvdev);
216215
int rndis_filter_open(struct netvsc_device *nvdev);
217216
int rndis_filter_close(struct netvsc_device *nvdev);
218217
struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,

drivers/net/hyperv/netvsc.c

+11-9
Original file line numberDiff line numberDiff line change
@@ -555,8 +555,6 @@ void netvsc_device_remove(struct hv_device *device)
555555
= rtnl_dereference(net_device_ctx->nvdev);
556556
int i;
557557

558-
cancel_work_sync(&net_device->subchan_work);
559-
560558
netvsc_revoke_buf(device, net_device);
561559

562560
RCU_INIT_POINTER(net_device_ctx->nvdev, NULL);
@@ -643,14 +641,18 @@ static void netvsc_send_tx_complete(struct netvsc_device *net_device,
643641
queue_sends =
644642
atomic_dec_return(&net_device->chan_table[q_idx].queue_sends);
645643

646-
if (net_device->destroy && queue_sends == 0)
647-
wake_up(&net_device->wait_drain);
644+
if (unlikely(net_device->destroy)) {
645+
if (queue_sends == 0)
646+
wake_up(&net_device->wait_drain);
647+
} else {
648+
struct netdev_queue *txq = netdev_get_tx_queue(ndev, q_idx);
648649

649-
if (netif_tx_queue_stopped(netdev_get_tx_queue(ndev, q_idx)) &&
650-
(hv_ringbuf_avail_percent(&channel->outbound) > RING_AVAIL_PERCENT_HIWATER ||
651-
queue_sends < 1)) {
652-
netif_tx_wake_queue(netdev_get_tx_queue(ndev, q_idx));
653-
ndev_ctx->eth_stats.wake_queue++;
650+
if (netif_tx_queue_stopped(txq) &&
651+
(hv_ringbuf_avail_percent(&channel->outbound) > RING_AVAIL_PERCENT_HIWATER ||
652+
queue_sends < 1)) {
653+
netif_tx_wake_queue(txq);
654+
ndev_ctx->eth_stats.wake_queue++;
655+
}
654656
}
655657
}
656658

0 commit comments

Comments
 (0)