summaryrefslogtreecommitdiffstats
path: root/drivers/net/hyperv/rndis_filter.c
diff options
context:
space:
mode:
authorstephen hemminger2017-01-24 22:06:11 +0100
committerDavid S. Miller2017-01-24 22:29:01 +0100
commit46b4f7f5d1f7410de48128540ef2d1aab913a619 (patch)
tree56117dc8ca944861b483f963386192027797918f /drivers/net/hyperv/rndis_filter.c
parentnetvsc: simplify rndis_filter_remove (diff)
downloadkernel-qcow2-linux-46b4f7f5d1f7410de48128540ef2d1aab913a619.tar.gz
kernel-qcow2-linux-46b4f7f5d1f7410de48128540ef2d1aab913a619.tar.xz
kernel-qcow2-linux-46b4f7f5d1f7410de48128540ef2d1aab913a619.zip
netvsc: eliminate per-device outstanding send counter
Since now keep track of per-queue outstanding sends, we can avoid one atomic update by removing no longer needed per-device atomic. Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/hyperv/rndis_filter.c')
-rw-r--r--drivers/net/hyperv/rndis_filter.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 70b099a731a9..19356f56b7b1 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -903,6 +903,23 @@ cleanup:
return ret;
}
+static bool netvsc_device_idle(const struct netvsc_device *nvdev)
+{
+ int i;
+
+ if (atomic_read(&nvdev->num_outstanding_recvs) > 0)
+ return false;
+
+ for (i = 0; i < nvdev->num_chn; i++) {
+ const struct netvsc_channel *nvchan = &nvdev->chan_table[i];
+
+ if (atomic_read(&nvchan->queue_sends) > 0)
+ return false;
+ }
+
+ return true;
+}
+
static void rndis_filter_halt_device(struct rndis_device *dev)
{
struct rndis_request *request;
@@ -933,9 +950,7 @@ cleanup:
spin_unlock_irqrestore(&hdev->channel->inbound_lock, flags);
/* Wait for all send completions */
- wait_event(nvdev->wait_drain,
- atomic_read(&nvdev->num_outstanding_sends) == 0 &&
- atomic_read(&nvdev->num_outstanding_recvs) == 0);
+ wait_event(nvdev->wait_drain, netvsc_device_idle(nvdev));
if (request)
put_rndis_request(dev, request);