Thread (6 messages) 6 messages, 4 authors, 2019-03-28

Re: [PATCH hyperv-fixes] hv_netvsc: Fix unwanted wakeup after tx_disable

From: Stephen Hemminger <stephen@networkplumber.org>
Date: 2019-03-28 19:42:13
Also in: linux-hyperv, lkml

On Thu, 28 Mar 2019 19:00:18 +0000
Haiyang Zhang [off-list ref] wrote:
quoted
-----Original Message-----
From: Stephen Hemminger <stephen@networkplumber.org>
Sent: Thursday, March 28, 2019 2:38 PM
To: Haiyang Zhang <redacted>
Cc: sashal@kernel.org; linux-hyperv@vger.kernel.org; Haiyang Zhang
[off-list ref]; KY Srinivasan [off-list ref]; Stephen
Hemminger [off-list ref]; olaf@aepfle.de; vkuznets
[off-list ref]; davem@davemloft.net; netdev@vger.kernel.org;
linux-kernel@vger.kernel.org
Subject: Re: [PATCH hyperv-fixes] hv_netvsc: Fix unwanted wakeup after
tx_disable

On Thu, 28 Mar 2019 17:48:45 +0000
Haiyang Zhang [off-list ref] wrote:
  
quoted
+static inline void netvsc_tx_enable(struct netvsc_device *nvscdev,
+				    struct net_device *ndev)
+{
+	nvscdev->tx_disable = false;
+	mb(); /* ensure queue wake up mechanism is on */
+
+	netif_tx_wake_all_queues(ndev);
+}  
You don't need a full mb(). virt_wmb() should be sufficient.  
I will make this change. 
quoted
Could I suggest an alternative approach.
You don't need to introduce a local tx_disable flag, the only place where a
wakeup could cause problems is after a send_completion was processed
during detach state.

Instead, just avoid wakeup in that place.  
In netvsc_detach(), after netif_tx_disable(), we call  netvsc_wait_until_empty(nvdev);
TX patch should not be waken up again while waiting for in/out ring to becomes empty.

In my tests before this patch, there are wakeup happens before netif_device_detach(), 
so netif_device_present(ndev) is still true at that time.

In other places, like netvsc_close(), link_change(), we also don't want wakeup after tx_disable.

Thanks.
- Haiyang
quoted
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -720,6 +720,7 @@ static void netvsc_send_tx_complete(struct
net_device *ndev,
                struct netdev_queue *txq = netdev_get_tx_queue(ndev, q_idx);

                if (netif_tx_queue_stopped(txq) &&
+                   netif_device_present(ndev) &&
                    (hv_get_avail_to_write_percent(&channel->outbound) >
                     RING_AVAIL_PERCENT_HIWATER || queue_sends < 1)) {
                        netif_tx_wake_queue(txq);  

Then what about doing netif_detach earlier in netvsc_detach.

The state management is already (too) complex in netvsc and adding another
boolean flag just makes it harder to understand.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help