Skip to content

Commit ee713b6

Browse files
committed
Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue
Jeff Kirsher says: ==================== 40GbE Intel Wired LAN Driver Updates 2018-08-30 This series contains updates to i40e, i40evf and virtchnl. Jake implements helper functions to use an array to handle the queue stats which reduces the boiler plate code as well as keep the complexity localized to a few functions. Paweł adds the ability to change a VF's MAC address from the host side without having to reload the VF driver on the guest side. Paul adds a check to ensure that the number of queues that the PF sends to the VF is equal to or less than the maximum number of queues the VF can support. Mitch fixes an issue caught by GCC 8, where we need to not include the terminating null in the length of the string for strncpy(). Lihong fixes a VF issue to ensure that it does not enter into promiscuous mode when macvlan is added to the VF. Fixed a potential crash after a VF is removed, since the workqueue sync for the adminq task was not being cancelled. Harshitha fixes the type for field_flags in the virtchnl_filter struct. Martyna removes an unnecessary check in a conditional if statement. Björn fixes an issue reported by Jesper Dangaard Brouer, where the driver was reporting incorrect statistics when XDP was enabled. Jan fixes the potential reporting of incorrect speed settings. Patryk fixed an issue where the flag I40EVF_FLAG_AQ_ENABLE_VLAN_STRIPPING was getting set when any offload is set via ethtool. Resolved by only setting this flag when VLAN offload is enabled. Also ensure we hold the rtnl lock when we are clearing the interrupt scheme. Added a check when deleting the MAC address from the VF to ensure that the MAC address was not set by the PF and if it was, do not delete it. v2: updated patch 2 in the series based on community feedback from David Miller to inline a function ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents f0259b6 + 5907cf6 commit ee713b6

File tree

10 files changed

+678
-281
lines changed

10 files changed

+678
-281
lines changed

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

Lines changed: 44 additions & 194 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,8 @@
66
#include "i40e.h"
77
#include "i40e_diag.h"
88

9-
struct i40e_stats {
10-
/* The stat_string is expected to be a format string formatted using
11-
* vsnprintf by i40e_add_stat_strings. Every member of a stats array
12-
* should use the same format specifiers as they will be formatted
13-
* using the same variadic arguments.
14-
*/
15-
char stat_string[ETH_GSTRING_LEN];
16-
int sizeof_stat;
17-
int stat_offset;
18-
};
9+
#include "i40e_ethtool_stats.h"
1910

20-
#define I40E_STAT(_type, _name, _stat) { \
21-
.stat_string = _name, \
22-
.sizeof_stat = FIELD_SIZEOF(_type, _stat), \
23-
.stat_offset = offsetof(_type, _stat) \
24-
}
25-
26-
#define I40E_NETDEV_STAT(_net_stat) \
27-
I40E_STAT(struct rtnl_link_stats64, #_net_stat, _net_stat)
2811
#define I40E_PF_STAT(_name, _stat) \
2912
I40E_STAT(struct i40e_pf, _name, _stat)
3013
#define I40E_VSI_STAT(_name, _stat) \
@@ -33,6 +16,8 @@ struct i40e_stats {
3316
I40E_STAT(struct i40e_veb, _name, _stat)
3417
#define I40E_PFC_STAT(_name, _stat) \
3518
I40E_STAT(struct i40e_pfc_stats, _name, _stat)
19+
#define I40E_QUEUE_STAT(_name, _stat) \
20+
I40E_STAT(struct i40e_ring, _name, _stat)
3621

3722
static const struct i40e_stats i40e_gstrings_net_stats[] = {
3823
I40E_NETDEV_STAT(rx_packets),
@@ -171,20 +156,11 @@ static const struct i40e_stats i40e_gstrings_pfc_stats[] = {
171156
I40E_PFC_STAT("port.rx_priority_%u_xon_2_xoff", priority_xon_2_xoff),
172157
};
173158

174-
/* We use num_tx_queues here as a proxy for the maximum number of queues
175-
* available because we always allocate queues symmetrically.
176-
*/
177-
#define I40E_MAX_NUM_QUEUES(n) ((n)->num_tx_queues)
178-
#define I40E_QUEUE_STATS_LEN(n) \
179-
(I40E_MAX_NUM_QUEUES(n) \
180-
* 2 /* Tx and Rx together */ \
181-
* (sizeof(struct i40e_queue_stats) / sizeof(u64)))
182-
#define I40E_GLOBAL_STATS_LEN ARRAY_SIZE(i40e_gstrings_stats)
183159
#define I40E_NETDEV_STATS_LEN ARRAY_SIZE(i40e_gstrings_net_stats)
160+
184161
#define I40E_MISC_STATS_LEN ARRAY_SIZE(i40e_gstrings_misc_stats)
185-
#define I40E_VSI_STATS_LEN(n) (I40E_NETDEV_STATS_LEN + \
186-
I40E_MISC_STATS_LEN + \
187-
I40E_QUEUE_STATS_LEN((n)))
162+
163+
#define I40E_VSI_STATS_LEN (I40E_NETDEV_STATS_LEN + I40E_MISC_STATS_LEN)
188164

189165
#define I40E_PFC_STATS_LEN (ARRAY_SIZE(i40e_gstrings_pfc_stats) * \
190166
I40E_MAX_USER_PRIORITY)
@@ -193,10 +169,15 @@ static const struct i40e_stats i40e_gstrings_pfc_stats[] = {
193169
(ARRAY_SIZE(i40e_gstrings_veb_tc_stats) * \
194170
I40E_MAX_TRAFFIC_CLASS))
195171

196-
#define I40E_PF_STATS_LEN(n) (I40E_GLOBAL_STATS_LEN + \
172+
#define I40E_GLOBAL_STATS_LEN ARRAY_SIZE(i40e_gstrings_stats)
173+
174+
#define I40E_PF_STATS_LEN (I40E_GLOBAL_STATS_LEN + \
197175
I40E_PFC_STATS_LEN + \
198176
I40E_VEB_STATS_LEN + \
199-
I40E_VSI_STATS_LEN((n)))
177+
I40E_VSI_STATS_LEN)
178+
179+
/* Length of stats for a single queue */
180+
#define I40E_QUEUE_STATS_LEN ARRAY_SIZE(i40e_gstrings_queue_stats)
200181

201182
enum i40e_ethtool_test_id {
202183
I40E_ETH_TEST_REG = 0,
@@ -1701,11 +1682,30 @@ static int i40e_get_stats_count(struct net_device *netdev)
17011682
struct i40e_netdev_priv *np = netdev_priv(netdev);
17021683
struct i40e_vsi *vsi = np->vsi;
17031684
struct i40e_pf *pf = vsi->back;
1685+
int stats_len;
17041686

17051687
if (vsi == pf->vsi[pf->lan_vsi] && pf->hw.partition_id == 1)
1706-
return I40E_PF_STATS_LEN(netdev);
1688+
stats_len = I40E_PF_STATS_LEN;
17071689
else
1708-
return I40E_VSI_STATS_LEN(netdev);
1690+
stats_len = I40E_VSI_STATS_LEN;
1691+
1692+
/* The number of stats reported for a given net_device must remain
1693+
* constant throughout the life of that device.
1694+
*
1695+
* This is because the API for obtaining the size, strings, and stats
1696+
* is spread out over three separate ethtool ioctls. There is no safe
1697+
* way to lock the number of stats across these calls, so we must
1698+
* assume that they will never change.
1699+
*
1700+
* Due to this, we report the maximum number of queues, even if not
1701+
* every queue is currently configured. Since we always allocate
1702+
* queues in pairs, we'll just use netdev->num_tx_queues * 2. This
1703+
* works because the num_tx_queues is set at device creation and never
1704+
* changes.
1705+
*/
1706+
stats_len += I40E_QUEUE_STATS_LEN * 2 * netdev->num_tx_queues;
1707+
1708+
return stats_len;
17091709
}
17101710

17111711
static int i40e_get_sset_count(struct net_device *netdev, int sset)
@@ -1727,89 +1727,6 @@ static int i40e_get_sset_count(struct net_device *netdev, int sset)
17271727
}
17281728
}
17291729

1730-
/**
1731-
* i40e_add_one_ethtool_stat - copy the stat into the supplied buffer
1732-
* @data: location to store the stat value
1733-
* @pointer: basis for where to copy from
1734-
* @stat: the stat definition
1735-
*
1736-
* Copies the stat data defined by the pointer and stat structure pair into
1737-
* the memory supplied as data. Used to implement i40e_add_ethtool_stats.
1738-
* If the pointer is null, data will be zero'd.
1739-
*/
1740-
static inline void
1741-
i40e_add_one_ethtool_stat(u64 *data, void *pointer,
1742-
const struct i40e_stats *stat)
1743-
{
1744-
char *p;
1745-
1746-
if (!pointer) {
1747-
/* ensure that the ethtool data buffer is zero'd for any stats
1748-
* which don't have a valid pointer.
1749-
*/
1750-
*data = 0;
1751-
return;
1752-
}
1753-
1754-
p = (char *)pointer + stat->stat_offset;
1755-
switch (stat->sizeof_stat) {
1756-
case sizeof(u64):
1757-
*data = *((u64 *)p);
1758-
break;
1759-
case sizeof(u32):
1760-
*data = *((u32 *)p);
1761-
break;
1762-
case sizeof(u16):
1763-
*data = *((u16 *)p);
1764-
break;
1765-
case sizeof(u8):
1766-
*data = *((u8 *)p);
1767-
break;
1768-
default:
1769-
WARN_ONCE(1, "unexpected stat size for %s",
1770-
stat->stat_string);
1771-
*data = 0;
1772-
}
1773-
}
1774-
1775-
/**
1776-
* __i40e_add_ethtool_stats - copy stats into the ethtool supplied buffer
1777-
* @data: ethtool stats buffer
1778-
* @pointer: location to copy stats from
1779-
* @stats: array of stats to copy
1780-
* @size: the size of the stats definition
1781-
*
1782-
* Copy the stats defined by the stats array using the pointer as a base into
1783-
* the data buffer supplied by ethtool. Updates the data pointer to point to
1784-
* the next empty location for successive calls to __i40e_add_ethtool_stats.
1785-
* If pointer is null, set the data values to zero and update the pointer to
1786-
* skip these stats.
1787-
**/
1788-
static inline void
1789-
__i40e_add_ethtool_stats(u64 **data, void *pointer,
1790-
const struct i40e_stats stats[],
1791-
const unsigned int size)
1792-
{
1793-
unsigned int i;
1794-
1795-
for (i = 0; i < size; i++)
1796-
i40e_add_one_ethtool_stat((*data)++, pointer, &stats[i]);
1797-
}
1798-
1799-
/**
1800-
* i40e_add_ethtool_stats - copy stats into ethtool supplied buffer
1801-
* @data: ethtool stats buffer
1802-
* @pointer: location where stats are stored
1803-
* @stats: static const array of stat definitions
1804-
*
1805-
* Macro to ease the use of __i40e_add_ethtool_stats by taking a static
1806-
* constant stats array and passing the ARRAY_SIZE(). This avoids typos by
1807-
* ensuring that we pass the size associated with the given stats array.
1808-
* Assumes that stats is an array.
1809-
**/
1810-
#define i40e_add_ethtool_stats(data, pointer, stats) \
1811-
__i40e_add_ethtool_stats(data, pointer, stats, ARRAY_SIZE(stats))
1812-
18131730
/**
18141731
* i40e_get_pfc_stats - copy HW PFC statistics to formatted structure
18151732
* @pf: the PF device structure
@@ -1853,12 +1770,10 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
18531770
struct ethtool_stats *stats, u64 *data)
18541771
{
18551772
struct i40e_netdev_priv *np = netdev_priv(netdev);
1856-
struct i40e_ring *tx_ring, *rx_ring;
18571773
struct i40e_vsi *vsi = np->vsi;
18581774
struct i40e_pf *pf = vsi->back;
18591775
struct i40e_veb *veb = pf->veb[pf->lan_veb];
18601776
unsigned int i;
1861-
unsigned int start;
18621777
bool veb_stats;
18631778
u64 *p = data;
18641779

@@ -1870,38 +1785,12 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
18701785
i40e_add_ethtool_stats(&data, vsi, i40e_gstrings_misc_stats);
18711786

18721787
rcu_read_lock();
1873-
for (i = 0; i < I40E_MAX_NUM_QUEUES(netdev) ; i++) {
1874-
tx_ring = READ_ONCE(vsi->tx_rings[i]);
1875-
1876-
if (!tx_ring) {
1877-
/* Bump the stat counter to skip these stats, and make
1878-
* sure the memory is zero'd
1879-
*/
1880-
*(data++) = 0;
1881-
*(data++) = 0;
1882-
*(data++) = 0;
1883-
*(data++) = 0;
1884-
continue;
1885-
}
1886-
1887-
/* process Tx ring statistics */
1888-
do {
1889-
start = u64_stats_fetch_begin_irq(&tx_ring->syncp);
1890-
data[0] = tx_ring->stats.packets;
1891-
data[1] = tx_ring->stats.bytes;
1892-
} while (u64_stats_fetch_retry_irq(&tx_ring->syncp, start));
1893-
data += 2;
1894-
1895-
/* Rx ring is the 2nd half of the queue pair */
1896-
rx_ring = &tx_ring[1];
1897-
do {
1898-
start = u64_stats_fetch_begin_irq(&rx_ring->syncp);
1899-
data[0] = rx_ring->stats.packets;
1900-
data[1] = rx_ring->stats.bytes;
1901-
} while (u64_stats_fetch_retry_irq(&rx_ring->syncp, start));
1902-
data += 2;
1788+
for (i = 0; i < netdev->num_tx_queues; i++) {
1789+
i40e_add_queue_stats(&data, READ_ONCE(vsi->tx_rings[i]));
1790+
i40e_add_queue_stats(&data, READ_ONCE(vsi->rx_rings[i]));
19031791
}
19041792
rcu_read_unlock();
1793+
19051794
if (vsi != pf->vsi[pf->lan_vsi] || pf->hw.partition_id != 1)
19061795
goto check_data_pointer;
19071796

@@ -1932,42 +1821,6 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
19321821
"ethtool stats count mismatch!");
19331822
}
19341823

1935-
/**
1936-
* __i40e_add_stat_strings - copy stat strings into ethtool buffer
1937-
* @p: ethtool supplied buffer
1938-
* @stats: stat definitions array
1939-
* @size: size of the stats array
1940-
*
1941-
* Format and copy the strings described by stats into the buffer pointed at
1942-
* by p.
1943-
**/
1944-
static void __i40e_add_stat_strings(u8 **p, const struct i40e_stats stats[],
1945-
const unsigned int size, ...)
1946-
{
1947-
unsigned int i;
1948-
1949-
for (i = 0; i < size; i++) {
1950-
va_list args;
1951-
1952-
va_start(args, size);
1953-
vsnprintf(*p, ETH_GSTRING_LEN, stats[i].stat_string, args);
1954-
*p += ETH_GSTRING_LEN;
1955-
va_end(args);
1956-
}
1957-
}
1958-
1959-
/**
1960-
* 40e_add_stat_strings - copy stat strings into ethtool buffer
1961-
* @p: ethtool supplied buffer
1962-
* @stats: stat definitions array
1963-
*
1964-
* Format and copy the strings described by the const static stats value into
1965-
* the buffer pointed at by p. Assumes that stats can have ARRAY_SIZE called
1966-
* for it.
1967-
**/
1968-
#define i40e_add_stat_strings(p, stats, ...) \
1969-
__i40e_add_stat_strings(p, stats, ARRAY_SIZE(stats), ## __VA_ARGS__)
1970-
19711824
/**
19721825
* i40e_get_stat_strings - copy stat strings into supplied buffer
19731826
* @netdev: the netdev to collect strings for
@@ -1990,16 +1843,13 @@ static void i40e_get_stat_strings(struct net_device *netdev, u8 *data)
19901843

19911844
i40e_add_stat_strings(&data, i40e_gstrings_misc_stats);
19921845

1993-
for (i = 0; i < I40E_MAX_NUM_QUEUES(netdev); i++) {
1994-
snprintf(data, ETH_GSTRING_LEN, "tx-%u.tx_packets", i);
1995-
data += ETH_GSTRING_LEN;
1996-
snprintf(data, ETH_GSTRING_LEN, "tx-%u.tx_bytes", i);
1997-
data += ETH_GSTRING_LEN;
1998-
snprintf(data, ETH_GSTRING_LEN, "rx-%u.rx_packets", i);
1999-
data += ETH_GSTRING_LEN;
2000-
snprintf(data, ETH_GSTRING_LEN, "rx-%u.rx_bytes", i);
2001-
data += ETH_GSTRING_LEN;
1846+
for (i = 0; i < netdev->num_tx_queues; i++) {
1847+
i40e_add_stat_strings(&data, i40e_gstrings_queue_stats,
1848+
"tx", i);
1849+
i40e_add_stat_strings(&data, i40e_gstrings_queue_stats,
1850+
"rx", i);
20021851
}
1852+
20031853
if (vsi != pf->vsi[pf->lan_vsi] || pf->hw.partition_id != 1)
20041854
return;
20051855

0 commit comments

Comments
 (0)