Commit 61248720 authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents bed187b5 f73a6f43
...@@ -362,7 +362,7 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev, ...@@ -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)) for (i = 0; i < NUM_MAIN_STATS; i++, bitmap_iterator_inc(&it))
if (bitmap_iterator_test(&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)) for (i = 0; i < NUM_PORT_STATS; i++, bitmap_iterator_inc(&it))
if (bitmap_iterator_test(&it)) if (bitmap_iterator_test(&it))
......
...@@ -1296,15 +1296,16 @@ static void mlx4_en_tx_timeout(struct net_device *dev) ...@@ -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); struct mlx4_en_priv *priv = netdev_priv(dev);
spin_lock_bh(&priv->stats_lock); 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); spin_unlock_bh(&priv->stats_lock);
return &priv->ret_stats; return stats;
} }
static void mlx4_en_set_default_moderation(struct mlx4_en_priv *priv) 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) ...@@ -1876,7 +1877,6 @@ static void mlx4_en_clear_stats(struct net_device *dev)
if (mlx4_en_DUMP_ETH_STATS(mdev, priv->port, 1)) if (mlx4_en_DUMP_ETH_STATS(mdev, priv->port, 1))
en_dbg(HW, priv, "Failed dumping statistics\n"); en_dbg(HW, priv, "Failed dumping statistics\n");
memset(&priv->stats, 0, sizeof(priv->stats));
memset(&priv->pstats, 0, sizeof(priv->pstats)); memset(&priv->pstats, 0, sizeof(priv->pstats));
memset(&priv->pkstats, 0, sizeof(priv->pkstats)); memset(&priv->pkstats, 0, sizeof(priv->pkstats));
memset(&priv->port_stats, 0, sizeof(priv->port_stats)); memset(&priv->port_stats, 0, sizeof(priv->port_stats));
...@@ -1892,6 +1892,11 @@ static void mlx4_en_clear_stats(struct net_device *dev) ...@@ -1892,6 +1892,11 @@ static void mlx4_en_clear_stats(struct net_device *dev)
priv->tx_ring[i]->bytes = 0; priv->tx_ring[i]->bytes = 0;
priv->tx_ring[i]->packets = 0; priv->tx_ring[i]->packets = 0;
priv->tx_ring[i]->tx_csum = 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++) { for (i = 0; i < priv->rx_ring_num; i++) {
priv->rx_ring[i]->bytes = 0; priv->rx_ring[i]->bytes = 0;
...@@ -2482,7 +2487,7 @@ static const struct net_device_ops mlx4_netdev_ops = { ...@@ -2482,7 +2487,7 @@ static const struct net_device_ops mlx4_netdev_ops = {
.ndo_stop = mlx4_en_close, .ndo_stop = mlx4_en_close,
.ndo_start_xmit = mlx4_en_xmit, .ndo_start_xmit = mlx4_en_xmit,
.ndo_select_queue = mlx4_en_select_queue, .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_rx_mode = mlx4_en_set_rx_mode,
.ndo_set_mac_address = mlx4_en_set_mac, .ndo_set_mac_address = mlx4_en_set_mac,
.ndo_validate_addr = eth_validate_addr, .ndo_validate_addr = eth_validate_addr,
...@@ -2514,7 +2519,7 @@ static const struct net_device_ops mlx4_netdev_ops_master = { ...@@ -2514,7 +2519,7 @@ static const struct net_device_ops mlx4_netdev_ops_master = {
.ndo_stop = mlx4_en_close, .ndo_stop = mlx4_en_close,
.ndo_start_xmit = mlx4_en_xmit, .ndo_start_xmit = mlx4_en_xmit,
.ndo_select_queue = mlx4_en_select_queue, .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_rx_mode = mlx4_en_set_rx_mode,
.ndo_set_mac_address = mlx4_en_set_mac, .ndo_set_mac_address = mlx4_en_set_mac,
.ndo_validate_addr = eth_validate_addr, .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) ...@@ -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_counter tmp_counter_stats;
struct mlx4_en_stat_out_mbox *mlx4_en_stats; struct mlx4_en_stat_out_mbox *mlx4_en_stats;
struct mlx4_en_stat_out_flow_control_mbox *flowstats; struct mlx4_en_stat_out_flow_control_mbox *flowstats;
struct mlx4_en_priv *priv = netdev_priv(mdev->pndev[port]); struct net_device *dev = mdev->pndev[port];
struct net_device_stats *stats = &priv->stats; struct mlx4_en_priv *priv = netdev_priv(dev);
struct net_device_stats *stats = &dev->stats;
struct mlx4_cmd_mailbox *mailbox; struct mlx4_cmd_mailbox *mailbox;
u64 in_mod = reset << 8 | port; u64 in_mod = reset << 8 | port;
int err; int err;
...@@ -188,6 +189,7 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset) ...@@ -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_packets = 0;
stats->tx_bytes = 0; stats->tx_bytes = 0;
stats->tx_dropped = 0;
priv->port_stats.tx_chksum_offload = 0; priv->port_stats.tx_chksum_offload = 0;
priv->port_stats.queue_stopped = 0; priv->port_stats.queue_stopped = 0;
priv->port_stats.wake_queue = 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) ...@@ -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_packets += ring->packets;
stats->tx_bytes += ring->bytes; stats->tx_bytes += ring->bytes;
stats->tx_dropped += ring->tx_dropped;
priv->port_stats.tx_chksum_offload += ring->tx_csum; priv->port_stats.tx_chksum_offload += ring->tx_csum;
priv->port_stats.queue_stopped += ring->queue_stopped; priv->port_stats.queue_stopped += ring->queue_stopped;
priv->port_stats.wake_queue += ring->wake_queue; 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) ...@@ -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, stats->multicast = en_stats_adder(&mlx4_en_stats->MCAST_prio_0,
&mlx4_en_stats->MCAST_prio_1, &mlx4_en_stats->MCAST_prio_1,
NUM_PRIORITIES); NUM_PRIORITIES);
stats->collisions = 0;
stats->rx_dropped = be32_to_cpu(mlx4_en_stats->RDROP) + stats->rx_dropped = be32_to_cpu(mlx4_en_stats->RDROP) +
sw_rx_dropped; sw_rx_dropped;
stats->rx_length_errors = be32_to_cpu(mlx4_en_stats->RdropLength); 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_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_fifo_errors = be32_to_cpu(mlx4_en_stats->RdropOvflw);
stats->rx_missed_errors = 0; stats->tx_dropped += be32_to_cpu(mlx4_en_stats->TDROP);
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);
/* RX stats */ /* RX stats */
priv->pkstats.rx_multicast_packets = stats->multicast; 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) ...@@ -726,12 +726,12 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
bool inline_ok; bool inline_ok;
u32 ring_cons; u32 ring_cons;
if (!priv->port_up)
goto tx_drop;
tx_ind = skb_get_queue_mapping(skb); tx_ind = skb_get_queue_mapping(skb);
ring = priv->tx_ring[tx_ind]; ring = priv->tx_ring[tx_ind];
if (!priv->port_up)
goto tx_drop;
/* fetch ring->cons far ahead before needing it to avoid stall */ /* fetch ring->cons far ahead before needing it to avoid stall */
ring_cons = ACCESS_ONCE(ring->cons); ring_cons = ACCESS_ONCE(ring->cons);
...@@ -1030,7 +1030,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1030,7 +1030,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
tx_drop: tx_drop:
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
priv->stats.tx_dropped++; ring->tx_dropped++;
return NETDEV_TX_OK; return NETDEV_TX_OK;
} }
...@@ -270,6 +270,7 @@ struct mlx4_en_tx_ring { ...@@ -270,6 +270,7 @@ struct mlx4_en_tx_ring {
unsigned long tx_csum; unsigned long tx_csum;
unsigned long tso_packets; unsigned long tso_packets;
unsigned long xmit_more; unsigned long xmit_more;
unsigned int tx_dropped;
struct mlx4_bf bf; struct mlx4_bf bf;
unsigned long queue_stopped; unsigned long queue_stopped;
...@@ -482,8 +483,6 @@ struct mlx4_en_priv { ...@@ -482,8 +483,6 @@ struct mlx4_en_priv {
struct mlx4_en_port_profile *prof; struct mlx4_en_port_profile *prof;
struct net_device *dev; struct net_device *dev;
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; 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; struct mlx4_en_port_state port_state;
spinlock_t stats_lock; spinlock_t stats_lock;
struct ethtool_flow_id ethtool_rules[MAX_NUM_OF_FS_RULES]; struct ethtool_flow_id ethtool_rules[MAX_NUM_OF_FS_RULES];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment