Skip to content

Commit 9955d49

Browse files
jacob-kellerJeff Kirsher
authored andcommitted
i40e: always return VEB stat strings
The ethtool API for obtaining device statistics is not intended to allow runtime changes in the number of statistics reported. It may *appear* this way, as there is an ability to request the number of stats using ethtool_get_set_count(). However, it is expected that this must always return the same value for invocations of the same device. If we don't satisfy this contract, and allow the number of stats to change during run time, we could cause invalid memory accesses or report the stat strings incorrectly. This is because the API for obtaining stats is to (1) get the size, (2) get the strings and finally (3) get the stats. Since these are each separate ethtool op commands, it is not possible to maintain consistency by holding the RTNL lock over the whole operation. This results in the potential for a race condition to occur where the size changed between any of the 3 calls. Avoid this issue by requiring that we always return the same value for a given device. We can check any values which remain constant for the life of the device, but must not report different sizes depending on runtime attributes. This patch specifically fixes the VEB statistics strings to always be reported. Other issues will be fixed in future patches. Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
1 parent bdf2752 commit 9955d49

File tree

1 file changed

+23
-29
lines changed

1 file changed

+23
-29
lines changed

drivers/net/ethernet/intel/i40e/i40e_ethtool.c

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1661,15 +1661,10 @@ static int i40e_get_stats_count(struct net_device *netdev)
16611661
struct i40e_vsi *vsi = np->vsi;
16621662
struct i40e_pf *pf = vsi->back;
16631663

1664-
if (vsi == pf->vsi[pf->lan_vsi] && pf->hw.partition_id == 1) {
1665-
if (pf->lan_veb != I40E_NO_VEB &&
1666-
pf->flags & I40E_FLAG_VEB_STATS_ENABLED)
1667-
return I40E_PF_STATS_LEN(netdev) + I40E_VEB_STATS_TOTAL;
1668-
else
1669-
return I40E_PF_STATS_LEN(netdev);
1670-
} else {
1664+
if (vsi == pf->vsi[pf->lan_vsi] && pf->hw.partition_id == 1)
1665+
return I40E_PF_STATS_LEN(netdev) + I40E_VEB_STATS_TOTAL;
1666+
else
16711667
return I40E_VSI_STATS_LEN(netdev);
1672-
}
16731668
}
16741669

16751670
static int i40e_get_sset_count(struct net_device *netdev, int sset)
@@ -1760,6 +1755,8 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
17601755
data[i++] = veb->tc_stats.tc_rx_packets[j];
17611756
data[i++] = veb->tc_stats.tc_rx_bytes[j];
17621757
}
1758+
} else {
1759+
i += I40E_VEB_STATS_TOTAL;
17631760
}
17641761
for (j = 0; j < I40E_GLOBAL_STATS_LEN; j++) {
17651762
p = (char *)pf + i40e_gstrings_stats[j].stat_offset;
@@ -1816,27 +1813,24 @@ static void i40e_get_strings(struct net_device *netdev, u32 stringset,
18161813
if (vsi != pf->vsi[pf->lan_vsi] || pf->hw.partition_id != 1)
18171814
return;
18181815

1819-
if ((pf->lan_veb != I40E_NO_VEB) &&
1820-
(pf->flags & I40E_FLAG_VEB_STATS_ENABLED)) {
1821-
for (i = 0; i < I40E_VEB_STATS_LEN; i++) {
1822-
snprintf(p, ETH_GSTRING_LEN, "veb.%s",
1823-
i40e_gstrings_veb_stats[i].stat_string);
1824-
p += ETH_GSTRING_LEN;
1825-
}
1826-
for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
1827-
snprintf(p, ETH_GSTRING_LEN,
1828-
"veb.tc_%d_tx_packets", i);
1829-
p += ETH_GSTRING_LEN;
1830-
snprintf(p, ETH_GSTRING_LEN,
1831-
"veb.tc_%d_tx_bytes", i);
1832-
p += ETH_GSTRING_LEN;
1833-
snprintf(p, ETH_GSTRING_LEN,
1834-
"veb.tc_%d_rx_packets", i);
1835-
p += ETH_GSTRING_LEN;
1836-
snprintf(p, ETH_GSTRING_LEN,
1837-
"veb.tc_%d_rx_bytes", i);
1838-
p += ETH_GSTRING_LEN;
1839-
}
1816+
for (i = 0; i < I40E_VEB_STATS_LEN; i++) {
1817+
snprintf(p, ETH_GSTRING_LEN, "veb.%s",
1818+
i40e_gstrings_veb_stats[i].stat_string);
1819+
p += ETH_GSTRING_LEN;
1820+
}
1821+
for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
1822+
snprintf(p, ETH_GSTRING_LEN,
1823+
"veb.tc_%u_tx_packets", i);
1824+
p += ETH_GSTRING_LEN;
1825+
snprintf(p, ETH_GSTRING_LEN,
1826+
"veb.tc_%u_tx_bytes", i);
1827+
p += ETH_GSTRING_LEN;
1828+
snprintf(p, ETH_GSTRING_LEN,
1829+
"veb.tc_%u_rx_packets", i);
1830+
p += ETH_GSTRING_LEN;
1831+
snprintf(p, ETH_GSTRING_LEN,
1832+
"veb.tc_%u_rx_bytes", i);
1833+
p += ETH_GSTRING_LEN;
18401834
}
18411835
for (i = 0; i < I40E_GLOBAL_STATS_LEN; i++) {
18421836
snprintf(p, ETH_GSTRING_LEN, "port.%s",

0 commit comments

Comments
 (0)