From: Stephen Hemminger <stephen@networkplumber.org>
To: davem@davemloft.net, kys@microsoft.com
Cc: netdev@vger.kernel.org, Stephen Hemminger <sthemmin@microsoft.com>
Subject: [PATCH 14/18] netvsc: eliminate per-device outstanding send counter
Date: Tue, 24 Jan 2017 13:06:11 -0800 [thread overview]
Message-ID: <20170124210615.18628-15-sthemmin@microsoft.com> (raw)
In-Reply-To: <20170124210615.18628-1-sthemmin@microsoft.com>
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>
---
drivers/net/hyperv/hyperv_net.h | 1 -
drivers/net/hyperv/netvsc.c | 44 ++++++++++++++-------------------------
drivers/net/hyperv/rndis_filter.c | 21 ++++++++++++++++---
3 files changed, 34 insertions(+), 32 deletions(-)
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 757205c9cb93..fec365241f37 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -729,7 +729,6 @@ struct netvsc_channel {
struct netvsc_device {
u32 nvsp_version;
- atomic_t num_outstanding_sends;
wait_queue_head_t wait_drain;
bool destroy;
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 359e7ef7040b..bd055146f098 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -90,29 +90,23 @@ static void free_netvsc_device(struct netvsc_device *nvdev)
kfree(nvdev);
}
-static struct netvsc_device *get_outbound_net_device(struct hv_device *device)
-{
- struct netvsc_device *net_device = hv_device_to_netvsc_device(device);
- if (net_device && net_device->destroy)
- net_device = NULL;
+static inline bool netvsc_channel_idle(const struct netvsc_device *net_device,
+ u16 q_idx)
+{
+ const struct netvsc_channel *nvchan = &net_device->chan_table[q_idx];
- return net_device;
+ return atomic_read(&net_device->num_outstanding_recvs) == 0 &&
+ atomic_read(&nvchan->queue_sends) == 0;
}
-static struct netvsc_device *get_inbound_net_device(struct hv_device *device)
+static struct netvsc_device *get_outbound_net_device(struct hv_device *device)
{
struct netvsc_device *net_device = hv_device_to_netvsc_device(device);
- if (!net_device)
- goto get_in_err;
-
- if (net_device->destroy &&
- atomic_read(&net_device->num_outstanding_sends) == 0 &&
- atomic_read(&net_device->num_outstanding_recvs) == 0)
+ if (net_device && net_device->destroy)
net_device = NULL;
-get_in_err:
return net_device;
}
@@ -612,7 +606,6 @@ static void netvsc_send_tx_complete(struct netvsc_device *net_device,
struct net_device *ndev = hv_get_drvdata(device);
struct net_device_context *net_device_ctx = netdev_priv(ndev);
struct vmbus_channel *channel = device->channel;
- int num_outstanding_sends;
u16 q_idx = 0;
int queue_sends;
@@ -630,13 +623,10 @@ static void netvsc_send_tx_complete(struct netvsc_device *net_device,
dev_consume_skb_any(skb);
}
- num_outstanding_sends =
- atomic_dec_return(&net_device->num_outstanding_sends);
-
queue_sends =
atomic_dec_return(&net_device->chan_table[q_idx].queue_sends);
- if (net_device->destroy && num_outstanding_sends == 0)
+ if (net_device->destroy && queue_sends == 0)
wake_up(&net_device->wait_drain);
if (netif_tx_queue_stopped(netdev_get_tx_queue(ndev, q_idx)) &&
@@ -823,15 +813,10 @@ static inline int netvsc_send_pkt(
}
if (ret == 0) {
- atomic_inc(&net_device->num_outstanding_sends);
atomic_inc_return(&nvchan->queue_sends);
- if (ring_avail < RING_AVAIL_PERCENT_LOWATER) {
+ if (ring_avail < RING_AVAIL_PERCENT_LOWATER)
netif_tx_stop_queue(txq);
-
- if (atomic_read(&nvchan->queue_sends) < 1)
- netif_tx_wake_queue(txq);
- }
} else if (ret == -EAGAIN) {
netif_tx_stop_queue(txq);
if (atomic_read(&nvchan->queue_sends) < 1) {
@@ -1259,11 +1244,14 @@ void netvsc_channel_cb(void *context)
else
device = channel->device_obj;
- net_device = get_inbound_net_device(device);
- if (!net_device)
+ ndev = hv_get_drvdata(device);
+ if (unlikely(!ndev))
return;
- ndev = hv_get_drvdata(device);
+ net_device = net_device_to_netvsc_device(ndev);
+ if (unlikely(net_device->destroy) &&
+ netvsc_channel_idle(net_device, q_idx))
+ return;
while ((desc = get_next_pkt_raw(channel)) != NULL) {
netvsc_process_raw_pkt(device, channel, net_device,
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 @@ static int rndis_filter_init_device(struct rndis_device *dev)
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 @@ static void rndis_filter_halt_device(struct rndis_device *dev)
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);
--
2.11.0
next prev parent reply other threads:[~2017-01-24 21:06 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-24 21:05 [PATCH net-next 00/18] netvsc driver enhancements for net-next Stephen Hemminger
2017-01-24 21:05 ` [PATCH 01/18] netvsc: remove no longer needed receive staging buffers Stephen Hemminger
2017-01-24 21:05 ` [PATCH 02/18] netvsc: negotiate checksum and segmentation parameters Stephen Hemminger
2017-01-24 21:06 ` [PATCH 03/18] netvsc: report number of rx queues in ethtool Stephen Hemminger
2017-01-24 21:06 ` [PATCH 04/18] netvsc: report rss field values Stephen Hemminger
2017-01-24 21:06 ` [PATCH 05/18] netvsc: add ethtool ops to get/set RSS key Stephen Hemminger
2017-01-24 21:06 ` [PATCH 06/18] netvsc: allow more flexible setting of number of channels Stephen Hemminger
2017-01-24 21:06 ` [PATCH 07/18] netvsc: allow get/set of RSS indirection table Stephen Hemminger
2017-01-24 21:06 ` [PATCH 08/18] netvsc: enhance transmit select_queue Stephen Hemminger
2017-01-24 21:06 ` [PATCH 09/18] netvsc: remove unused variables Stephen Hemminger
2017-01-24 21:06 ` [PATCH 10/18] netvsc: group all per-channel state together Stephen Hemminger
2017-01-24 21:06 ` [PATCH 11/18] netvsc: optimize receive path Stephen Hemminger
2017-01-24 21:06 ` [PATCH 12/18] netvsc: don't pass void * to internal device_add Stephen Hemminger
2017-01-24 21:06 ` [PATCH 13/18] netvsc: simplify rndis_filter_remove Stephen Hemminger
2017-01-24 21:06 ` Stephen Hemminger [this message]
2017-01-24 21:06 ` [PATCH 15/18] netvsc: account for packets/bytes transmitted after completion Stephen Hemminger
2017-01-24 21:06 ` [PATCH 16/18] netvsc: report per-channel stats in ethtool statistics Stephen Hemminger
2017-01-24 21:06 ` [PATCH 17/18] netvsc: simplify get next send section Stephen Hemminger
2017-01-24 21:06 ` [PATCH 18/18] netvsc: call netif_receive_skb Stephen Hemminger
2017-01-24 22:39 ` Eric Dumazet
2017-01-24 23:00 ` Stephen Hemminger
2017-01-24 23:07 ` Eric Dumazet
2017-01-24 21:30 ` [PATCH net-next 00/18] netvsc driver enhancements for net-next David Miller
2017-01-24 22:00 ` Stephen Hemminger
2017-01-24 22:50 ` Stephen Hemminger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170124210615.18628-15-sthemmin@microsoft.com \
--to=stephen@networkplumber.org \
--cc=davem@davemloft.net \
--cc=kys@microsoft.com \
--cc=netdev@vger.kernel.org \
--cc=sthemmin@microsoft.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).