* [net-next 6/9] i40e: fold prefix strings directly into stat names
From: Jeff Kirsher @ 2018-05-22 17:45 UTC (permalink / raw)
To: davem; +Cc: Jacob Keller, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <20180522174527.19680-1-jeffrey.t.kirsher@intel.com>
From: Jacob Keller <jacob.e.keller@intel.com>
We always prefix these stats with a fixed string, so just fold this
prefix into the stat string definition. This preparatory work will make
it easier to implement a helper function to copy stats and strings into
the supplied buffers in a future patch.
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>
---
.../net/ethernet/intel/i40e/i40e_ethtool.c | 137 +++++++++---------
1 file changed, 69 insertions(+), 68 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index 32bcb6a2a590..6b34845d251c 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -42,18 +42,18 @@ static const struct i40e_stats i40e_gstrings_net_stats[] = {
};
static const struct i40e_stats i40e_gstrings_veb_stats[] = {
- I40E_VEB_STAT("rx_bytes", stats.rx_bytes),
- I40E_VEB_STAT("tx_bytes", stats.tx_bytes),
- I40E_VEB_STAT("rx_unicast", stats.rx_unicast),
- I40E_VEB_STAT("tx_unicast", stats.tx_unicast),
- I40E_VEB_STAT("rx_multicast", stats.rx_multicast),
- I40E_VEB_STAT("tx_multicast", stats.tx_multicast),
- I40E_VEB_STAT("rx_broadcast", stats.rx_broadcast),
- I40E_VEB_STAT("tx_broadcast", stats.tx_broadcast),
- I40E_VEB_STAT("rx_discards", stats.rx_discards),
- I40E_VEB_STAT("tx_discards", stats.tx_discards),
- I40E_VEB_STAT("tx_errors", stats.tx_errors),
- I40E_VEB_STAT("rx_unknown_protocol", stats.rx_unknown_protocol),
+ I40E_VEB_STAT("veb.rx_bytes", stats.rx_bytes),
+ I40E_VEB_STAT("veb.tx_bytes", stats.tx_bytes),
+ I40E_VEB_STAT("veb.rx_unicast", stats.rx_unicast),
+ I40E_VEB_STAT("veb.tx_unicast", stats.tx_unicast),
+ I40E_VEB_STAT("veb.rx_multicast", stats.rx_multicast),
+ I40E_VEB_STAT("veb.tx_multicast", stats.tx_multicast),
+ I40E_VEB_STAT("veb.rx_broadcast", stats.rx_broadcast),
+ I40E_VEB_STAT("veb.tx_broadcast", stats.tx_broadcast),
+ I40E_VEB_STAT("veb.rx_discards", stats.rx_discards),
+ I40E_VEB_STAT("veb.tx_discards", stats.tx_discards),
+ I40E_VEB_STAT("veb.tx_errors", stats.tx_errors),
+ I40E_VEB_STAT("veb.rx_unknown_protocol", stats.rx_unknown_protocol),
};
static const struct i40e_stats i40e_gstrings_misc_stats[] = {
@@ -82,62 +82,63 @@ static const struct i40e_stats i40e_gstrings_misc_stats[] = {
* is queried on the base PF netdev, not on the VMDq or FCoE netdev.
*/
static const struct i40e_stats i40e_gstrings_stats[] = {
- I40E_PF_STAT("rx_bytes", stats.eth.rx_bytes),
- I40E_PF_STAT("tx_bytes", stats.eth.tx_bytes),
- I40E_PF_STAT("rx_unicast", stats.eth.rx_unicast),
- I40E_PF_STAT("tx_unicast", stats.eth.tx_unicast),
- I40E_PF_STAT("rx_multicast", stats.eth.rx_multicast),
- I40E_PF_STAT("tx_multicast", stats.eth.tx_multicast),
- I40E_PF_STAT("rx_broadcast", stats.eth.rx_broadcast),
- I40E_PF_STAT("tx_broadcast", stats.eth.tx_broadcast),
- I40E_PF_STAT("tx_errors", stats.eth.tx_errors),
- I40E_PF_STAT("rx_dropped", stats.eth.rx_discards),
- I40E_PF_STAT("tx_dropped_link_down", stats.tx_dropped_link_down),
- I40E_PF_STAT("rx_crc_errors", stats.crc_errors),
- I40E_PF_STAT("illegal_bytes", stats.illegal_bytes),
- I40E_PF_STAT("mac_local_faults", stats.mac_local_faults),
- I40E_PF_STAT("mac_remote_faults", stats.mac_remote_faults),
- I40E_PF_STAT("tx_timeout", tx_timeout_count),
- I40E_PF_STAT("rx_csum_bad", hw_csum_rx_error),
- I40E_PF_STAT("rx_length_errors", stats.rx_length_errors),
- I40E_PF_STAT("link_xon_rx", stats.link_xon_rx),
- I40E_PF_STAT("link_xoff_rx", stats.link_xoff_rx),
- I40E_PF_STAT("link_xon_tx", stats.link_xon_tx),
- I40E_PF_STAT("link_xoff_tx", stats.link_xoff_tx),
- I40E_PF_STAT("rx_size_64", stats.rx_size_64),
- I40E_PF_STAT("rx_size_127", stats.rx_size_127),
- I40E_PF_STAT("rx_size_255", stats.rx_size_255),
- I40E_PF_STAT("rx_size_511", stats.rx_size_511),
- I40E_PF_STAT("rx_size_1023", stats.rx_size_1023),
- I40E_PF_STAT("rx_size_1522", stats.rx_size_1522),
- I40E_PF_STAT("rx_size_big", stats.rx_size_big),
- I40E_PF_STAT("tx_size_64", stats.tx_size_64),
- I40E_PF_STAT("tx_size_127", stats.tx_size_127),
- I40E_PF_STAT("tx_size_255", stats.tx_size_255),
- I40E_PF_STAT("tx_size_511", stats.tx_size_511),
- I40E_PF_STAT("tx_size_1023", stats.tx_size_1023),
- I40E_PF_STAT("tx_size_1522", stats.tx_size_1522),
- I40E_PF_STAT("tx_size_big", stats.tx_size_big),
- I40E_PF_STAT("rx_undersize", stats.rx_undersize),
- I40E_PF_STAT("rx_fragments", stats.rx_fragments),
- I40E_PF_STAT("rx_oversize", stats.rx_oversize),
- I40E_PF_STAT("rx_jabber", stats.rx_jabber),
- I40E_PF_STAT("VF_admin_queue_requests", vf_aq_requests),
- I40E_PF_STAT("arq_overflows", arq_overflows),
- I40E_PF_STAT("rx_hwtstamp_cleared", rx_hwtstamp_cleared),
- I40E_PF_STAT("tx_hwtstamp_skipped", tx_hwtstamp_skipped),
- I40E_PF_STAT("fdir_flush_cnt", fd_flush_cnt),
- I40E_PF_STAT("fdir_atr_match", stats.fd_atr_match),
- I40E_PF_STAT("fdir_atr_tunnel_match", stats.fd_atr_tunnel_match),
- I40E_PF_STAT("fdir_atr_status", stats.fd_atr_status),
- I40E_PF_STAT("fdir_sb_match", stats.fd_sb_match),
- I40E_PF_STAT("fdir_sb_status", stats.fd_sb_status),
+ I40E_PF_STAT("port.rx_bytes", stats.eth.rx_bytes),
+ I40E_PF_STAT("port.tx_bytes", stats.eth.tx_bytes),
+ I40E_PF_STAT("port.rx_unicast", stats.eth.rx_unicast),
+ I40E_PF_STAT("port.tx_unicast", stats.eth.tx_unicast),
+ I40E_PF_STAT("port.rx_multicast", stats.eth.rx_multicast),
+ I40E_PF_STAT("port.tx_multicast", stats.eth.tx_multicast),
+ I40E_PF_STAT("port.rx_broadcast", stats.eth.rx_broadcast),
+ I40E_PF_STAT("port.tx_broadcast", stats.eth.tx_broadcast),
+ I40E_PF_STAT("port.tx_errors", stats.eth.tx_errors),
+ I40E_PF_STAT("port.rx_dropped", stats.eth.rx_discards),
+ I40E_PF_STAT("port.tx_dropped_link_down", stats.tx_dropped_link_down),
+ I40E_PF_STAT("port.rx_crc_errors", stats.crc_errors),
+ I40E_PF_STAT("port.illegal_bytes", stats.illegal_bytes),
+ I40E_PF_STAT("port.mac_local_faults", stats.mac_local_faults),
+ I40E_PF_STAT("port.mac_remote_faults", stats.mac_remote_faults),
+ I40E_PF_STAT("port.tx_timeout", tx_timeout_count),
+ I40E_PF_STAT("port.rx_csum_bad", hw_csum_rx_error),
+ I40E_PF_STAT("port.rx_length_errors", stats.rx_length_errors),
+ I40E_PF_STAT("port.link_xon_rx", stats.link_xon_rx),
+ I40E_PF_STAT("port.link_xoff_rx", stats.link_xoff_rx),
+ I40E_PF_STAT("port.link_xon_tx", stats.link_xon_tx),
+ I40E_PF_STAT("port.link_xoff_tx", stats.link_xoff_tx),
+ I40E_PF_STAT("port.rx_size_64", stats.rx_size_64),
+ I40E_PF_STAT("port.rx_size_127", stats.rx_size_127),
+ I40E_PF_STAT("port.rx_size_255", stats.rx_size_255),
+ I40E_PF_STAT("port.rx_size_511", stats.rx_size_511),
+ I40E_PF_STAT("port.rx_size_1023", stats.rx_size_1023),
+ I40E_PF_STAT("port.rx_size_1522", stats.rx_size_1522),
+ I40E_PF_STAT("port.rx_size_big", stats.rx_size_big),
+ I40E_PF_STAT("port.tx_size_64", stats.tx_size_64),
+ I40E_PF_STAT("port.tx_size_127", stats.tx_size_127),
+ I40E_PF_STAT("port.tx_size_255", stats.tx_size_255),
+ I40E_PF_STAT("port.tx_size_511", stats.tx_size_511),
+ I40E_PF_STAT("port.tx_size_1023", stats.tx_size_1023),
+ I40E_PF_STAT("port.tx_size_1522", stats.tx_size_1522),
+ I40E_PF_STAT("port.tx_size_big", stats.tx_size_big),
+ I40E_PF_STAT("port.rx_undersize", stats.rx_undersize),
+ I40E_PF_STAT("port.rx_fragments", stats.rx_fragments),
+ I40E_PF_STAT("port.rx_oversize", stats.rx_oversize),
+ I40E_PF_STAT("port.rx_jabber", stats.rx_jabber),
+ I40E_PF_STAT("port.VF_admin_queue_requests", vf_aq_requests),
+ I40E_PF_STAT("port.arq_overflows", arq_overflows),
+ I40E_PF_STAT("port.tx_hwtstamp_timeouts", tx_hwtstamp_timeouts),
+ I40E_PF_STAT("port.rx_hwtstamp_cleared", rx_hwtstamp_cleared),
+ I40E_PF_STAT("port.tx_hwtstamp_skipped", tx_hwtstamp_skipped),
+ I40E_PF_STAT("port.fdir_flush_cnt", fd_flush_cnt),
+ I40E_PF_STAT("port.fdir_atr_match", stats.fd_atr_match),
+ I40E_PF_STAT("port.fdir_atr_tunnel_match", stats.fd_atr_tunnel_match),
+ I40E_PF_STAT("port.fdir_atr_status", stats.fd_atr_status),
+ I40E_PF_STAT("port.fdir_sb_match", stats.fd_sb_match),
+ I40E_PF_STAT("port.fdir_sb_status", stats.fd_sb_status),
/* LPI stats */
- I40E_PF_STAT("tx_lpi_status", stats.tx_lpi_status),
- I40E_PF_STAT("rx_lpi_status", stats.rx_lpi_status),
- I40E_PF_STAT("tx_lpi_count", stats.tx_lpi_count),
- I40E_PF_STAT("rx_lpi_count", stats.rx_lpi_count),
+ I40E_PF_STAT("port.tx_lpi_status", stats.tx_lpi_status),
+ I40E_PF_STAT("port.rx_lpi_status", stats.rx_lpi_status),
+ I40E_PF_STAT("port.tx_lpi_count", stats.tx_lpi_count),
+ I40E_PF_STAT("port.rx_lpi_count", stats.rx_lpi_count),
};
/* We use num_tx_queues here as a proxy for the maximum number of queues
@@ -1819,7 +1820,7 @@ static void i40e_get_stat_strings(struct net_device *netdev, u8 *data)
return;
for (i = 0; i < I40E_VEB_STATS_LEN; i++) {
- snprintf(p, ETH_GSTRING_LEN, "veb.%s",
+ snprintf(p, ETH_GSTRING_LEN, "%s",
i40e_gstrings_veb_stats[i].stat_string);
p += ETH_GSTRING_LEN;
}
@@ -1839,7 +1840,7 @@ static void i40e_get_stat_strings(struct net_device *netdev, u8 *data)
}
for (i = 0; i < I40E_GLOBAL_STATS_LEN; i++) {
- snprintf(p, ETH_GSTRING_LEN, "port.%s",
+ snprintf(p, ETH_GSTRING_LEN, "%s",
i40e_gstrings_stats[i].stat_string);
p += ETH_GSTRING_LEN;
}
--
2.17.0
^ permalink raw reply related
* [net-next 7/9] i40e: update data pointer directly when copying to the buffer
From: Jeff Kirsher @ 2018-05-22 17:45 UTC (permalink / raw)
To: davem; +Cc: Jacob Keller, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <20180522174527.19680-1-jeffrey.t.kirsher@intel.com>
From: Jacob Keller <jacob.e.keller@intel.com>
A future patch is going to add a helper function i40e_add_ethtool_stats
that will help lower the amount of boiler plate code in the
i40e_get_ethtool_stats function.
This conversion will take place over many patches, and the helper
function will work by directly updating a reference to the data pointer.
Since this would not work combined with the current method of accessing
data like an array, update all the code that copies stats into the data
buffer to use direct updates to the pointer instead of array accesses.
This will prevent incorrect stat updates for patches in between the
conversion.
Similarly, when copying strings, we used a separate char *p pointer.
Instead, use the data pointer directly as it's already a (u8 *) type
which is the same size.
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>
---
.../net/ethernet/intel/i40e/i40e_ethtool.c | 117 +++++++++---------
1 file changed, 58 insertions(+), 59 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index 6b34845d251c..44a2803cb1ec 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -1699,7 +1699,6 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
struct i40e_vsi *vsi = np->vsi;
struct i40e_pf *pf = vsi->back;
unsigned int j;
- int i = 0;
char *p;
struct rtnl_link_stats64 *net_stats = i40e_get_vsi_stats_struct(vsi);
unsigned int start;
@@ -1708,12 +1707,12 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
for (j = 0; j < I40E_NETDEV_STATS_LEN; j++) {
p = (char *)net_stats + i40e_gstrings_net_stats[j].stat_offset;
- data[i++] = (i40e_gstrings_net_stats[j].sizeof_stat ==
+ *(data++) = (i40e_gstrings_net_stats[j].sizeof_stat ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
for (j = 0; j < I40E_MISC_STATS_LEN; j++) {
p = (char *)vsi + i40e_gstrings_misc_stats[j].stat_offset;
- data[i++] = (i40e_gstrings_misc_stats[j].sizeof_stat ==
+ *(data++) = (i40e_gstrings_misc_stats[j].sizeof_stat ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
rcu_read_lock();
@@ -1724,29 +1723,29 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
/* Bump the stat counter to skip these stats, and make
* sure the memory is zero'd
*/
- data[i++] = 0;
- data[i++] = 0;
- data[i++] = 0;
- data[i++] = 0;
+ *(data++) = 0;
+ *(data++) = 0;
+ *(data++) = 0;
+ *(data++) = 0;
continue;
}
/* process Tx ring statistics */
do {
start = u64_stats_fetch_begin_irq(&tx_ring->syncp);
- data[i] = tx_ring->stats.packets;
- data[i + 1] = tx_ring->stats.bytes;
+ data[0] = tx_ring->stats.packets;
+ data[1] = tx_ring->stats.bytes;
} while (u64_stats_fetch_retry_irq(&tx_ring->syncp, start));
- i += 2;
+ data += 2;
/* Rx ring is the 2nd half of the queue pair */
rx_ring = &tx_ring[1];
do {
start = u64_stats_fetch_begin_irq(&rx_ring->syncp);
- data[i] = rx_ring->stats.packets;
- data[i + 1] = rx_ring->stats.bytes;
+ data[0] = rx_ring->stats.packets;
+ data[1] = rx_ring->stats.bytes;
} while (u64_stats_fetch_retry_irq(&rx_ring->syncp, start));
- i += 2;
+ data += 2;
}
rcu_read_unlock();
if (vsi != pf->vsi[pf->lan_vsi] || pf->hw.partition_id != 1)
@@ -1759,33 +1758,33 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
for (j = 0; j < I40E_VEB_STATS_LEN; j++) {
p = (char *)veb;
p += i40e_gstrings_veb_stats[j].stat_offset;
- data[i++] = (i40e_gstrings_veb_stats[j].sizeof_stat ==
+ *(data++) = (i40e_gstrings_veb_stats[j].sizeof_stat ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
for (j = 0; j < I40E_MAX_TRAFFIC_CLASS; j++) {
- data[i++] = veb->tc_stats.tc_tx_packets[j];
- data[i++] = veb->tc_stats.tc_tx_bytes[j];
- data[i++] = veb->tc_stats.tc_rx_packets[j];
- data[i++] = veb->tc_stats.tc_rx_bytes[j];
+ *(data++) = veb->tc_stats.tc_tx_packets[j];
+ *(data++) = veb->tc_stats.tc_tx_bytes[j];
+ *(data++) = veb->tc_stats.tc_rx_packets[j];
+ *(data++) = veb->tc_stats.tc_rx_bytes[j];
}
} else {
- i += I40E_VEB_STATS_TOTAL;
+ data += I40E_VEB_STATS_TOTAL;
}
for (j = 0; j < I40E_GLOBAL_STATS_LEN; j++) {
p = (char *)pf + i40e_gstrings_stats[j].stat_offset;
- data[i++] = (i40e_gstrings_stats[j].sizeof_stat ==
+ *(data++) = (i40e_gstrings_stats[j].sizeof_stat ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
for (j = 0; j < I40E_MAX_USER_PRIORITY; j++) {
- data[i++] = pf->stats.priority_xon_tx[j];
- data[i++] = pf->stats.priority_xoff_tx[j];
+ *(data++) = pf->stats.priority_xon_tx[j];
+ *(data++) = pf->stats.priority_xoff_tx[j];
}
for (j = 0; j < I40E_MAX_USER_PRIORITY; j++) {
- data[i++] = pf->stats.priority_xon_rx[j];
- data[i++] = pf->stats.priority_xoff_rx[j];
+ *(data++) = pf->stats.priority_xon_rx[j];
+ *(data++) = pf->stats.priority_xoff_rx[j];
}
for (j = 0; j < I40E_MAX_USER_PRIORITY; j++)
- data[i++] = pf->stats.priority_xon_2_xoff[j];
+ *(data++) = pf->stats.priority_xon_2_xoff[j];
}
static void i40e_get_stat_strings(struct net_device *netdev, u8 *data)
@@ -1797,73 +1796,73 @@ static void i40e_get_stat_strings(struct net_device *netdev, u8 *data)
u8 *p = data;
for (i = 0; i < I40E_NETDEV_STATS_LEN; i++) {
- snprintf(p, ETH_GSTRING_LEN, "%s",
+ snprintf(data, ETH_GSTRING_LEN, "%s",
i40e_gstrings_net_stats[i].stat_string);
- p += ETH_GSTRING_LEN;
+ data += ETH_GSTRING_LEN;
}
for (i = 0; i < I40E_MISC_STATS_LEN; i++) {
- snprintf(p, ETH_GSTRING_LEN, "%s",
+ snprintf(data, ETH_GSTRING_LEN, "%s",
i40e_gstrings_misc_stats[i].stat_string);
- p += ETH_GSTRING_LEN;
+ data += ETH_GSTRING_LEN;
}
for (i = 0; i < I40E_MAX_NUM_QUEUES(netdev); i++) {
- snprintf(p, ETH_GSTRING_LEN, "tx-%u.tx_packets", i);
- p += ETH_GSTRING_LEN;
- snprintf(p, ETH_GSTRING_LEN, "tx-%u.tx_bytes", i);
- p += ETH_GSTRING_LEN;
- snprintf(p, ETH_GSTRING_LEN, "rx-%u.rx_packets", i);
- p += ETH_GSTRING_LEN;
- snprintf(p, ETH_GSTRING_LEN, "rx-%u.rx_bytes", i);
- p += ETH_GSTRING_LEN;
+ snprintf(data, ETH_GSTRING_LEN, "tx-%u.tx_packets", i);
+ data += ETH_GSTRING_LEN;
+ snprintf(data, ETH_GSTRING_LEN, "tx-%u.tx_bytes", i);
+ data += ETH_GSTRING_LEN;
+ snprintf(data, ETH_GSTRING_LEN, "rx-%u.rx_packets", i);
+ data += ETH_GSTRING_LEN;
+ snprintf(data, ETH_GSTRING_LEN, "rx-%u.rx_bytes", i);
+ data += ETH_GSTRING_LEN;
}
if (vsi != pf->vsi[pf->lan_vsi] || pf->hw.partition_id != 1)
return;
for (i = 0; i < I40E_VEB_STATS_LEN; i++) {
- snprintf(p, ETH_GSTRING_LEN, "%s",
+ snprintf(data, ETH_GSTRING_LEN, "%s",
i40e_gstrings_veb_stats[i].stat_string);
- p += ETH_GSTRING_LEN;
+ data += ETH_GSTRING_LEN;
}
for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
- snprintf(p, ETH_GSTRING_LEN,
+ snprintf(data, ETH_GSTRING_LEN,
"veb.tc_%u_tx_packets", i);
- p += ETH_GSTRING_LEN;
- snprintf(p, ETH_GSTRING_LEN,
+ data += ETH_GSTRING_LEN;
+ snprintf(data, ETH_GSTRING_LEN,
"veb.tc_%u_tx_bytes", i);
- p += ETH_GSTRING_LEN;
- snprintf(p, ETH_GSTRING_LEN,
+ data += ETH_GSTRING_LEN;
+ snprintf(data, ETH_GSTRING_LEN,
"veb.tc_%u_rx_packets", i);
- p += ETH_GSTRING_LEN;
- snprintf(p, ETH_GSTRING_LEN,
+ data += ETH_GSTRING_LEN;
+ snprintf(data, ETH_GSTRING_LEN,
"veb.tc_%u_rx_bytes", i);
- p += ETH_GSTRING_LEN;
+ data += ETH_GSTRING_LEN;
}
for (i = 0; i < I40E_GLOBAL_STATS_LEN; i++) {
- snprintf(p, ETH_GSTRING_LEN, "%s",
+ snprintf(data, ETH_GSTRING_LEN, "%s",
i40e_gstrings_stats[i].stat_string);
- p += ETH_GSTRING_LEN;
+ data += ETH_GSTRING_LEN;
}
for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
- snprintf(p, ETH_GSTRING_LEN,
+ snprintf(data, ETH_GSTRING_LEN,
"port.tx_priority_%u_xon", i);
- p += ETH_GSTRING_LEN;
- snprintf(p, ETH_GSTRING_LEN,
+ data += ETH_GSTRING_LEN;
+ snprintf(data, ETH_GSTRING_LEN,
"port.tx_priority_%u_xoff", i);
- p += ETH_GSTRING_LEN;
+ data += ETH_GSTRING_LEN;
}
for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
- snprintf(p, ETH_GSTRING_LEN,
+ snprintf(data, ETH_GSTRING_LEN,
"port.rx_priority_%u_xon", i);
- p += ETH_GSTRING_LEN;
- snprintf(p, ETH_GSTRING_LEN,
+ data += ETH_GSTRING_LEN;
+ snprintf(data, ETH_GSTRING_LEN,
"port.rx_priority_%u_xoff", i);
- p += ETH_GSTRING_LEN;
+ data += ETH_GSTRING_LEN;
}
for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
- snprintf(p, ETH_GSTRING_LEN,
+ snprintf(data, ETH_GSTRING_LEN,
"port.rx_priority_%u_xon_2_xoff", i);
- p += ETH_GSTRING_LEN;
+ data += ETH_GSTRING_LEN;
}
WARN_ONCE(p - data != i40e_get_stats_count(netdev) * ETH_GSTRING_LEN,
--
2.17.0
^ permalink raw reply related
* [net-next 3/9] i40e: always return all queue stat strings
From: Jeff Kirsher @ 2018-05-22 17:45 UTC (permalink / raw)
To: davem; +Cc: Jacob Keller, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <20180522174527.19680-1-jeffrey.t.kirsher@intel.com>
From: Jacob Keller <jacob.e.keller@intel.com>
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 queue statistics to always return
every queue even if it's not currently in use.
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>
---
.../net/ethernet/intel/i40e/i40e_ethtool.c | 22 ++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index de5dad7ff340..bacb01b63727 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -140,8 +140,12 @@ static const struct i40e_stats i40e_gstrings_stats[] = {
I40E_PF_STAT("rx_lpi_count", stats.rx_lpi_count),
};
-#define I40E_QUEUE_STATS_LEN(n) \
- (((struct i40e_netdev_priv *)netdev_priv((n)))->vsi->num_queue_pairs \
+/* We use num_tx_queues here as a proxy for the maximum number of queues
+ * available because we always allocate queues symmetrically.
+ */
+#define I40E_MAX_NUM_QUEUES(n) ((n)->num_tx_queues)
+#define I40E_QUEUE_STATS_LEN(n) \
+ (I40E_MAX_NUM_QUEUES(n) \
* 2 /* Tx and Rx together */ \
* (sizeof(struct i40e_queue_stats) / sizeof(u64)))
#define I40E_GLOBAL_STATS_LEN ARRAY_SIZE(i40e_gstrings_stats)
@@ -1712,11 +1716,19 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
rcu_read_lock();
- for (j = 0; j < vsi->num_queue_pairs; j++) {
+ for (j = 0; j < I40E_MAX_NUM_QUEUES(netdev) ; j++) {
tx_ring = READ_ONCE(vsi->tx_rings[j]);
- if (!tx_ring)
+ if (!tx_ring) {
+ /* Bump the stat counter to skip these stats, and make
+ * sure the memory is zero'd
+ */
+ data[i++] = 0;
+ data[i++] = 0;
+ data[i++] = 0;
+ data[i++] = 0;
continue;
+ }
/* process Tx ring statistics */
do {
@@ -1800,7 +1812,7 @@ static void i40e_get_strings(struct net_device *netdev, u32 stringset,
i40e_gstrings_misc_stats[i].stat_string);
p += ETH_GSTRING_LEN;
}
- for (i = 0; i < vsi->num_queue_pairs; i++) {
+ for (i = 0; i < I40E_MAX_NUM_QUEUES(netdev); i++) {
snprintf(p, ETH_GSTRING_LEN, "tx-%d.tx_packets", i);
p += ETH_GSTRING_LEN;
snprintf(p, ETH_GSTRING_LEN, "tx-%d.tx_bytes", i);
--
2.17.0
^ permalink raw reply related
* [net-next 4/9] i40e: split i40e_get_strings() into smaller functions
From: Jeff Kirsher @ 2018-05-22 17:45 UTC (permalink / raw)
To: davem; +Cc: Jacob Keller, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <20180522174527.19680-1-jeffrey.t.kirsher@intel.com>
From: Jacob Keller <jacob.e.keller@intel.com>
Split the statistic strings and private flags strings into their own
separate functions to aid code readability.
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>
---
.../net/ethernet/intel/i40e/i40e_ethtool.c | 183 ++++++++++--------
1 file changed, 100 insertions(+), 83 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index bacb01b63727..c50ed2d391e1 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -1787,8 +1787,7 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
data[i++] = pf->stats.priority_xon_2_xoff[j];
}
-static void i40e_get_strings(struct net_device *netdev, u32 stringset,
- u8 *data)
+static void i40e_get_stat_strings(struct net_device *netdev, u8 *data)
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_vsi *vsi = np->vsi;
@@ -1796,95 +1795,113 @@ static void i40e_get_strings(struct net_device *netdev, u32 stringset,
char *p = (char *)data;
unsigned int i;
+ for (i = 0; i < I40E_NETDEV_STATS_LEN; i++) {
+ snprintf(p, ETH_GSTRING_LEN, "%s",
+ i40e_gstrings_net_stats[i].stat_string);
+ p += ETH_GSTRING_LEN;
+ }
+ for (i = 0; i < I40E_MISC_STATS_LEN; i++) {
+ snprintf(p, ETH_GSTRING_LEN, "%s",
+ i40e_gstrings_misc_stats[i].stat_string);
+ p += ETH_GSTRING_LEN;
+ }
+ for (i = 0; i < I40E_MAX_NUM_QUEUES(netdev); i++) {
+ snprintf(p, ETH_GSTRING_LEN, "tx-%u.tx_packets", i);
+ p += ETH_GSTRING_LEN;
+ snprintf(p, ETH_GSTRING_LEN, "tx-%u.tx_bytes", i);
+ p += ETH_GSTRING_LEN;
+ snprintf(p, ETH_GSTRING_LEN, "rx-%u.rx_packets", i);
+ p += ETH_GSTRING_LEN;
+ snprintf(p, ETH_GSTRING_LEN, "rx-%u.rx_bytes", i);
+ p += ETH_GSTRING_LEN;
+ }
+ if (vsi != pf->vsi[pf->lan_vsi] || pf->hw.partition_id != 1)
+ return;
+
+ for (i = 0; i < I40E_VEB_STATS_LEN; i++) {
+ snprintf(p, ETH_GSTRING_LEN, "veb.%s",
+ i40e_gstrings_veb_stats[i].stat_string);
+ p += ETH_GSTRING_LEN;
+ }
+ for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
+ snprintf(p, ETH_GSTRING_LEN,
+ "veb.tc_%u_tx_packets", i);
+ p += ETH_GSTRING_LEN;
+ snprintf(p, ETH_GSTRING_LEN,
+ "veb.tc_%u_tx_bytes", i);
+ p += ETH_GSTRING_LEN;
+ snprintf(p, ETH_GSTRING_LEN,
+ "veb.tc_%u_rx_packets", i);
+ p += ETH_GSTRING_LEN;
+ snprintf(p, ETH_GSTRING_LEN,
+ "veb.tc_%u_rx_bytes", i);
+ p += ETH_GSTRING_LEN;
+ }
+
+ for (i = 0; i < I40E_GLOBAL_STATS_LEN; i++) {
+ snprintf(p, ETH_GSTRING_LEN, "port.%s",
+ i40e_gstrings_stats[i].stat_string);
+ p += ETH_GSTRING_LEN;
+ }
+ for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
+ snprintf(p, ETH_GSTRING_LEN,
+ "port.tx_priority_%u_xon", i);
+ p += ETH_GSTRING_LEN;
+ snprintf(p, ETH_GSTRING_LEN,
+ "port.tx_priority_%u_xoff", i);
+ p += ETH_GSTRING_LEN;
+ }
+ for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
+ snprintf(p, ETH_GSTRING_LEN,
+ "port.rx_priority_%u_xon", i);
+ p += ETH_GSTRING_LEN;
+ snprintf(p, ETH_GSTRING_LEN,
+ "port.rx_priority_%u_xoff", i);
+ p += ETH_GSTRING_LEN;
+ }
+ for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
+ snprintf(p, ETH_GSTRING_LEN,
+ "port.rx_priority_%u_xon_2_xoff", i);
+ p += ETH_GSTRING_LEN;
+ }
+ /* BUG_ON(p - data != I40E_STATS_LEN * ETH_GSTRING_LEN); */
+}
+
+static void i40e_get_priv_flag_strings(struct net_device *netdev, u8 *data)
+{
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
+ struct i40e_vsi *vsi = np->vsi;
+ struct i40e_pf *pf = vsi->back;
+ char *p = (char *)data;
+ unsigned int i;
+
+ for (i = 0; i < I40E_PRIV_FLAGS_STR_LEN; i++) {
+ snprintf(p, ETH_GSTRING_LEN, "%s",
+ i40e_gstrings_priv_flags[i].flag_string);
+ p += ETH_GSTRING_LEN;
+ }
+ if (pf->hw.pf_id != 0)
+ return;
+ for (i = 0; i < I40E_GL_PRIV_FLAGS_STR_LEN; i++) {
+ snprintf(p, ETH_GSTRING_LEN, "%s",
+ i40e_gl_gstrings_priv_flags[i].flag_string);
+ p += ETH_GSTRING_LEN;
+ }
+}
+
+static void i40e_get_strings(struct net_device *netdev, u32 stringset,
+ u8 *data)
+{
switch (stringset) {
case ETH_SS_TEST:
memcpy(data, i40e_gstrings_test,
I40E_TEST_LEN * ETH_GSTRING_LEN);
break;
case ETH_SS_STATS:
- for (i = 0; i < I40E_NETDEV_STATS_LEN; i++) {
- snprintf(p, ETH_GSTRING_LEN, "%s",
- i40e_gstrings_net_stats[i].stat_string);
- p += ETH_GSTRING_LEN;
- }
- for (i = 0; i < I40E_MISC_STATS_LEN; i++) {
- snprintf(p, ETH_GSTRING_LEN, "%s",
- i40e_gstrings_misc_stats[i].stat_string);
- p += ETH_GSTRING_LEN;
- }
- for (i = 0; i < I40E_MAX_NUM_QUEUES(netdev); i++) {
- snprintf(p, ETH_GSTRING_LEN, "tx-%d.tx_packets", i);
- p += ETH_GSTRING_LEN;
- snprintf(p, ETH_GSTRING_LEN, "tx-%d.tx_bytes", i);
- p += ETH_GSTRING_LEN;
- snprintf(p, ETH_GSTRING_LEN, "rx-%d.rx_packets", i);
- p += ETH_GSTRING_LEN;
- snprintf(p, ETH_GSTRING_LEN, "rx-%d.rx_bytes", i);
- p += ETH_GSTRING_LEN;
- }
- if (vsi != pf->vsi[pf->lan_vsi] || pf->hw.partition_id != 1)
- return;
-
- for (i = 0; i < I40E_VEB_STATS_LEN; i++) {
- snprintf(p, ETH_GSTRING_LEN, "veb.%s",
- i40e_gstrings_veb_stats[i].stat_string);
- p += ETH_GSTRING_LEN;
- }
- for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
- snprintf(p, ETH_GSTRING_LEN,
- "veb.tc_%u_tx_packets", i);
- p += ETH_GSTRING_LEN;
- snprintf(p, ETH_GSTRING_LEN,
- "veb.tc_%u_tx_bytes", i);
- p += ETH_GSTRING_LEN;
- snprintf(p, ETH_GSTRING_LEN,
- "veb.tc_%u_rx_packets", i);
- p += ETH_GSTRING_LEN;
- snprintf(p, ETH_GSTRING_LEN,
- "veb.tc_%u_rx_bytes", i);
- p += ETH_GSTRING_LEN;
- }
- for (i = 0; i < I40E_GLOBAL_STATS_LEN; i++) {
- snprintf(p, ETH_GSTRING_LEN, "port.%s",
- i40e_gstrings_stats[i].stat_string);
- p += ETH_GSTRING_LEN;
- }
- for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
- snprintf(p, ETH_GSTRING_LEN,
- "port.tx_priority_%d_xon", i);
- p += ETH_GSTRING_LEN;
- snprintf(p, ETH_GSTRING_LEN,
- "port.tx_priority_%d_xoff", i);
- p += ETH_GSTRING_LEN;
- }
- for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
- snprintf(p, ETH_GSTRING_LEN,
- "port.rx_priority_%d_xon", i);
- p += ETH_GSTRING_LEN;
- snprintf(p, ETH_GSTRING_LEN,
- "port.rx_priority_%d_xoff", i);
- p += ETH_GSTRING_LEN;
- }
- for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
- snprintf(p, ETH_GSTRING_LEN,
- "port.rx_priority_%d_xon_2_xoff", i);
- p += ETH_GSTRING_LEN;
- }
- /* BUG_ON(p - data != I40E_STATS_LEN * ETH_GSTRING_LEN); */
+ i40e_get_stat_strings(netdev, data);
break;
case ETH_SS_PRIV_FLAGS:
- for (i = 0; i < I40E_PRIV_FLAGS_STR_LEN; i++) {
- snprintf(p, ETH_GSTRING_LEN, "%s",
- i40e_gstrings_priv_flags[i].flag_string);
- p += ETH_GSTRING_LEN;
- }
- if (pf->hw.pf_id != 0)
- break;
- for (i = 0; i < I40E_GL_PRIV_FLAGS_STR_LEN; i++) {
- snprintf(p, ETH_GSTRING_LEN, "%s",
- i40e_gl_gstrings_priv_flags[i].flag_string);
- p += ETH_GSTRING_LEN;
- }
+ i40e_get_priv_flag_strings(netdev, data);
break;
default:
break;
--
2.17.0
^ permalink raw reply related
* [net-next 5/9] i40e: use WARN_ONCE to replace the commented BUG_ON size check
From: Jeff Kirsher @ 2018-05-22 17:45 UTC (permalink / raw)
To: davem; +Cc: Jacob Keller, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <20180522174527.19680-1-jeffrey.t.kirsher@intel.com>
From: Jacob Keller <jacob.e.keller@intel.com>
We don't really want to use BUG_ON here since that would completely
crash the kernel, thus the reason we commented it out. We *can't* use
BUILD_BUG_ON because at least now (a) the sizes aren't constant (we are
fixing this) and (b) not all compilers are smart enough to understand
that "p - data" is a constant.
Instead, just use a WARN_ONCE so that the first time we end up with an
incorrect size we will dump a stack trace and a message, hopefully
highlighting the issues early in testing.
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>
---
drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index c50ed2d391e1..32bcb6a2a590 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -1792,8 +1792,8 @@ static void i40e_get_stat_strings(struct net_device *netdev, u8 *data)
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_vsi *vsi = np->vsi;
struct i40e_pf *pf = vsi->back;
- char *p = (char *)data;
unsigned int i;
+ u8 *p = data;
for (i = 0; i < I40E_NETDEV_STATS_LEN; i++) {
snprintf(p, ETH_GSTRING_LEN, "%s",
@@ -1864,7 +1864,9 @@ static void i40e_get_stat_strings(struct net_device *netdev, u8 *data)
"port.rx_priority_%u_xon_2_xoff", i);
p += ETH_GSTRING_LEN;
}
- /* BUG_ON(p - data != I40E_STATS_LEN * ETH_GSTRING_LEN); */
+
+ WARN_ONCE(p - data != i40e_get_stats_count(netdev) * ETH_GSTRING_LEN,
+ "stat strings count mismatch!");
}
static void i40e_get_priv_flag_strings(struct net_device *netdev, u8 *data)
--
2.17.0
^ permalink raw reply related
* [net-next 8/9] i40e: add function doc headers for ethtool stats functions
From: Jeff Kirsher @ 2018-05-22 17:45 UTC (permalink / raw)
To: davem; +Cc: Jacob Keller, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <20180522174527.19680-1-jeffrey.t.kirsher@intel.com>
From: Jacob Keller <jacob.e.keller@intel.com>
Add documentation for the i40e_get_stats_count, i40e_get_stat_strings
and i40e_get_ethtool_stats explaining that the number and ordering of
statistics must remain constant for a given netdevice.
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>
---
.../net/ethernet/intel/i40e/i40e_ethtool.c | 38 +++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index 44a2803cb1ec..4b5ecba0148c 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -1660,6 +1660,20 @@ static int i40e_set_ringparam(struct net_device *netdev,
return err;
}
+/**
+ * i40e_get_stats_count - return the stats count for a device
+ * @netdev: the netdev to return the count for
+ *
+ * Returns the total number of statistics for this netdev. Note that even
+ * though this is a function, it is required that the count for a specific
+ * netdev must never change. Basing the count on static values such as the
+ * maximum number of queues or the device type is ok. However, the API for
+ * obtaining stats is *not* safe against changes based on non-static
+ * values such as the *current* number of queues, or runtime flags.
+ *
+ * If a statistic is not always enabled, return it as part of the count
+ * anyways, always return its string, and report its value as zero.
+ **/
static int i40e_get_stats_count(struct net_device *netdev)
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
@@ -1691,6 +1705,20 @@ static int i40e_get_sset_count(struct net_device *netdev, int sset)
}
}
+/**
+ * i40e_get_ethtool_stats - copy stat values into supplied buffer
+ * @netdev: the netdev to collect stats for
+ * @stats: ethtool stats command structure
+ * @data: ethtool supplied buffer
+ *
+ * Copy the stats values for this netdev into the buffer. Expects data to be
+ * pre-allocated to the size returned by i40e_get_stats_count.. Note that all
+ * statistics must be copied in a static order, and the count must not change
+ * for a given netdev. See i40e_get_stats_count for more details.
+ *
+ * If a statistic is not currently valid (such as a disabled queue), this
+ * function reports its value as zero.
+ **/
static void i40e_get_ethtool_stats(struct net_device *netdev,
struct ethtool_stats *stats, u64 *data)
{
@@ -1787,6 +1815,16 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
*(data++) = pf->stats.priority_xon_2_xoff[j];
}
+/**
+ * i40e_get_stat_strings - copy stat strings into supplied buffer
+ * @netdev: the netdev to collect strings for
+ * @data: supplied buffer to copy strings into
+ *
+ * Copy the strings related to stats for this netdev. Expects data to be
+ * pre-allocated with the size reported by i40e_get_stats_count. Note that the
+ * strings must be copied in a static order and the total count must not
+ * change for a given netdev. See i40e_get_stats_count for more details.
+ **/
static void i40e_get_stat_strings(struct net_device *netdev, u8 *data)
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
--
2.17.0
^ permalink raw reply related
* [net-next 9/9] i40e: use the more traditional 'i' loop variable
From: Jeff Kirsher @ 2018-05-22 17:45 UTC (permalink / raw)
To: davem; +Cc: Jacob Keller, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <20180522174527.19680-1-jeffrey.t.kirsher@intel.com>
From: Jacob Keller <jacob.e.keller@intel.com>
Since we no longer use i as an array index for the data variable,
replace the use of 'j' with 'i' so that we match the general loop
variable name.
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>
---
.../net/ethernet/intel/i40e/i40e_ethtool.c | 56 +++++++++----------
1 file changed, 28 insertions(+), 28 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index 4b5ecba0148c..6947a2a571cb 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -1726,26 +1726,26 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
struct i40e_ring *tx_ring, *rx_ring;
struct i40e_vsi *vsi = np->vsi;
struct i40e_pf *pf = vsi->back;
- unsigned int j;
+ unsigned int i;
char *p;
struct rtnl_link_stats64 *net_stats = i40e_get_vsi_stats_struct(vsi);
unsigned int start;
i40e_update_stats(vsi);
- for (j = 0; j < I40E_NETDEV_STATS_LEN; j++) {
- p = (char *)net_stats + i40e_gstrings_net_stats[j].stat_offset;
- *(data++) = (i40e_gstrings_net_stats[j].sizeof_stat ==
+ for (i = 0; i < I40E_NETDEV_STATS_LEN; i++) {
+ p = (char *)net_stats + i40e_gstrings_net_stats[i].stat_offset;
+ *(data++) = (i40e_gstrings_net_stats[i].sizeof_stat ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
- for (j = 0; j < I40E_MISC_STATS_LEN; j++) {
- p = (char *)vsi + i40e_gstrings_misc_stats[j].stat_offset;
- *(data++) = (i40e_gstrings_misc_stats[j].sizeof_stat ==
+ for (i = 0; i < I40E_MISC_STATS_LEN; i++) {
+ p = (char *)vsi + i40e_gstrings_misc_stats[i].stat_offset;
+ *(data++) = (i40e_gstrings_misc_stats[i].sizeof_stat ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
rcu_read_lock();
- for (j = 0; j < I40E_MAX_NUM_QUEUES(netdev) ; j++) {
- tx_ring = READ_ONCE(vsi->tx_rings[j]);
+ for (i = 0; i < I40E_MAX_NUM_QUEUES(netdev) ; i++) {
+ tx_ring = READ_ONCE(vsi->tx_rings[i]);
if (!tx_ring) {
/* Bump the stat counter to skip these stats, and make
@@ -1783,36 +1783,36 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
(pf->flags & I40E_FLAG_VEB_STATS_ENABLED)) {
struct i40e_veb *veb = pf->veb[pf->lan_veb];
- for (j = 0; j < I40E_VEB_STATS_LEN; j++) {
+ for (i = 0; i < I40E_VEB_STATS_LEN; i++) {
p = (char *)veb;
- p += i40e_gstrings_veb_stats[j].stat_offset;
- *(data++) = (i40e_gstrings_veb_stats[j].sizeof_stat ==
+ p += i40e_gstrings_veb_stats[i].stat_offset;
+ *(data++) = (i40e_gstrings_veb_stats[i].sizeof_stat ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
- for (j = 0; j < I40E_MAX_TRAFFIC_CLASS; j++) {
- *(data++) = veb->tc_stats.tc_tx_packets[j];
- *(data++) = veb->tc_stats.tc_tx_bytes[j];
- *(data++) = veb->tc_stats.tc_rx_packets[j];
- *(data++) = veb->tc_stats.tc_rx_bytes[j];
+ for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
+ *(data++) = veb->tc_stats.tc_tx_packets[i];
+ *(data++) = veb->tc_stats.tc_tx_bytes[i];
+ *(data++) = veb->tc_stats.tc_rx_packets[i];
+ *(data++) = veb->tc_stats.tc_rx_bytes[i];
}
} else {
data += I40E_VEB_STATS_TOTAL;
}
- for (j = 0; j < I40E_GLOBAL_STATS_LEN; j++) {
- p = (char *)pf + i40e_gstrings_stats[j].stat_offset;
- *(data++) = (i40e_gstrings_stats[j].sizeof_stat ==
+ for (i = 0; i < I40E_GLOBAL_STATS_LEN; i++) {
+ p = (char *)pf + i40e_gstrings_stats[i].stat_offset;
+ *(data++) = (i40e_gstrings_stats[i].sizeof_stat ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
- for (j = 0; j < I40E_MAX_USER_PRIORITY; j++) {
- *(data++) = pf->stats.priority_xon_tx[j];
- *(data++) = pf->stats.priority_xoff_tx[j];
+ for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
+ *(data++) = pf->stats.priority_xon_tx[i];
+ *(data++) = pf->stats.priority_xoff_tx[i];
}
- for (j = 0; j < I40E_MAX_USER_PRIORITY; j++) {
- *(data++) = pf->stats.priority_xon_rx[j];
- *(data++) = pf->stats.priority_xoff_rx[j];
+ for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
+ *(data++) = pf->stats.priority_xon_rx[i];
+ *(data++) = pf->stats.priority_xoff_rx[i];
}
- for (j = 0; j < I40E_MAX_USER_PRIORITY; j++)
- *(data++) = pf->stats.priority_xon_2_xoff[j];
+ for (i = 0; i < I40E_MAX_USER_PRIORITY; i++)
+ *(data++) = pf->stats.priority_xon_2_xoff[i];
}
/**
--
2.17.0
^ permalink raw reply related
* Re: [PATCH 1/2] net: fec: ptp: Switch to SPDX identifier
From: David Miller @ 2018-05-22 17:45 UTC (permalink / raw)
To: festevam; +Cc: fugang.duan, netdev, fabio.estevam
In-Reply-To: <1526835319-17408-1-git-send-email-festevam@gmail.com>
From: Fabio Estevam <festevam@gmail.com>
Date: Sun, 20 May 2018 13:55:18 -0300
> From: Fabio Estevam <fabio.estevam@nxp.com>
>
> Adopt the SPDX license identifier headers to ease license compliance
> management.
>
> Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com>
Applied.
^ permalink raw reply
* Re: [PATCH 2/2] net: fec: Add a SPDX identifier
From: David Miller @ 2018-05-22 17:45 UTC (permalink / raw)
To: festevam; +Cc: fugang.duan, netdev, fabio.estevam
In-Reply-To: <1526835319-17408-2-git-send-email-festevam@gmail.com>
From: Fabio Estevam <festevam@gmail.com>
Date: Sun, 20 May 2018 13:55:19 -0300
> From: Fabio Estevam <fabio.estevam@nxp.com>
>
> Currently there is no license information in the header of
> this file.
>
> The MODULE_LICENSE field contains ("GPL"), which means
> GNU Public License v2 or later, so add a corresponding
> SPDX license identifier.
>
> Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com>
Applied.
^ permalink raw reply
* Re: [PATCH v3] isdn: eicon: fix a missing-check bug
From: David Miller @ 2018-05-22 17:52 UTC (permalink / raw)
To: wang6495; +Cc: kjlu, mac, isdn, netdev, linux-kernel
In-Reply-To: <1526885887-9759-1-git-send-email-wang6495@umn.edu>
From: Wenwen Wang <wang6495@umn.edu>
Date: Mon, 21 May 2018 01:58:07 -0500
> In divasmain.c, the function divas_write() firstly invokes the function
> diva_xdi_open_adapter() to open the adapter that matches with the adapter
> number provided by the user, and then invokes the function diva_xdi_write()
> to perform the write operation using the matched adapter. The two functions
> diva_xdi_open_adapter() and diva_xdi_write() are located in diva.c.
>
> In diva_xdi_open_adapter(), the user command is copied to the object 'msg'
> from the userspace pointer 'src' through the function pointer 'cp_fn',
> which eventually calls copy_from_user() to do the copy. Then, the adapter
> number 'msg.adapter' is used to find out a matched adapter from the
> 'adapter_queue'. A matched adapter will be returned if it is found.
> Otherwise, NULL is returned to indicate the failure of the verification on
> the adapter number.
>
> As mentioned above, if a matched adapter is returned, the function
> diva_xdi_write() is invoked to perform the write operation. In this
> function, the user command is copied once again from the userspace pointer
> 'src', which is the same as the 'src' pointer in diva_xdi_open_adapter() as
> both of them are from the 'buf' pointer in divas_write(). Similarly, the
> copy is achieved through the function pointer 'cp_fn', which finally calls
> copy_from_user(). After the successful copy, the corresponding command
> processing handler of the matched adapter is invoked to perform the write
> operation.
>
> It is obvious that there are two copies here from userspace, one is in
> diva_xdi_open_adapter(), and one is in diva_xdi_write(). Plus, both of
> these two copies share the same source userspace pointer, i.e., the 'buf'
> pointer in divas_write(). Given that a malicious userspace process can race
> to change the content pointed by the 'buf' pointer, this can pose potential
> security issues. For example, in the first copy, the user provides a valid
> adapter number to pass the verification process and a valid adapter can be
> found. Then the user can modify the adapter number to an invalid number.
> This way, the user can bypass the verification process of the adapter
> number and inject inconsistent data.
>
> This patch reuses the data copied in
> diva_xdi_open_adapter() and passes it to diva_xdi_write(). This way, the
> above issues can be avoided.
>
> Signed-off-by: Wenwen Wang <wang6495@umn.edu>
Applied and queued up for -stable.
^ permalink raw reply
* Re: [PATCH net] dccp: don't free ccid2_hc_tx_sock struct in dccp_disconnect()
From: David Miller @ 2018-05-22 17:55 UTC (permalink / raw)
To: alexey.kodanev; +Cc: netdev
In-Reply-To: <1526920124-6103-1-git-send-email-alexey.kodanev@oracle.com>
From: Alexey Kodanev <alexey.kodanev@oracle.com>
Date: Mon, 21 May 2018 19:28:44 +0300
> Syzbot reported the use-after-free in timer_is_static_object() [1].
>
> This can happen because the structure for the rto timer (ccid2_hc_tx_sock)
> is removed in dccp_disconnect(), and ccid2_hc_tx_rto_expire() can be
> called after that.
>
> The report [1] is similar to the one in commit 120e9dabaf55 ("dccp:
> defer ccid_hc_tx_delete() at dismantle time"). And the fix is the same,
> delay freeing ccid2_hc_tx_sock structure, so that it is freed in
> dccp_sk_destruct().
...
> Reported-by: syzbot+5d47e9ec91a6f15dbd6f@syzkaller.appspotmail.com
> Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
Applied and queued up for -stable, thanks.
^ permalink raw reply
* Re: [PATCH net-next] r8169: perform reset synchronously in __rtl8169_resume
From: David Miller @ 2018-05-22 17:59 UTC (permalink / raw)
To: hkallweit1; +Cc: nic_swsd, netdev
In-Reply-To: <040eb6ae-bb21-2d27-14e0-b291cb4cc1c9@gmail.com>
From: Heiner Kallweit <hkallweit1@gmail.com>
Date: Mon, 21 May 2018 19:01:19 +0200
> The driver uses pm_runtime_get_sync() in few places and relies on the
> device being fully runtime-resumed after this call. So far however
> the runtime resume callback triggers an asynchronous reset.
> Avoid this and perform the reset synchronously.
>
> Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
> ---
> drivers/net/ethernet/realtek/r8169.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
> index 75dfac024..1eb4f625a 100644
> --- a/drivers/net/ethernet/realtek/r8169.c
> +++ b/drivers/net/ethernet/realtek/r8169.c
> @@ -7327,9 +7327,9 @@ static void __rtl8169_resume(struct net_device *dev)
> rtl_lock_work(tp);
> napi_enable(&tp->napi);
> set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags);
> + if (netif_running(dev))
> + rtl_reset_work(tp);
> rtl_unlock_work(tp);
> -
> - rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING);
> }
>
Given what we know about ->ndo_open() and the checks by the callers of
__rtl8169_resume(), the netif_running() test seems superfluous or
wrong.
Either way you need to resolve this somehow.
^ permalink raw reply
* Regression: Approximate 34% performance hit in receive throughput over ixgbe seen due to build_skb patch
From: William Kucharski @ 2018-05-22 18:00 UTC (permalink / raw)
To: linux-kernel, netdev, intel-wired-lan, Jeff Kirsher; +Cc: alexander.h.duyck
A performance hit of approximately 34% in receive numbers for some packet sizes is
seen when testing traffic over ixgbe links using the network test netperf.
Starting with the top of tree commit 7addb3e4ad3db6a95a953c59884921b5883dcdec,
a git bisect narrowed the issue down to:
commit 6f429223b31c550b835b4f066ac034d0cf0cc71e
ixgbe: Add support for build_skb
This patch adds build_skb support to the Rx path. There are several
advantages to this change.
1. It avoids the memcpy and skb->head allocation for small packets which
improves performance by about 5% in my tests.
2. It avoids the memcpy, skb->head allocation, and eth_get_headlen
for larger packets improving performance by about 10% in my tests.
3. For VXLAN packets it allows the full header to be in skb->data which
improves the performance by as much as 30% in some of my tests.
Netperf was sourced from:
https://hewlettpackard.github.io/netperf/
Two machines were directly connected via ixgbe links.
The process "netserver" was started on 10.196.11.8, and running this test:
# netperf -l 60 -H 10.196.11.8 -i 10,2 -I 99,10 -t UDP_STREAM -- -m 64 -s 32768 -S 32768
showed that on machines without the patch, we typically see performance
like:
Socket Message Elapsed Messages
Size Size Time Okay Errors Throughput
bytes bytes secs # # 10^6bits/sec
65536 64 60.00 35435847 0 302.38 <-- SEND
65536 60.00 35391087 302.00 <-- RECEIVE
or
Socket Message Elapsed Messages
Size Size Time Okay Errors Throughput
bytes bytes secs # # 10^6bits/sec
65536 64 60.00 33708816 0 287.65
65536 60.00 33706010 287.62
However, on machines with the patch, receive performance is seen to fall by an
average of 34%, e.g.:
Socket Message Elapsed Messages
Size Size Time Okay Errors Throughput
bytes bytes secs # # 10^6bits/sec
65536 64 60.00 35179881 0 300.20
65536 60.00 21418471 182.77
or
Socket Message Elapsed Messages
Size Size Time Okay Errors Throughput
bytes bytes secs # # 10^6bits/sec
65536 64 60.00 36937716 0 315.20
65536 60.00 16838656 143.69
William Kucharski
william.kucharski@oracle.com
^ permalink raw reply
* Re: [PATCH bpf-next 1/5] bpf: Hooks for sys_sendmsg
From: Andrey Ignatov @ 2018-05-22 18:04 UTC (permalink / raw)
To: Martin KaFai Lau; +Cc: netdev, davem, ast, daniel, kernel-team
In-Reply-To: <20180521231647.2ypehnbvrn5mitep@kafai-mbp.dhcp.thefacebook.com>
Martin KaFai Lau <kafai@fb.com> [Mon, 2018-05-21 16:17 -0700]:
> On Fri, May 18, 2018 at 07:21:09PM -0700, Andrey Ignatov wrote:
[...]
> > diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
> > index 2839c1b..6f580ea 100644
> > --- a/net/ipv6/udp.c
> > +++ b/net/ipv6/udp.c
> > @@ -1315,6 +1315,22 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
> > fl6.saddr = np->saddr;
> > fl6.fl6_sport = inet->inet_sport;
> >
> > + if (!connected) {
> > + err = BPF_CGROUP_RUN_PROG_UDP6_SENDMSG_LOCK(sk,
> > + (struct sockaddr *)sin6, &fl6.saddr);
> > + if (err)
> > + goto out_no_dst;
> > + if (sin6) {
> > + if (sin6->sin6_port == 0) {
> > + /* BPF program set invalid port. Reject it. */
> > + err = -EINVAL;
> > + goto out_no_dst;
> > + }
> > + fl6.fl6_dport = sin6->sin6_port;
> > + fl6.daddr = sin6->sin6_addr;
> Could the bpf_prog change sin6 to a v4mapped address?
It's a good point.
Yes, bpf_prog can rewrite sin6->sin6_addr with any IPv6 address,
including IPv4-mapped IPv6 and this is not handled in this patch.
I see two possible options to handle this:
1) Return with error similar to how it's done for (sin6_port == 0).
2) Or delegate to udp_sendmsg() similar to how it's done in the
beginning of udpv6_sendmsg().
By this point udpv6_sendmsg already checked that destination is not
IPv4-mapped IPv6. And I think it might not be a good idea to rewrite
IPv6-only address with IPv4-mapped IPv6 in bpf_prog.
So IMO "1)" is safer since user passed IPv6-only destination
(IPv4-mapped IPv6 passed by user don't reach this point) and both
msg->msg_name and msg->msg_control may have IPv6-only fields, e.g.
sin6_flowinfo in msg->msg_name or SOL_IPV6 options in msg->msg_control.
Also a few steps were already done based on this by that time, e.g.
ancillary data, if present, was already parsed successfully by
ip6_datagram_send_ctl().
As for specific errno, ENOTSUPP can be returned for now so that in the
future there is a way to extend this code to support IPv4-mapped IPv6 if
needed.
I'll send v2 with this change.
> > + }
> > + }
> > +
> > final_p = fl6_update_dst(&fl6, opt, &final);
> It seems fl6_update_dst() may update fl6->daddr.
> Is it fine (or inline with the expectation after running
> a bpf_prog that has changed user_ip6)?
Yeah, I checked this code and from what I see it should be fine.
If fl6_update_dst updates fl6->daddr, then it returns original daddr
(e.g. that set by bpf_prog) as final_p. Later udpv6_sendmsg calls
ip6_sk_dst_lookup_flow where the new daddr is used to lookup flow and it
is set back to final_p in ip6_dst_lookup_flow:
if (final_dst)
fl6->daddr = *final_dst;
So final value of fl6->daddr will be daddr set by bpf_prog.
> > if (final_p)
> > connected = false;
> > @@ -1394,6 +1410,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
> >
> > out:
> > dst_release(dst);
> > +out_no_dst:
> A nit. If dst is init to NULL, can a new exit label
> be avoided?
Yes, if dst was init to NULL, new label could be avoided. But it's not
initialized when created. It can probably be changed, but I'd need to
check all dst usages to make sure that it's fine to remove `dst = NULL`
from other places. Maybe in another patch.
> > fl6_sock_release(flowlabel);
> > txopt_put(opt_to_free);
> > if (!err)
> > --
> > 2.9.5
> >
--
Andrey Ignatov
^ permalink raw reply
* Re: Regression: Approximate 34% performance hit in receive throughput over ixgbe seen due to build_skb patch
From: Alexander Duyck @ 2018-05-22 18:23 UTC (permalink / raw)
To: William Kucharski
Cc: LKML, Netdev, intel-wired-lan, Jeff Kirsher, Duyck, Alexander H
In-Reply-To: <A940030A-CDBF-41CD-816F-0BBC76E7C4F4@oracle.com>
On Tue, May 22, 2018 at 11:00 AM, William Kucharski
<william.kucharski@oracle.com> wrote:
> A performance hit of approximately 34% in receive numbers for some packet sizes is
> seen when testing traffic over ixgbe links using the network test netperf.
>
> Starting with the top of tree commit 7addb3e4ad3db6a95a953c59884921b5883dcdec,
> a git bisect narrowed the issue down to:
>
> commit 6f429223b31c550b835b4f066ac034d0cf0cc71e
>
> ixgbe: Add support for build_skb
>
> This patch adds build_skb support to the Rx path. There are several
> advantages to this change.
>
> 1. It avoids the memcpy and skb->head allocation for small packets which
> improves performance by about 5% in my tests.
> 2. It avoids the memcpy, skb->head allocation, and eth_get_headlen
> for larger packets improving performance by about 10% in my tests.
> 3. For VXLAN packets it allows the full header to be in skb->data which
> improves the performance by as much as 30% in some of my tests.
>
> Netperf was sourced from:
>
> https://hewlettpackard.github.io/netperf/
>
> Two machines were directly connected via ixgbe links.
>
> The process "netserver" was started on 10.196.11.8, and running this test:
>
> # netperf -l 60 -H 10.196.11.8 -i 10,2 -I 99,10 -t UDP_STREAM -- -m 64 -s 32768 -S 32768
Okay, so I can already see what the most likely issue is. The
build_skb code is more CPU efficient, but it will consume more memory
in the process since it is avoiding the memcpy and is instead using a
full 2K block of memory for a small frame. I'm suspecting any
performance issue you are seeing may be due to a slow interrupt rate
causing us to either exhaust available Tx memory, or overrun the
available Rx memory.
There end up being multiple ways to address this.
1. Use a larger value for your "-s/-S" values to allow for more memory
to be handled in the queues.
2. Update the interrupt moderation code for the driver. You can either
manually decrease the per-interrupt delay via "ethtool -C" or just
update the adaptive ITR code, see commit b4ded8327fea ("ixgbe: Update
adaptive ITR algorithm").
3. There should be a private flag that can be updated via "ethtool
--set-priv-flags" called "legacy-rx" that you can enable that will
roll back to the original that did the copy-break type approach for
small packets and the headers of the frame.
Thanks.
- Alex
^ permalink raw reply
* [PATCH net-next] hv_netvsc: Add handlers for ethtool get/set msg level
From: Haiyang Zhang @ 2018-05-22 18:29 UTC (permalink / raw)
To: davem, netdev; +Cc: olaf, sthemmin, haiyangz, linux-kernel, devel, vkuznets
From: Haiyang Zhang <haiyangz@microsoft.com>
The handlers for ethtool get/set msg level are missing from netvsc.
This patch adds them.
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
drivers/net/hyperv/netvsc_drv.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index da07ccdf84bf..60a5769ef5a1 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -1618,8 +1618,24 @@ static int netvsc_set_ringparam(struct net_device *ndev,
return ret;
}
+static u32 netvsc_get_msglevel(struct net_device *ndev)
+{
+ struct net_device_context *ndev_ctx = netdev_priv(ndev);
+
+ return ndev_ctx->msg_enable;
+}
+
+static void netvsc_set_msglevel(struct net_device *ndev, u32 val)
+{
+ struct net_device_context *ndev_ctx = netdev_priv(ndev);
+
+ ndev_ctx->msg_enable = val;
+}
+
static const struct ethtool_ops ethtool_ops = {
.get_drvinfo = netvsc_get_drvinfo,
+ .get_msglevel = netvsc_get_msglevel,
+ .set_msglevel = netvsc_set_msglevel,
.get_link = ethtool_op_get_link,
.get_ethtool_stats = netvsc_get_ethtool_stats,
.get_sset_count = netvsc_get_sset_count,
--
2.17.0
^ permalink raw reply related
* Re: [net-next 1/6] net/dcb: Add dcbnl buffer attribute
From: Jakub Kicinski @ 2018-05-22 18:32 UTC (permalink / raw)
To: Huy Nguyen
Cc: Saeed Mahameed, David S. Miller, netdev, Jiri Pirko, Or Gerlitz,
Parav Pandit
In-Reply-To: <5b0d2137-8c70-ceb4-6965-fef2c75c4c24@mellanox.com>
On Tue, 22 May 2018 10:36:17 -0500, Huy Nguyen wrote:
> On 5/22/2018 12:20 AM, Jakub Kicinski wrote:
> > On Mon, 21 May 2018 14:04:57 -0700, Saeed Mahameed wrote:
> >> From: Huy Nguyen <huyn@mellanox.com>
> >>
> >> In this patch, we add dcbnl buffer attribute to allow user
> >> change the NIC's buffer configuration such as priority
> >> to buffer mapping and buffer size of individual buffer.
> >>
> >> This attribute combined with pfc attribute allows advance user to
> >> fine tune the qos setting for specific priority queue. For example,
> >> user can give dedicated buffer for one or more prirorities or user
> >> can give large buffer to certain priorities.
> >>
> >> We present an use case scenario where dcbnl buffer attribute configured
> >> by advance user helps reduce the latency of messages of different sizes.
> >>
> >> Scenarios description:
> >> On ConnectX-5, we run latency sensitive traffic with
> >> small/medium message sizes ranging from 64B to 256KB and bandwidth sensitive
> >> traffic with large messages sizes 512KB and 1MB. We group small, medium,
> >> and large message sizes to their own pfc enables priorities as follow.
> >> Priorities 1 & 2 (64B, 256B and 1KB)
> >> Priorities 3 & 4 (4KB, 8KB, 16KB, 64KB, 128KB and 256KB)
> >> Priorities 5 & 6 (512KB and 1MB)
> >>
> >> By default, ConnectX-5 maps all pfc enabled priorities to a single
> >> lossless fixed buffer size of 50% of total available buffer space. The
> >> other 50% is assigned to lossy buffer. Using dcbnl buffer attribute,
> >> we create three equal size lossless buffers. Each buffer has 25% of total
> >> available buffer space. Thus, the lossy buffer size reduces to 25%. Priority
> >> to lossless buffer mappings are set as follow.
> >> Priorities 1 & 2 on lossless buffer #1
> >> Priorities 3 & 4 on lossless buffer #2
> >> Priorities 5 & 6 on lossless buffer #3
> >>
> >> We observe improvements in latency for small and medium message sizes
> >> as follows. Please note that the large message sizes bandwidth performance is
> >> reduced but the total bandwidth remains the same.
> >> 256B message size (42 % latency reduction)
> >> 4K message size (21% latency reduction)
> >> 64K message size (16% latency reduction)
> >>
> >> Signed-off-by: Huy Nguyen <huyn@mellanox.com>
> >> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
> > On a cursory look this bares a lot of resemblance to devlink shared
> > buffer configuration ABI. Did you look into using that?
> >
> > Just to be clear devlink shared buffer ABIs don't require representors
> > and "switchdev mode".
> > .
> [HQN] Dear Jakub, there are several reasons that devlink shared buffer
> ABI cannot be used:
> 1. The devlink shared buffer ABI is written based on the switch cli
> which you can find out more
> from this link https://community.mellanox.com/docs/DOC-2558.
Devlink API accommodates requirements of simpler (SwitchX2?) and more
advanced schemes (present in Spectrum). The simpler/basic static
threshold configurations is exactly what you are doing here, AFAIU.
> 2. The dcbnl interfaces have been used for QoS settings.
QoS settings != shared buffer configuration.
> In NIC, the buffer configuration are tied to priority (ETS PFC).
Some customers use DCB, a lot (most?) of them don't. I don't think the
"this is a logical extension of a commonly used API" really stands here.
> The buffer configuration are not tied to port like switch.
It's tied to a port and TCs, you just have one port but still have 8
TCs exactly like a switch...
> 3. Shared buffer, alpha, threshold are switch specific terms.
IDK how talking about alpha is relevant, it's just one threshold type
the API supports. As far as shared buffer and threshold I don't know
if these are switch terms (or how "switch" differs from "NIC" at that
level) - I personally find carving shared buffer into pools very
intuitive.
Could you give examples of commands/configs one can use with your new
ABI? How does one query the total size of the buffer to be carved?
^ permalink raw reply
* Re: [PATCH net-next 0/7] net/ipv6: Fix route append and replace use cases
From: David Miller @ 2018-05-22 18:46 UTC (permalink / raw)
To: dsahern; +Cc: netdev, Thomas.Winter, idosch, sharpd, roopa, dsahern
In-Reply-To: <20180521172658.7389-1-dsahern@kernel.org>
From: dsahern@kernel.org
Date: Mon, 21 May 2018 10:26:51 -0700
> This patch set fixes a few append and replace uses cases for IPv6
> and adds test cases that codifies the expectations of how append and
> replace are expected to work. In paricular it allows a multipath
> route to have a dev-only nexthop, something Thomas tried to
> accomplish with commit edd7ceb78296 ("ipv6: Allow non-gateway ECMP
> for IPv6") which had to be reverted because of breakage, and to
> replace an existing FIB entry with a reject route.
Ok, I'll apply this series.
But if this breaks things for anyone in a practical way, I am unfortunately
going to have to revert no matter how silly the current behavior may be.
Thanks!
^ permalink raw reply
* Re: [pull request][for-next 00/15] Mellanox, mlx5 core and netdev updates 2018-05-17
From: Doug Ledford @ 2018-05-22 18:48 UTC (permalink / raw)
To: Saeed Mahameed, davem@davemloft.net
Cc: Jason Gunthorpe, netdev@vger.kernel.org, Leon Romanovsky,
linux-rdma@vger.kernel.org, Or Gerlitz
In-Reply-To: <feff55e081cc69a774de885ec9df0ac844a4e098.camel@mellanox.com>
[-- Attachment #1: Type: text/plain, Size: 2789 bytes --]
On Fri, 2018-05-18 at 20:33 +0000, Saeed Mahameed wrote:
> On Fri, 2018-05-18 at 13:03 -0400, David Miller wrote:
> > From: Saeed Mahameed <saeedm@mellanox.com>
> > Date: Thu, 17 May 2018 18:22:43 -0700
> >
> > > Below you can find two pull requests,
> > >
> > > 1. mlx5 core updates to be shared for both netdev and RDMA,
> > > (patches 1..9)
> > > which is based on the last mlx5-next pull request
> > >
> > > The following changes since commit
> > > a8408f4e6db775e245f20edf12b13fd58cc03a1c:
> > >
> > > net/mlx5: fix spelling mistake: "modfiy" -> "modify" (2018-05-04
> > > 12:11:51 -0700)
> > >
> > > are available in the Git repository at:
> > >
> > > git://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux.git
> > > tags/mlx5-updates-2018-05-17
> > >
> > > for you to fetch changes up to
> > > 10ff5359f883412728ba816046ee3a696625ca02:
> > >
> > > net/mlx5e: Explicitly set source e-switch in offloaded TC rules
> > > (2018-05-17 14:17:35 -0700)
> > >
> > > 2. mlx5e netdev updates only for net-next branch (patches 10..15)
> > > based on net-next
> > > and the above pull request.
> > >
> > > The following changes since commit
> > > 538e2de104cfb4ef1acb35af42427bff42adbe4d:
> > >
> > > Merge branch 'net-Allow-more-drivers-with-COMPILE_TEST' (2018-05-
> > > 17 17:11:07 -0400)
> > >
> > > are available in the Git repository at:
> > >
> > > git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux.git
> > > tags/mlx5e-updates-2018-05-17
> > >
> > > for you to fetch changes up to
> > > a228060a7c9ab88597eeac131e4578595d5d46ae:
> > >
> > > net/mlx5e: Add HW vport counters to representor ethtool stats
> > > (2018-05-17 17:48:54 -0700)
> > >
> > > Dave, for your convenience you can either pull 1. and then 2. or
> > > pull 2.
> > > directly.
> >
> > Looks good.
> >
> > I pulled 1 then I pulled 2. That seemed to work well. Particularly
> > it allowed me to capture the two different merge commit messages one
> > by one.
> >
> > Is this basically how you want to handle things moving forward?
> >
>
> Thanks Dave !
> Basically yes, we want to avoid sending netdev related patches to rdma,
> and vice versa.
> Unlike the previous "shared code" procedure, this is a more natural way
> to do things, since the mlx5 core is a shared arena, we want to
> maintain it separate from netdev and rdma.
>
> Before, Leon and I needed to sync before each release and create a
> "shared code" pull requests that includes everything (core/rdma/netdev)
> that was conflicting in the core arena.
I've pulled tag #1. Thanks.
--
Doug Ledford <dledford@redhat.com>
GPG KeyID: B826A3330E572FDD
Key fingerprint = AE6B 1BDA 122B 23B4 265B 1274 B826 A333 0E57 2FDD
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [RFC PATCH ghak32 V2 13/13] debug audit: read container ID of a process
From: Paul Moore @ 2018-05-22 18:59 UTC (permalink / raw)
To: Richard Guy Briggs
Cc: cgroups-u79uwXL29TY76Z2rM5mHXA, luto-DgEjT+Ai2ygdnm+yROfE0A,
jlayton-H+wXaHxf7aLQT0dZR+AlfA, carlos-H+wXaHxf7aLQT0dZR+AlfA,
linux-api-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
dhowells-H+wXaHxf7aLQT0dZR+AlfA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA, Eric W. Biederman,
simo-H+wXaHxf7aLQT0dZR+AlfA, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA, Eric Paris, Steve Grubb,
viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn
In-Reply-To: <20180522173541.slcdszumi7q6c4id-bcJWsdo4jJjeVoXN4CMphl7TgLCtbB0G@public.gmane.org>
On Tue, May 22, 2018 at 1:35 PM, Richard Guy Briggs <rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> On 2018-05-21 16:06, Paul Moore wrote:
>> On Mon, May 21, 2018 at 3:19 PM, Eric W. Biederman <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org> wrote:
>> > Steve Grubb <sgrubb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> writes:
>> >> On Friday, March 16, 2018 5:00:40 AM EDT Richard Guy Briggs wrote:
>> >>> Add support for reading the container ID from the proc filesystem.
>> >>
>> >> I think this could be useful in general. Please consider this to be part of
>> >> the full patch set and not something merely used to debug the patches.
>> >
>> > Only with an audit specific name.
>> >
>> > As it is:
>> >
>> > Nacked-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
>> >
>> > The truth is the containerid name really stinks and is quite confusing
>> > and does not imply that the label applies only to audit. And little
>> > things like this make me extremely uncofortable with it.
>>
>> It also makes the audit container ID (notice how I *always* call it
>> the *audit* container ID? that is not an accident) available for
>> userspace applications to abuse. Perhaps in the future we can look at
>> ways to make this more available to applications, but this patch is
>> not the answer.
>
> Do you have a productive suggestion?
I haven't given it much thought beyond our discussions and until we
get the basic audit container ID support in place (all the other parts
of this patchset) I doubt I'll be giving it much thought.
--
paul moore
www.paul-moore.com
^ permalink raw reply
* [PATCH v3] wcn36xx: Add support for Factory Test Mode (FTM)
From: Ramon Fried @ 2018-05-22 19:02 UTC (permalink / raw)
To: kvalo
Cc: linux-kernel, wcn36xx, linux-wireless, netdev, Eyal Ilsar,
Ramon Fried
From: Eyal Ilsar <eilsar@codeaurora.org>
Introduce infrastructure for supporting Factory Test Mode (FTM) of the
wireless LAN subsystem. In order for the user space to access the
firmware in test mode the relevant netlink channel needs to be exposed
from the kernel driver.
The above is achieved as follows:
1) Register wcn36xx driver to testmode callback from netlink
2) Add testmode callback implementation to handle incoming FTM commands
3) Add FTM command packet structure
4) Add handling for GET_BUILD_RELEASE_NUMBER (msgid=0x32A2)
5) Add generic handling for all PTT_MSG packets
Signed-off-by: Eyal Ilsar <eilsar@codeaurora.org>
Signed-off-by: Ramon Fried <ramon.fried@linaro.org>
---
v3:
* fixed kbuild warning
v2:
* check for NULL after kmalloc
* don't assign value to ret.
drivers/net/wireless/ath/wcn36xx/Makefile | 2 +
drivers/net/wireless/ath/wcn36xx/hal.h | 16 ++
drivers/net/wireless/ath/wcn36xx/main.c | 3 +
drivers/net/wireless/ath/wcn36xx/smd.c | 81 ++++++++++
drivers/net/wireless/ath/wcn36xx/smd.h | 4 +
drivers/net/wireless/ath/wcn36xx/testmode.c | 149 ++++++++++++++++++
drivers/net/wireless/ath/wcn36xx/testmode.h | 46 ++++++
drivers/net/wireless/ath/wcn36xx/testmode_i.h | 29 ++++
drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 2 +
9 files changed, 332 insertions(+)
create mode 100644 drivers/net/wireless/ath/wcn36xx/testmode.c
create mode 100644 drivers/net/wireless/ath/wcn36xx/testmode.h
create mode 100644 drivers/net/wireless/ath/wcn36xx/testmode_i.h
diff --git a/drivers/net/wireless/ath/wcn36xx/Makefile b/drivers/net/wireless/ath/wcn36xx/Makefile
index 3b09435104eb..582049f65735 100644
--- a/drivers/net/wireless/ath/wcn36xx/Makefile
+++ b/drivers/net/wireless/ath/wcn36xx/Makefile
@@ -6,3 +6,5 @@ wcn36xx-y += main.o \
smd.o \
pmc.o \
debug.o
+
+wcn36xx-$(CONFIG_NL80211_TESTMODE) += testmode.o
diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h b/drivers/net/wireless/ath/wcn36xx/hal.h
index 182963522941..8491b3cb3206 100644
--- a/drivers/net/wireless/ath/wcn36xx/hal.h
+++ b/drivers/net/wireless/ath/wcn36xx/hal.h
@@ -2230,6 +2230,22 @@ struct wcn36xx_hal_switch_channel_rsp_msg {
} __packed;
+struct wcn36xx_hal_process_ptt_msg_req_msg {
+ struct wcn36xx_hal_msg_header header;
+
+ /* Actual FTM Command body */
+ u8 ptt_msg[0];
+} __packed;
+
+struct wcn36xx_hal_process_ptt_msg_rsp_msg {
+ struct wcn36xx_hal_msg_header header;
+
+ /* FTM Command response status */
+ u32 ptt_msg_resp_status;
+ /* Actual FTM Command body */
+ u8 ptt_msg[0];
+} __packed;
+
struct update_edca_params_req_msg {
struct wcn36xx_hal_msg_header header;
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index 69d6be59d97f..ea14f87d11ff 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -26,6 +26,7 @@
#include <linux/soc/qcom/smem_state.h>
#include <linux/soc/qcom/wcnss_ctrl.h>
#include "wcn36xx.h"
+#include "testmode.h"
unsigned int wcn36xx_dbg_mask;
module_param_named(debug_mask, wcn36xx_dbg_mask, uint, 0644);
@@ -1116,6 +1117,8 @@ static const struct ieee80211_ops wcn36xx_ops = {
.sta_add = wcn36xx_sta_add,
.sta_remove = wcn36xx_sta_remove,
.ampdu_action = wcn36xx_ampdu_action,
+
+ CFG80211_TESTMODE_CMD(wcn36xx_tm_cmd)
};
static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
index 8932af5e4d8d..fb0192b7ee99 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -292,12 +292,26 @@ static void init_hal_msg(struct wcn36xx_hal_msg_header *hdr,
msg_body.header.len = sizeof(msg_body); \
} while (0) \
+#define INIT_HAL_PTT_MSG(p_msg_body, ppt_msg_len) \
+ do { \
+ memset(p_msg_body, 0, sizeof(*p_msg_body) + ppt_msg_len); \
+ p_msg_body->header.msg_type = WCN36XX_HAL_PROCESS_PTT_REQ; \
+ p_msg_body->header.msg_version = WCN36XX_HAL_MSG_VERSION0; \
+ p_msg_body->header.len = sizeof(*p_msg_body) + ppt_msg_len; \
+ } while (0)
+
#define PREPARE_HAL_BUF(send_buf, msg_body) \
do { \
memset(send_buf, 0, msg_body.header.len); \
memcpy(send_buf, &msg_body, sizeof(msg_body)); \
} while (0) \
+#define PREPARE_HAL_PTT_MSG_BUF(send_buf, p_msg_body) \
+ do { \
+ memset(send_buf, 0, p_msg_body->header.len); \
+ memcpy(send_buf, p_msg_body, p_msg_body->header.len); \
+ } while (0)
+
static int wcn36xx_smd_rsp_status_check(void *buf, size_t len)
{
struct wcn36xx_fw_msg_status_rsp *rsp;
@@ -741,6 +755,71 @@ int wcn36xx_smd_switch_channel(struct wcn36xx *wcn,
return ret;
}
+static int wcn36xx_smd_process_ptt_msg_rsp(void *buf, size_t len,
+ void **p_ptt_rsp_msg)
+{
+ struct wcn36xx_hal_process_ptt_msg_rsp_msg *rsp;
+ int ret;
+
+ ret = wcn36xx_smd_rsp_status_check(buf, len);
+ if (ret)
+ return ret;
+
+ rsp = (struct wcn36xx_hal_process_ptt_msg_rsp_msg *)buf;
+
+ wcn36xx_dbg(WCN36XX_DBG_HAL, "process ptt msg responded with length %d\n",
+ rsp->header.len);
+ wcn36xx_dbg_dump(WCN36XX_DBG_HAL_DUMP, "HAL_PTT_MSG_RSP:", rsp->ptt_msg,
+ rsp->header.len - sizeof(rsp->ptt_msg_resp_status));
+
+ if (rsp->header.len > 0) {
+ *p_ptt_rsp_msg = kmalloc(rsp->header.len, GFP_ATOMIC);
+ if (!*p_ptt_rsp_msg)
+ return -ENOMEM;
+ memcpy(*p_ptt_rsp_msg, rsp->ptt_msg, rsp->header.len);
+ }
+ return ret;
+}
+
+int wcn36xx_smd_process_ptt_msg(struct wcn36xx *wcn,
+ struct ieee80211_vif *vif, void *ptt_msg, size_t len,
+ void **ptt_rsp_msg)
+{
+ struct wcn36xx_hal_process_ptt_msg_req_msg *p_msg_body;
+ int ret;
+
+ mutex_lock(&wcn->hal_mutex);
+ p_msg_body = kmalloc(
+ sizeof(struct wcn36xx_hal_process_ptt_msg_req_msg) + len,
+ GFP_ATOMIC);
+ if (!p_msg_body) {
+ ret = -ENOMEM;
+ goto out_nomem;
+ }
+ INIT_HAL_PTT_MSG(p_msg_body, len);
+
+ memcpy(&p_msg_body->ptt_msg, ptt_msg, len);
+
+ PREPARE_HAL_PTT_MSG_BUF(wcn->hal_buf, p_msg_body);
+
+ ret = wcn36xx_smd_send_and_wait(wcn, p_msg_body->header.len);
+ if (ret) {
+ wcn36xx_err("Sending hal_process_ptt_msg failed\n");
+ goto out;
+ }
+ ret = wcn36xx_smd_process_ptt_msg_rsp(wcn->hal_buf, wcn->hal_rsp_len,
+ ptt_rsp_msg);
+ if (ret) {
+ wcn36xx_err("process_ptt_msg response failed err=%d\n", ret);
+ goto out;
+ }
+out:
+ kfree(p_msg_body);
+out_nomem:
+ mutex_unlock(&wcn->hal_mutex);
+ return ret;
+}
+
static int wcn36xx_smd_update_scan_params_rsp(void *buf, size_t len)
{
struct wcn36xx_hal_update_scan_params_resp *rsp;
@@ -2367,6 +2446,7 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
case WCN36XX_HAL_JOIN_RSP:
case WCN36XX_HAL_UPDATE_SCAN_PARAM_RSP:
case WCN36XX_HAL_CH_SWITCH_RSP:
+ case WCN36XX_HAL_PROCESS_PTT_RSP:
case WCN36XX_HAL_FEATURE_CAPS_EXCHANGE_RSP:
case WCN36XX_HAL_8023_MULTICAST_LIST_RSP:
case WCN36XX_HAL_START_SCAN_OFFLOAD_RSP:
@@ -2407,6 +2487,7 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
return 0;
}
+
static void wcn36xx_ind_smd_work(struct work_struct *work)
{
struct wcn36xx *wcn =
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h
index 8076edf40ac8..945407b8764b 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.h
+++ b/drivers/net/wireless/ath/wcn36xx/smd.h
@@ -86,6 +86,10 @@ int wcn36xx_smd_send_beacon(struct wcn36xx *wcn, struct ieee80211_vif *vif,
u16 p2p_off);
int wcn36xx_smd_switch_channel(struct wcn36xx *wcn,
struct ieee80211_vif *vif, int ch);
+int wcn36xx_smd_process_ptt_msg(struct wcn36xx *wcn,
+ struct ieee80211_vif *vif,
+ void *ptt_msg, size_t len,
+ void **ptt_rsp_msg);
int wcn36xx_smd_update_proberesp_tmpl(struct wcn36xx *wcn,
struct ieee80211_vif *vif,
struct sk_buff *skb);
diff --git a/drivers/net/wireless/ath/wcn36xx/testmode.c b/drivers/net/wireless/ath/wcn36xx/testmode.c
new file mode 100644
index 000000000000..1279064a3b71
--- /dev/null
+++ b/drivers/net/wireless/ath/wcn36xx/testmode.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <net/netlink.h>
+#include <linux/firmware.h>
+#include <net/cfg80211.h>
+#include "wcn36xx.h"
+
+#include "testmode.h"
+#include "testmode_i.h"
+#include "hal.h"
+#include "smd.h"
+
+static const struct nla_policy wcn36xx_tm_policy[WCN36XX_TM_ATTR_MAX + 1] = {
+ [WCN36XX_TM_ATTR_CMD] = { .type = NLA_U16 },
+ [WCN36XX_TM_ATTR_DATA] = { .type = NLA_BINARY,
+ .len = WCN36XX_TM_DATA_MAX_LEN },
+};
+
+struct build_release_number {
+ u16 drv_major;
+ u16 drv_minor;
+ u16 drv_patch;
+ u16 drv_build;
+ u16 ptt_max;
+ u16 ptt_min;
+ u16 fw_ver;
+} __packed;
+
+static int wcn36xx_tm_cmd_ptt(struct wcn36xx *wcn, struct ieee80211_vif *vif,
+ struct nlattr *tb[])
+{
+ int ret = 0, buf_len;
+ void *buf;
+ struct ftm_rsp_msg *msg, *rsp = NULL;
+ struct sk_buff *skb;
+
+ if (!tb[WCN36XX_TM_ATTR_DATA])
+ return -EINVAL;
+
+ buf = nla_data(tb[WCN36XX_TM_ATTR_DATA]);
+ buf_len = nla_len(tb[WCN36XX_TM_ATTR_DATA]);
+ msg = (struct ftm_rsp_msg *)buf;
+
+ wcn36xx_dbg(WCN36XX_DBG_TESTMODE,
+ "testmode cmd wmi msg_id 0x%04X msg_len %d buf %pK buf_len %d\n",
+ msg->msg_id, msg->msg_body_length,
+ buf, buf_len);
+
+ wcn36xx_dbg_dump(WCN36XX_DBG_TESTMODE_DUMP, "REQ ", buf, buf_len);
+
+ if (msg->msg_id == MSG_GET_BUILD_RELEASE_NUMBER) {
+ struct build_release_number *body =
+ (struct build_release_number *)
+ msg->msg_response;
+
+ body->drv_major = wcn->fw_major;
+ body->drv_minor = wcn->fw_minor;
+ body->drv_patch = wcn->fw_version;
+ body->drv_build = wcn->fw_revision;
+ body->ptt_max = 10;
+ body->ptt_min = 0;
+
+ rsp = msg;
+ rsp->resp_status = 0;
+ } else {
+ wcn36xx_dbg(WCN36XX_DBG_TESTMODE,
+ "PPT Request >> HAL size %d\n",
+ msg->msg_body_length);
+
+ msg->resp_status = wcn36xx_smd_process_ptt_msg(wcn, vif, msg,
+ msg->msg_body_length, (void *)(&rsp));
+
+ wcn36xx_dbg(WCN36XX_DBG_TESTMODE,
+ "Response status = %d\n",
+ msg->resp_status);
+ if (rsp)
+ wcn36xx_dbg(WCN36XX_DBG_TESTMODE,
+ "PPT Response << HAL size %d\n",
+ rsp->msg_body_length);
+ }
+
+ if (!rsp) {
+ rsp = msg;
+ wcn36xx_warn("No response! Echoing request with response status %d\n",
+ rsp->resp_status);
+ }
+ wcn36xx_dbg_dump(WCN36XX_DBG_TESTMODE_DUMP, "RSP ",
+ rsp, rsp->msg_body_length);
+
+ skb = cfg80211_testmode_alloc_reply_skb(wcn->hw->wiphy,
+ nla_total_size(msg->msg_body_length));
+ if (!skb) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = nla_put(skb, WCN36XX_TM_ATTR_DATA, rsp->msg_body_length, rsp);
+ if (ret) {
+ kfree_skb(skb);
+ goto out;
+ }
+
+ ret = cfg80211_testmode_reply(skb);
+
+out:
+ if (rsp != msg)
+ kfree(rsp);
+
+ return ret;
+}
+
+int wcn36xx_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ void *data, int len)
+{
+ struct wcn36xx *wcn = hw->priv;
+ struct nlattr *tb[WCN36XX_TM_ATTR_MAX + 1];
+ int ret = 0;
+ unsigned short attr;
+
+ wcn36xx_dbg_dump(WCN36XX_DBG_TESTMODE_DUMP, "Data:", data, len);
+ ret = nla_parse(tb, WCN36XX_TM_ATTR_MAX, data, len,
+ wcn36xx_tm_policy, NULL);
+ if (ret)
+ return ret;
+
+ if (!tb[WCN36XX_TM_ATTR_CMD])
+ return -EINVAL;
+
+ attr = nla_get_u16(tb[WCN36XX_TM_ATTR_CMD]);
+
+ if (attr != WCN36XX_TM_CMD_PTT)
+ return -EOPNOTSUPP;
+
+ return wcn36xx_tm_cmd_ptt(wcn, vif, tb);
+}
diff --git a/drivers/net/wireless/ath/wcn36xx/testmode.h b/drivers/net/wireless/ath/wcn36xx/testmode.h
new file mode 100644
index 000000000000..4c6cfdb46580
--- /dev/null
+++ b/drivers/net/wireless/ath/wcn36xx/testmode.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "wcn36xx.h"
+
+struct ftm_rsp_msg {
+ u16 msg_id;
+ u16 msg_body_length;
+ u32 resp_status;
+ u8 msg_response[0];
+} __packed;
+
+/* The request buffer of FTM which contains a byte of command and the request */
+struct ftm_payload {
+ u16 ftm_cmd_type;
+ struct ftm_rsp_msg ftm_cmd_msg;
+} __packed;
+
+#define MSG_GET_BUILD_RELEASE_NUMBER 0x32A2
+
+#ifdef CONFIG_NL80211_TESTMODE
+int wcn36xx_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ void *data, int len);
+
+#else
+static inline int wcn36xx_tm_cmd(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ void *data, int len)
+{
+ return 0;
+}
+
+#endif
diff --git a/drivers/net/wireless/ath/wcn36xx/testmode_i.h b/drivers/net/wireless/ath/wcn36xx/testmode_i.h
new file mode 100644
index 000000000000..8a1477ffd5a0
--- /dev/null
+++ b/drivers/net/wireless/ath/wcn36xx/testmode_i.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define WCN36XX_TM_DATA_MAX_LEN 5000
+
+enum wcn36xx_tm_attr {
+ __WCN36XX_TM_ATTR_INVALID = 0,
+ WCN36XX_TM_ATTR_CMD = 1,
+ WCN36XX_TM_ATTR_DATA = 2,
+
+ /* keep last */
+ __WCN36XX_TM_ATTR_AFTER_LAST,
+ WCN36XX_TM_ATTR_MAX = __WCN36XX_TM_ATTR_AFTER_LAST - 1,
+};
+
+#define WCN36XX_TM_CMD_PTT 3
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
index 5854adf43f3a..547e9a9eb28f 100644
--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
+++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
@@ -56,6 +56,8 @@ enum wcn36xx_debug_mask {
WCN36XX_DBG_BEACON_DUMP = 0x00001000,
WCN36XX_DBG_PMC = 0x00002000,
WCN36XX_DBG_PMC_DUMP = 0x00004000,
+ WCN36XX_DBG_TESTMODE = 0x00008000,
+ WCN36XX_DBG_TESTMODE_DUMP = 0x00010000,
WCN36XX_DBG_ANY = 0xffffffff,
};
--
2.17.0
^ permalink raw reply related
* Re: [PATCH net-next 00/13] nfp: abm: add basic support for advanced buffering NIC
From: Jakub Kicinski @ 2018-05-22 19:14 UTC (permalink / raw)
To: Or Gerlitz
Cc: David Miller, Linux Netdev List, oss-drivers, Andy Gospodarek,
linux-internal
In-Reply-To: <CAJ3xEMhfZjKKRGZOJ8CvrbDEQ9jh9kYvZ-aJBsC86ixm+1RnWw@mail.gmail.com>
On Tue, 22 May 2018 17:50:45 +0300, Or Gerlitz wrote:
> On Tue, May 22, 2018 at 10:56 AM, Jakub Kicinski wrote:
> > On Mon, May 21, 2018 at 11:32 PM, Or Gerlitz wrote:
> >> On Tue, May 22, 2018 at 8:12 AM, Jakub Kicinski wrote:
> >>> Hi!
> >>>
> >>> This series lays groundwork for advanced buffer management NIC feature.
> >>> It makes necessary NFP core changes, spawns representors and adds devlink
> >>> glue. Following series will add the actual buffering configuration (patch
> >>> series size limit).
> >>>
> >>> First three patches add support for configuring NFP buffer pools via a
> >>> mailbox. The existing devlink APIs are used for the purpose.
> >>>
> >>> Third patch allows us to perform small reads from the NFP memory.
> >>>
> >>> The rest of the patch set adds eswitch mode change support and makes
> >>> the driver spawn appropriate representors.
> >>
> >> Hi Jakub,
> >>
> >> Could you provide more higher level description on the abm use-case
> >> and nature of these representors? I understand that under abm you are
> >> modeling the nic as switch with vNIC ports, does vNIC port and vNIC
> >> port rep have the same characteristics as VF and VF rep (xmit on one side
> >> <--> send on 2nd side), does traffic is to be offloaded using TC, etc.
> >> What one would be doing with vNIC instance, hand it to container ala the Intel
> >> VMDQ concept?
> >> can this be seen as veth HW offload? etc
>
> > Yes, the reprs can be used like VF reprs but that's not the main use
> > case. We are targeting container world with ABM, so no VFs and no
> > SR-IOV. There is only one vNIC per port and no veth offload etc. In
>
> one vNIC for multiple containers? or you have a (v?) port per container?
One vNIC with many queues for multiple containers. If containers have
QoS requirements they should be pinned to specific CPUs and eBPF on the
card can be used to RSS only to the queues associated with those CPUs,
while TC qdisc offload can be used to manipulate the scheduling of
those queues (and ECN marking).
> > In the most basic scenario with 1 PF corresponding to 1 port there is no
> > real use for switching.
>
> multiple containers? please clarify it a little better
Yes, if we had a netdev per container that would mean we would need
switching. But vetch/macvlan/ipvlan offload and therefore multiple
netdevs is not a requirement right now.
IOW we have the eBPF programmable RSS and we are trying to extend the
QoS to be able to make sure that critical/important containers' RX/TX
doesn't get disturbed by less important workloads.
> > The main purpose here is that we want to setup the buffering and QoS
> > inside the NIC (both for TX and RX) and then use eBPF to perform
> > filtering, queue assignment and per-application RSS. That's pretty
> > much it at this point.
> >
> > Switching if any will be a basic bridge offload. QoS configuration
> > will all be done using TC qdisc offload, RED etc. exactly like mlxsw :)
>
> I guess I'll understand it better once you clarify the multiple
> containers thing,
> thanks for the details and openness
I hope my clarifications help :)
^ permalink raw reply
* Re: Regression: Approximate 34% performance hit in receive throughput over ixgbe seen due to build_skb patch
From: William Kucharski @ 2018-05-22 19:29 UTC (permalink / raw)
To: Alexander Duyck
Cc: LKML, Netdev, intel-wired-lan, Jeff Kirsher, Duyck, Alexander H
In-Reply-To: <CAKgT0Ud2qriAkWcs56WEkw2vhYzBbWvzZOoY24ndsqPKaWn=Sg@mail.gmail.com>
> On May 22, 2018, at 12:23 PM, Alexander Duyck <alexander.duyck@gmail.com> wrote:
>
> 3. There should be a private flag that can be updated via "ethtool
> --set-priv-flags" called "legacy-rx" that you can enable that will
> roll back to the original that did the copy-break type approach for
> small packets and the headers of the frame.
With legacy-rx enabled, most of the regression goes away, but it's still present
as compared to the code without the patch; the regression then drops to about 6%:
# ethtool --show-priv-flags eno1
Private flags for eno1:
legacy-rx: on
Socket Message Elapsed Messages
Size Size Time Okay Errors Throughput
bytes bytes secs # # 10^6bits/sec
65536 64 60.00 35934709 0 306.64
65536 60.00 33791739 288.35
Socket Message Elapsed Messages
Size Size Time Okay Errors Throughput
bytes bytes secs # # 10^6bits/sec
65536 64 60.00 39254351 0 334.97
65536 60.00 36761069 313.69
Is this variance to be expected, or do you think modification of the
interrupt delay would achieve better results?
William Kucharski
^ permalink raw reply
* Re: [PATCH net] ipmr: properly check rhltable_init() return value
From: David Miller @ 2018-05-22 19:32 UTC (permalink / raw)
To: edumazet; +Cc: netdev, eric.dumazet, nikolay, yuvalm
In-Reply-To: <20180521175153.27484-1-edumazet@google.com>
From: Eric Dumazet <edumazet@google.com>
Date: Mon, 21 May 2018 10:51:53 -0700
> commit 8fb472c09b9d ("ipmr: improve hash scalability")
> added a call to rhltable_init() without checking its return value.
>
> This problem was then later copied to IPv6 and factorized in commit
> 0bbbf0e7d0e7 ("ipmr, ip6mr: Unite creation of new mr_table")
...
> Fixes: 8fb472c09b9d ("ipmr: improve hash scalability")
> Fixes: 0bbbf0e7d0e7 ("ipmr, ip6mr: Unite creation of new mr_table")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
> Cc: Yuval Mintz <yuvalm@mellanox.com>
> Reported-by: syzbot <syzkaller@googlegroups.com>
Applied and queued up for -stable, thanks Eric.
^ permalink raw reply
* Re: [PATCH net 1/1] qed: Fix mask for physical address in ILT entry
From: David Miller @ 2018-05-22 19:33 UTC (permalink / raw)
To: shahed.shaikh; +Cc: netdev, Ariel.Elior, Dept-EngEverestLinuxL2
In-Reply-To: <20180521193147.18628-1-shahed.shaikh@cavium.com>
From: Shahed Shaikh <shahed.shaikh@cavium.com>
Date: Mon, 21 May 2018 12:31:47 -0700
> ILT entry requires 12 bit right shifted physical address.
> Existing mask for ILT entry of physical address i.e.
> ILT_ENTRY_PHY_ADDR_MASK is not sufficient to handle 64bit
> address because upper 8 bits of 64 bit address were getting
> masked which resulted in completer abort error on
> PCIe bus due to invalid address.
>
> Fix that mask to handle 64bit physical address.
>
> Fixes: fe56b9e6a8d9 ("qed: Add module with basic common support")
>
> Signed-off-by: Shahed Shaikh <shahed.shaikh@cavium.com>
> Signed-off-by: Ariel Elior <ariel.elior@cavium.com>
Please do not put an empty line between Fixes: and other tags in the
future. I fixed it up this time.
Applied, thanks.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox