forked from Minki/linux
Merge branch 'mlx4-stats-fixes'
Eric Dumazet says: ==================== net/mlx4_en: fix stats mlx4 has various bugs in its ndo_get_stats() and related functions. This patch series address the obvious issues. Remaining ones will be discussed later. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
61248720c4
@ -362,7 +362,7 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev,
|
||||
|
||||
for (i = 0; i < NUM_MAIN_STATS; i++, bitmap_iterator_inc(&it))
|
||||
if (bitmap_iterator_test(&it))
|
||||
data[index++] = ((unsigned long *)&priv->stats)[i];
|
||||
data[index++] = ((unsigned long *)&dev->stats)[i];
|
||||
|
||||
for (i = 0; i < NUM_PORT_STATS; i++, bitmap_iterator_inc(&it))
|
||||
if (bitmap_iterator_test(&it))
|
||||
|
@ -1296,15 +1296,16 @@ static void mlx4_en_tx_timeout(struct net_device *dev)
|
||||
}
|
||||
|
||||
|
||||
static struct net_device_stats *mlx4_en_get_stats(struct net_device *dev)
|
||||
static struct rtnl_link_stats64 *
|
||||
mlx4_en_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
|
||||
{
|
||||
struct mlx4_en_priv *priv = netdev_priv(dev);
|
||||
|
||||
spin_lock_bh(&priv->stats_lock);
|
||||
memcpy(&priv->ret_stats, &priv->stats, sizeof(priv->stats));
|
||||
netdev_stats_to_stats64(stats, &dev->stats);
|
||||
spin_unlock_bh(&priv->stats_lock);
|
||||
|
||||
return &priv->ret_stats;
|
||||
return stats;
|
||||
}
|
||||
|
||||
static void mlx4_en_set_default_moderation(struct mlx4_en_priv *priv)
|
||||
@ -1876,7 +1877,6 @@ static void mlx4_en_clear_stats(struct net_device *dev)
|
||||
if (mlx4_en_DUMP_ETH_STATS(mdev, priv->port, 1))
|
||||
en_dbg(HW, priv, "Failed dumping statistics\n");
|
||||
|
||||
memset(&priv->stats, 0, sizeof(priv->stats));
|
||||
memset(&priv->pstats, 0, sizeof(priv->pstats));
|
||||
memset(&priv->pkstats, 0, sizeof(priv->pkstats));
|
||||
memset(&priv->port_stats, 0, sizeof(priv->port_stats));
|
||||
@ -1892,6 +1892,11 @@ static void mlx4_en_clear_stats(struct net_device *dev)
|
||||
priv->tx_ring[i]->bytes = 0;
|
||||
priv->tx_ring[i]->packets = 0;
|
||||
priv->tx_ring[i]->tx_csum = 0;
|
||||
priv->tx_ring[i]->tx_dropped = 0;
|
||||
priv->tx_ring[i]->queue_stopped = 0;
|
||||
priv->tx_ring[i]->wake_queue = 0;
|
||||
priv->tx_ring[i]->tso_packets = 0;
|
||||
priv->tx_ring[i]->xmit_more = 0;
|
||||
}
|
||||
for (i = 0; i < priv->rx_ring_num; i++) {
|
||||
priv->rx_ring[i]->bytes = 0;
|
||||
@ -2482,7 +2487,7 @@ static const struct net_device_ops mlx4_netdev_ops = {
|
||||
.ndo_stop = mlx4_en_close,
|
||||
.ndo_start_xmit = mlx4_en_xmit,
|
||||
.ndo_select_queue = mlx4_en_select_queue,
|
||||
.ndo_get_stats = mlx4_en_get_stats,
|
||||
.ndo_get_stats64 = mlx4_en_get_stats64,
|
||||
.ndo_set_rx_mode = mlx4_en_set_rx_mode,
|
||||
.ndo_set_mac_address = mlx4_en_set_mac,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
@ -2514,7 +2519,7 @@ static const struct net_device_ops mlx4_netdev_ops_master = {
|
||||
.ndo_stop = mlx4_en_close,
|
||||
.ndo_start_xmit = mlx4_en_xmit,
|
||||
.ndo_select_queue = mlx4_en_select_queue,
|
||||
.ndo_get_stats = mlx4_en_get_stats,
|
||||
.ndo_get_stats64 = mlx4_en_get_stats64,
|
||||
.ndo_set_rx_mode = mlx4_en_set_rx_mode,
|
||||
.ndo_set_mac_address = mlx4_en_set_mac,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
|
@ -152,8 +152,9 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
|
||||
struct mlx4_counter tmp_counter_stats;
|
||||
struct mlx4_en_stat_out_mbox *mlx4_en_stats;
|
||||
struct mlx4_en_stat_out_flow_control_mbox *flowstats;
|
||||
struct mlx4_en_priv *priv = netdev_priv(mdev->pndev[port]);
|
||||
struct net_device_stats *stats = &priv->stats;
|
||||
struct net_device *dev = mdev->pndev[port];
|
||||
struct mlx4_en_priv *priv = netdev_priv(dev);
|
||||
struct net_device_stats *stats = &dev->stats;
|
||||
struct mlx4_cmd_mailbox *mailbox;
|
||||
u64 in_mod = reset << 8 | port;
|
||||
int err;
|
||||
@ -188,6 +189,7 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
|
||||
}
|
||||
stats->tx_packets = 0;
|
||||
stats->tx_bytes = 0;
|
||||
stats->tx_dropped = 0;
|
||||
priv->port_stats.tx_chksum_offload = 0;
|
||||
priv->port_stats.queue_stopped = 0;
|
||||
priv->port_stats.wake_queue = 0;
|
||||
@ -199,6 +201,7 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
|
||||
|
||||
stats->tx_packets += ring->packets;
|
||||
stats->tx_bytes += ring->bytes;
|
||||
stats->tx_dropped += ring->tx_dropped;
|
||||
priv->port_stats.tx_chksum_offload += ring->tx_csum;
|
||||
priv->port_stats.queue_stopped += ring->queue_stopped;
|
||||
priv->port_stats.wake_queue += ring->wake_queue;
|
||||
@ -237,21 +240,12 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
|
||||
stats->multicast = en_stats_adder(&mlx4_en_stats->MCAST_prio_0,
|
||||
&mlx4_en_stats->MCAST_prio_1,
|
||||
NUM_PRIORITIES);
|
||||
stats->collisions = 0;
|
||||
stats->rx_dropped = be32_to_cpu(mlx4_en_stats->RDROP) +
|
||||
sw_rx_dropped;
|
||||
stats->rx_length_errors = be32_to_cpu(mlx4_en_stats->RdropLength);
|
||||
stats->rx_over_errors = 0;
|
||||
stats->rx_crc_errors = be32_to_cpu(mlx4_en_stats->RCRC);
|
||||
stats->rx_frame_errors = 0;
|
||||
stats->rx_fifo_errors = be32_to_cpu(mlx4_en_stats->RdropOvflw);
|
||||
stats->rx_missed_errors = 0;
|
||||
stats->tx_aborted_errors = 0;
|
||||
stats->tx_carrier_errors = 0;
|
||||
stats->tx_fifo_errors = 0;
|
||||
stats->tx_heartbeat_errors = 0;
|
||||
stats->tx_window_errors = 0;
|
||||
stats->tx_dropped = be32_to_cpu(mlx4_en_stats->TDROP);
|
||||
stats->tx_dropped += be32_to_cpu(mlx4_en_stats->TDROP);
|
||||
|
||||
/* RX stats */
|
||||
priv->pkstats.rx_multicast_packets = stats->multicast;
|
||||
|
@ -726,12 +726,12 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
bool inline_ok;
|
||||
u32 ring_cons;
|
||||
|
||||
if (!priv->port_up)
|
||||
goto tx_drop;
|
||||
|
||||
tx_ind = skb_get_queue_mapping(skb);
|
||||
ring = priv->tx_ring[tx_ind];
|
||||
|
||||
if (!priv->port_up)
|
||||
goto tx_drop;
|
||||
|
||||
/* fetch ring->cons far ahead before needing it to avoid stall */
|
||||
ring_cons = ACCESS_ONCE(ring->cons);
|
||||
|
||||
@ -1030,7 +1030,7 @@ tx_drop_unmap:
|
||||
|
||||
tx_drop:
|
||||
dev_kfree_skb_any(skb);
|
||||
priv->stats.tx_dropped++;
|
||||
ring->tx_dropped++;
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
|
@ -270,6 +270,7 @@ struct mlx4_en_tx_ring {
|
||||
unsigned long tx_csum;
|
||||
unsigned long tso_packets;
|
||||
unsigned long xmit_more;
|
||||
unsigned int tx_dropped;
|
||||
struct mlx4_bf bf;
|
||||
unsigned long queue_stopped;
|
||||
|
||||
@ -482,8 +483,6 @@ struct mlx4_en_priv {
|
||||
struct mlx4_en_port_profile *prof;
|
||||
struct net_device *dev;
|
||||
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
|
||||
struct net_device_stats stats;
|
||||
struct net_device_stats ret_stats;
|
||||
struct mlx4_en_port_state port_state;
|
||||
spinlock_t stats_lock;
|
||||
struct ethtool_flow_id ethtool_rules[MAX_NUM_OF_FS_RULES];
|
||||
|
Loading…
Reference in New Issue
Block a user