Skip to content

Commit d8ae40d

Browse files
aloktionanguy11
authored andcommitted
ixgbe: stop re-reading flash on every get_drvinfo for e610
ixgbe_get_drvinfo() calls ixgbe_refresh_fw_version() on every ethtool query for e610 adapters. That ends up in ixgbe_discover_flash_size(), which bisects the full 16 MB NVM space issuing one ACI command per step (~20 ms each, ~24 steps total = ~500 ms). Profiling on an idle E610-XAT2 system with telegraf scraping ethtool stats every 10 seconds: kretprobe:ixgbe_get_drvinfo took 527603 us kretprobe:ixgbe_get_drvinfo took 523978 us kretprobe:ixgbe_get_drvinfo took 552975 us kretprobe:ice_get_drvinfo took 3 us kretprobe:igb_get_drvinfo took 2 us kretprobe:i40e_get_drvinfo took 5 us The half-second stall happens under the RTNL lock, causing visible latency on ip-link and friends. The FW version can only change after an EMPR reset. All flash data is already populated at probe time and the cached adapter->eeprom_id is what get_drvinfo should be returning. The only place that needs to trigger a re-read is ixgbe_devlink_reload_empr_finish(), right after the EMPR completes and new firmware is running. Additionally, refresh the FW version in ixgbe_reinit_locked() so that any PF that undergoes a reinit after an EMPR (e.g. triggered by another PF's devlink reload) also picks up the new version in adapter->eeprom_id. ixgbe_devlink_info_get() keeps its refresh call for explicit "devlink dev info" queries, which is fine given those are user-initiated. Fixes: c9e563c ("ixgbe: add support for devlink reload") Co-developed-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com> Signed-off-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com> Signed-off-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com> Reviewed-by: Simon Horman <horms@kernel.org> Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel) Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
1 parent bf6dbad commit d8ae40d

4 files changed

Lines changed: 19 additions & 8 deletions

File tree

drivers/net/ethernet/intel/ixgbe/devlink/devlink.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ static int ixgbe_devlink_reload_empr_finish(struct devlink *devlink,
474474
adapter->flags2 &= ~(IXGBE_FLAG2_API_MISMATCH |
475475
IXGBE_FLAG2_FW_ROLLBACK);
476476

477-
return 0;
477+
return ixgbe_refresh_fw_version(adapter);
478478
}
479479

480480
static const struct devlink_ops ixgbe_devlink_ops = {

drivers/net/ethernet/intel/ixgbe/ixgbe.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,7 @@ int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter);
973973
bool ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id,
974974
u16 subdevice_id);
975975
void ixgbe_set_fw_version_e610(struct ixgbe_adapter *adapter);
976-
void ixgbe_refresh_fw_version(struct ixgbe_adapter *adapter);
976+
int ixgbe_refresh_fw_version(struct ixgbe_adapter *adapter);
977977
#ifdef CONFIG_PCI_IOV
978978
void ixgbe_full_sync_mac_table(struct ixgbe_adapter *adapter);
979979
#endif

drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,23 +1155,24 @@ static int ixgbe_set_eeprom(struct net_device *netdev,
11551155
return ret_val;
11561156
}
11571157

1158-
void ixgbe_refresh_fw_version(struct ixgbe_adapter *adapter)
1158+
int ixgbe_refresh_fw_version(struct ixgbe_adapter *adapter)
11591159
{
11601160
struct ixgbe_hw *hw = &adapter->hw;
1161+
int err;
1162+
1163+
err = ixgbe_get_flash_data(hw);
1164+
if (err)
1165+
return err;
11611166

1162-
ixgbe_get_flash_data(hw);
11631167
ixgbe_set_fw_version_e610(adapter);
1168+
return 0;
11641169
}
11651170

11661171
static void ixgbe_get_drvinfo(struct net_device *netdev,
11671172
struct ethtool_drvinfo *drvinfo)
11681173
{
11691174
struct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);
11701175

1171-
/* need to refresh info for e610 in case fw reloads in runtime */
1172-
if (adapter->hw.mac.type == ixgbe_mac_e610)
1173-
ixgbe_refresh_fw_version(adapter);
1174-
11751176
strscpy(drvinfo->driver, ixgbe_driver_name, sizeof(drvinfo->driver));
11761177

11771178
strscpy(drvinfo->fw_version, adapter->eeprom_id,

drivers/net/ethernet/intel/ixgbe/ixgbe_main.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6289,6 +6289,16 @@ void ixgbe_reinit_locked(struct ixgbe_adapter *adapter)
62896289
if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
62906290
msleep(2000);
62916291
ixgbe_up(adapter);
6292+
6293+
/* E610 has no FW event to notify all PFs of an EMPR reset, so
6294+
* refresh the FW version here to pick up any new FW version after
6295+
* a hardware reset (e.g. EMPR triggered by another PF's devlink
6296+
* reload). ixgbe_refresh_fw_version() updates both hw->flash and
6297+
* adapter->eeprom_id so ethtool -i reports the correct string.
6298+
*/
6299+
if (adapter->hw.mac.type == ixgbe_mac_e610)
6300+
(void)ixgbe_refresh_fw_version(adapter);
6301+
62926302
clear_bit(__IXGBE_RESETTING, &adapter->state);
62936303
}
62946304

0 commit comments

Comments
 (0)