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