From 7a7a743123f91d6a6f7346c09a657075b47d2ee5 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Mon, 4 Jun 2012 06:42:38 +0000 Subject: [PATCH] --- yaml --- r: 310710 b: refs/heads/master c: dc5cd894cace7bda4a743487a9f87d59a3f0a095 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/net/hyperv/hyperv_net.h | 1 + trunk/drivers/net/hyperv/netvsc.c | 12 ++++++------ 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/[refs] b/[refs] index fdfde0ddc10e..0d0aa060ddd0 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 9ec0db71af04f4560e27a3c2f5a0411ba3155198 +refs/heads/master: dc5cd894cace7bda4a743487a9f87d59a3f0a095 diff --git a/trunk/drivers/net/hyperv/hyperv_net.h b/trunk/drivers/net/hyperv/hyperv_net.h index 4ffcd57b011b..2857ab078aac 100644 --- a/trunk/drivers/net/hyperv/hyperv_net.h +++ b/trunk/drivers/net/hyperv/hyperv_net.h @@ -478,6 +478,7 @@ struct netvsc_device { u32 nvsp_version; atomic_t num_outstanding_sends; + wait_queue_head_t wait_drain; bool start_remove; bool destroy; /* diff --git a/trunk/drivers/net/hyperv/netvsc.c b/trunk/drivers/net/hyperv/netvsc.c index 8b919471472f..0c569831db5a 100644 --- a/trunk/drivers/net/hyperv/netvsc.c +++ b/trunk/drivers/net/hyperv/netvsc.c @@ -42,6 +42,7 @@ static struct netvsc_device *alloc_net_device(struct hv_device *device) if (!net_device) return NULL; + init_waitqueue_head(&net_device->wait_drain); net_device->start_remove = false; net_device->destroy = false; net_device->dev = device; @@ -387,12 +388,8 @@ int netvsc_device_remove(struct hv_device *device) spin_unlock_irqrestore(&device->channel->inbound_lock, flags); /* Wait for all send completions */ - while (atomic_read(&net_device->num_outstanding_sends)) { - dev_info(&device->device, - "waiting for %d requests to complete...\n", - atomic_read(&net_device->num_outstanding_sends)); - udelay(100); - } + wait_event(net_device->wait_drain, + atomic_read(&net_device->num_outstanding_sends) == 0); netvsc_disconnect_vsp(net_device); @@ -486,6 +483,9 @@ static void netvsc_send_completion(struct hv_device *device, num_outstanding_sends = atomic_dec_return(&net_device->num_outstanding_sends); + if (net_device->destroy && num_outstanding_sends == 0) + wake_up(&net_device->wait_drain); + if (netif_queue_stopped(ndev) && !net_device->start_remove && (hv_ringbuf_avail_percent(&device->channel->outbound) > RING_AVAIL_PERCENT_HIWATER ||