Skip to content

Commit

Permalink
Merge branch 'mlx4-next'
Browse files Browse the repository at this point in the history
Or Gerlitz says:

====================
mlx4: Extend statistics gathering and display

This series from Eran and Matan extends the statistics collected and later
reported to the user via ethtool for native mode and SRIOV PF.

More Packet statistics, PFC statistics and global pause statistics
are now displayed via ethtool.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Mar 31, 2015
2 parents c997533 + a3333b3 commit 3aa10da
Show file tree
Hide file tree
Showing 9 changed files with 546 additions and 151 deletions.
4 changes: 4 additions & 0 deletions drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,10 @@ static int mlx4_en_dcbnl_ieee_setpfc(struct net_device *dev,
prof->rx_ppp);
if (err)
en_err(priv, "Failed setting pause params\n");
else
mlx4_en_update_pfc_stats_bitmap(mdev->dev, &priv->stats_bitmap,
prof->rx_ppp, prof->rx_pause,
prof->tx_ppp, prof->tx_pause);

return err;
}
Expand Down
225 changes: 173 additions & 52 deletions drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <linux/mlx4/device.h>
#include <linux/in.h>
#include <net/ip.h>
#include <linux/bitmap.h>

#include "mlx4_en.h"
#include "en_port.h"
Expand Down Expand Up @@ -104,6 +105,7 @@ static const char mlx4_en_priv_flags[][ETH_GSTRING_LEN] = {
};

static const char main_strings[][ETH_GSTRING_LEN] = {
/* main statistics */
"rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
"tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions",
"rx_length_errors", "rx_over_errors", "rx_crc_errors",
Expand All @@ -117,14 +119,76 @@ static const char main_strings[][ETH_GSTRING_LEN] = {
"queue_stopped", "wake_queue", "tx_timeout", "rx_alloc_failed",
"rx_csum_good", "rx_csum_none", "rx_csum_complete", "tx_chksum_offload",

/* priority flow control statistics rx */
"rx_pause_prio_0", "rx_pause_duration_prio_0",
"rx_pause_transition_prio_0",
"rx_pause_prio_1", "rx_pause_duration_prio_1",
"rx_pause_transition_prio_1",
"rx_pause_prio_2", "rx_pause_duration_prio_2",
"rx_pause_transition_prio_2",
"rx_pause_prio_3", "rx_pause_duration_prio_3",
"rx_pause_transition_prio_3",
"rx_pause_prio_4", "rx_pause_duration_prio_4",
"rx_pause_transition_prio_4",
"rx_pause_prio_5", "rx_pause_duration_prio_5",
"rx_pause_transition_prio_5",
"rx_pause_prio_6", "rx_pause_duration_prio_6",
"rx_pause_transition_prio_6",
"rx_pause_prio_7", "rx_pause_duration_prio_7",
"rx_pause_transition_prio_7",

/* flow control statistics rx */
"rx_pause", "rx_pause_duration", "rx_pause_transition",

/* priority flow control statistics tx */
"tx_pause_prio_0", "tx_pause_duration_prio_0",
"tx_pause_transition_prio_0",
"tx_pause_prio_1", "tx_pause_duration_prio_1",
"tx_pause_transition_prio_1",
"tx_pause_prio_2", "tx_pause_duration_prio_2",
"tx_pause_transition_prio_2",
"tx_pause_prio_3", "tx_pause_duration_prio_3",
"tx_pause_transition_prio_3",
"tx_pause_prio_4", "tx_pause_duration_prio_4",
"tx_pause_transition_prio_4",
"tx_pause_prio_5", "tx_pause_duration_prio_5",
"tx_pause_transition_prio_5",
"tx_pause_prio_6", "tx_pause_duration_prio_6",
"tx_pause_transition_prio_6",
"tx_pause_prio_7", "tx_pause_duration_prio_7",
"tx_pause_transition_prio_7",

/* flow control statistics tx */
"tx_pause", "tx_pause_duration", "tx_pause_transition",

/* packet statistics */
"broadcast", "rx_prio_0", "rx_prio_1", "rx_prio_2", "rx_prio_3",
"rx_prio_4", "rx_prio_5", "rx_prio_6", "rx_prio_7", "tx_prio_0",
"tx_prio_1", "tx_prio_2", "tx_prio_3", "tx_prio_4", "tx_prio_5",
"tx_prio_6", "tx_prio_7",
"rx_multicast_packets",
"rx_broadcast_packets",
"rx_jabbers",
"rx_in_range_length_error",
"rx_out_range_length_error",
"tx_multicast_packets",
"tx_broadcast_packets",
"rx_prio_0_packets", "rx_prio_0_bytes",
"rx_prio_1_packets", "rx_prio_1_bytes",
"rx_prio_2_packets", "rx_prio_2_bytes",
"rx_prio_3_packets", "rx_prio_3_bytes",
"rx_prio_4_packets", "rx_prio_4_bytes",
"rx_prio_5_packets", "rx_prio_5_bytes",
"rx_prio_6_packets", "rx_prio_6_bytes",
"rx_prio_7_packets", "rx_prio_7_bytes",
"rx_novlan_packets", "rx_novlan_bytes",
"tx_prio_0_packets", "tx_prio_0_bytes",
"tx_prio_1_packets", "tx_prio_1_bytes",
"tx_prio_2_packets", "tx_prio_2_bytes",
"tx_prio_3_packets", "tx_prio_3_bytes",
"tx_prio_4_packets", "tx_prio_4_bytes",
"tx_prio_5_packets", "tx_prio_5_bytes",
"tx_prio_6_packets", "tx_prio_6_bytes",
"tx_prio_7_packets", "tx_prio_7_bytes",
"tx_novlan_packets", "tx_novlan_bytes",

};
#define NUM_MAIN_STATS 21
#define NUM_ALL_STATS (NUM_MAIN_STATS + NUM_PORT_STATS + NUM_PKT_STATS + NUM_PERF_STATS)

static const char mlx4_en_test_names[][ETH_GSTRING_LEN]= {
"Interrupt Test",
Expand Down Expand Up @@ -224,14 +288,50 @@ static int mlx4_en_set_wol(struct net_device *netdev,
return err;
}

struct bitmap_iterator {
unsigned long *stats_bitmap;
unsigned int count;
unsigned int iterator;
bool advance_array; /* if set, force no increments */
};

static inline void bitmap_iterator_init(struct bitmap_iterator *h,
unsigned long *stats_bitmap,
int count)
{
h->iterator = 0;
h->advance_array = !bitmap_empty(stats_bitmap, count);
h->count = h->advance_array ? bitmap_weight(stats_bitmap, count)
: count;
h->stats_bitmap = stats_bitmap;
}

static inline int bitmap_iterator_test(struct bitmap_iterator *h)
{
return !h->advance_array ? 1 : test_bit(h->iterator, h->stats_bitmap);
}

static inline int bitmap_iterator_inc(struct bitmap_iterator *h)
{
return h->iterator++;
}

static inline unsigned int
bitmap_iterator_count(struct bitmap_iterator *h)
{
return h->count;
}

static int mlx4_en_get_sset_count(struct net_device *dev, int sset)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
int bit_count = hweight64(priv->stats_bitmap);
struct bitmap_iterator it;

bitmap_iterator_init(&it, priv->stats_bitmap.bitmap, NUM_ALL_STATS);

switch (sset) {
case ETH_SS_STATS:
return (priv->stats_bitmap ? bit_count : NUM_ALL_STATS) +
return bitmap_iterator_count(&it) +
(priv->tx_ring_num * 2) +
#ifdef CONFIG_NET_RX_BUSY_POLL
(priv->rx_ring_num * 5);
Expand All @@ -253,34 +353,45 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev,
{
struct mlx4_en_priv *priv = netdev_priv(dev);
int index = 0;
int i, j = 0;
int i;
struct bitmap_iterator it;

bitmap_iterator_init(&it, priv->stats_bitmap.bitmap, NUM_ALL_STATS);

spin_lock_bh(&priv->stats_lock);

if (!(priv->stats_bitmap)) {
for (i = 0; i < NUM_MAIN_STATS; i++)
data[index++] =
((unsigned long *) &priv->stats)[i];
for (i = 0; i < NUM_PORT_STATS; i++)
for (i = 0; i < NUM_MAIN_STATS; i++, bitmap_iterator_inc(&it))
if (bitmap_iterator_test(&it))
data[index++] = ((unsigned long *)&priv->stats)[i];

for (i = 0; i < NUM_PORT_STATS; i++, bitmap_iterator_inc(&it))
if (bitmap_iterator_test(&it))
data[index++] = ((unsigned long *)&priv->port_stats)[i];

for (i = 0; i < NUM_FLOW_PRIORITY_STATS_RX;
i++, bitmap_iterator_inc(&it))
if (bitmap_iterator_test(&it))
data[index++] =
((unsigned long *) &priv->port_stats)[i];
for (i = 0; i < NUM_PKT_STATS; i++)
((u64 *)&priv->rx_priority_flowstats)[i];

for (i = 0; i < NUM_FLOW_STATS_RX; i++, bitmap_iterator_inc(&it))
if (bitmap_iterator_test(&it))
data[index++] = ((u64 *)&priv->rx_flowstats)[i];

for (i = 0; i < NUM_FLOW_PRIORITY_STATS_TX;
i++, bitmap_iterator_inc(&it))
if (bitmap_iterator_test(&it))
data[index++] =
((unsigned long *) &priv->pkstats)[i];
} else {
for (i = 0; i < NUM_MAIN_STATS; i++) {
if ((priv->stats_bitmap >> j) & 1)
data[index++] =
((unsigned long *) &priv->stats)[i];
j++;
}
for (i = 0; i < NUM_PORT_STATS; i++) {
if ((priv->stats_bitmap >> j) & 1)
data[index++] =
((unsigned long *) &priv->port_stats)[i];
j++;
}
}
((u64 *)&priv->tx_priority_flowstats)[i];

for (i = 0; i < NUM_FLOW_STATS_TX; i++, bitmap_iterator_inc(&it))
if (bitmap_iterator_test(&it))
data[index++] = ((u64 *)&priv->tx_flowstats)[i];

for (i = 0; i < NUM_PKT_STATS; i++, bitmap_iterator_inc(&it))
if (bitmap_iterator_test(&it))
data[index++] = ((unsigned long *)&priv->pkstats)[i];

for (i = 0; i < priv->tx_ring_num; i++) {
data[index++] = priv->tx_ring[i]->packets;
data[index++] = priv->tx_ring[i]->bytes;
Expand Down Expand Up @@ -309,7 +420,10 @@ static void mlx4_en_get_strings(struct net_device *dev,
{
struct mlx4_en_priv *priv = netdev_priv(dev);
int index = 0;
int i;
int i, strings = 0;
struct bitmap_iterator it;

bitmap_iterator_init(&it, priv->stats_bitmap.bitmap, NUM_ALL_STATS);

switch (stringset) {
case ETH_SS_TEST:
Expand All @@ -322,29 +436,30 @@ static void mlx4_en_get_strings(struct net_device *dev,

case ETH_SS_STATS:
/* Add main counters */
if (!priv->stats_bitmap) {
for (i = 0; i < NUM_MAIN_STATS; i++)
for (i = 0; i < NUM_MAIN_STATS; i++, strings++,
bitmap_iterator_inc(&it))
if (bitmap_iterator_test(&it))
strcpy(data + (index++) * ETH_GSTRING_LEN,
main_strings[i]);
for (i = 0; i < NUM_PORT_STATS; i++)
main_strings[strings]);

for (i = 0; i < NUM_PORT_STATS; i++, strings++,
bitmap_iterator_inc(&it))
if (bitmap_iterator_test(&it))
strcpy(data + (index++) * ETH_GSTRING_LEN,
main_strings[i +
NUM_MAIN_STATS]);
for (i = 0; i < NUM_PKT_STATS; i++)
main_strings[strings]);

for (i = 0; i < NUM_FLOW_STATS; i++, strings++,
bitmap_iterator_inc(&it))
if (bitmap_iterator_test(&it))
strcpy(data + (index++) * ETH_GSTRING_LEN,
main_strings[i +
NUM_MAIN_STATS +
NUM_PORT_STATS]);
} else
for (i = 0; i < NUM_MAIN_STATS + NUM_PORT_STATS; i++) {
if ((priv->stats_bitmap >> i) & 1) {
strcpy(data +
(index++) * ETH_GSTRING_LEN,
main_strings[i]);
}
if (!(priv->stats_bitmap >> i))
break;
}
main_strings[strings]);

for (i = 0; i < NUM_PKT_STATS; i++, strings++,
bitmap_iterator_inc(&it))
if (bitmap_iterator_test(&it))
strcpy(data + (index++) * ETH_GSTRING_LEN,
main_strings[strings]);

for (i = 0; i < priv->tx_ring_num; i++) {
sprintf(data + (index++) * ETH_GSTRING_LEN,
"tx%d_packets", i);
Expand Down Expand Up @@ -885,6 +1000,12 @@ static int mlx4_en_set_pauseparam(struct net_device *dev,
priv->prof->rx_ppp);
if (err)
en_err(priv, "Failed setting pause params\n");
else
mlx4_en_update_pfc_stats_bitmap(mdev->dev, &priv->stats_bitmap,
priv->prof->rx_ppp,
priv->prof->rx_pause,
priv->prof->tx_ppp,
priv->prof->tx_pause);

return err;
}
Expand Down
Loading

0 comments on commit 3aa10da

Please sign in to comment.