From: Konstantin Ilichev <[email protected]>

When an offline self-test is initiated with ethtool -t, any ongoing
traffic could get stuck because ice_stop() and ice_open() are called
without letting the OS know about state transitions.  In most cases
a write() system call would block.

Fix this by calling dev_change_flags() to bring the netdev up and
down, which ensures ndo_open()/ndo_stop() are called and all watchers
are notified correctly.

Fixes: 0e674aeb0b77 ("ice: Add handler for ethtool selftest")
Cc: [email protected]
Co-developed-by: Grzegorz Nitka <[email protected]>
Signed-off-by: Grzegorz Nitka <[email protected]>
Signed-off-by: Konstantin Ilichev <[email protected]>
Signed-off-by: Aleksandr Loktionov <[email protected]>
---

 drivers/net/ethernet/intel/ice/ice_ethtool.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c 
b/drivers/net/ethernet/intel/ice/ice_ethtool.c
index 96d95af..2a4f06f 100644
--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c
+++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c
@@ -1416,7 +1416,7 @@ ice_self_test(struct net_device *netdev, struct 
ethtool_test *eth_test,
                /* If the device is online then take it offline */
                if (if_running)
                        /* indicate we're in test mode */
-                       ice_stop(netdev);
+                       dev_change_flags(netdev, netdev->flags & ~IFF_UP, NULL);
 
                data[ICE_ETH_TEST_LINK] = ice_link_test(netdev);
                data[ICE_ETH_TEST_EEPROM] = ice_eeprom_test(netdev);
@@ -1434,10 +1434,12 @@ ice_self_test(struct net_device *netdev, struct 
ethtool_test *eth_test,
                clear_bit(ICE_TESTING, pf->state);
 
                if (if_running) {
-                       int status = ice_open(netdev);
+                       int status = dev_change_flags(netdev,
+                                                     netdev->flags | IFF_UP,
+                                                     NULL);
 
                        if (status) {
-                               dev_err(dev, "Could not open device %s, err 
%d\n",
+                               dev_err(dev, "Could not bring up device %s, err 
%d\n",
                                        pf->int_name, status);
                        }
                }
-- 
2.52.0

Reply via email to