mirror of https://gitee.com/openkylin/linux.git
net/mlx4_en: Add ethtool statistics for XDP cases
XDP statistics are reported in ethtool, in total and per ring, as follows: - xdp_drop: the number of packets dropped by xdp. - xdp_tx: the number of packets forwarded by xdp. - xdp_tx_full: the number of times an xdp forward failed due to a full tx xdp ring. In addition, all packets that are dropped/forwarded by XDP are no longer accounted in rx_packets/rx_bytes of the ring, so that they count traffic that is passed to the stack. Signed-off-by: Tariq Toukan <tariqt@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
67f8b1dcb9
commit
15fca2c8eb
|
@ -195,6 +195,10 @@ static const char main_strings[][ETH_GSTRING_LEN] = {
|
||||||
"tx_prio_7_packets", "tx_prio_7_bytes",
|
"tx_prio_7_packets", "tx_prio_7_bytes",
|
||||||
"tx_novlan_packets", "tx_novlan_bytes",
|
"tx_novlan_packets", "tx_novlan_bytes",
|
||||||
|
|
||||||
|
/* xdp statistics */
|
||||||
|
"rx_xdp_drop",
|
||||||
|
"rx_xdp_tx",
|
||||||
|
"rx_xdp_tx_full",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char mlx4_en_test_names[][ETH_GSTRING_LEN]= {
|
static const char mlx4_en_test_names[][ETH_GSTRING_LEN]= {
|
||||||
|
@ -340,7 +344,7 @@ static int mlx4_en_get_sset_count(struct net_device *dev, int sset)
|
||||||
case ETH_SS_STATS:
|
case ETH_SS_STATS:
|
||||||
return bitmap_iterator_count(&it) +
|
return bitmap_iterator_count(&it) +
|
||||||
(priv->tx_ring_num[TX] * 2) +
|
(priv->tx_ring_num[TX] * 2) +
|
||||||
(priv->rx_ring_num * 3);
|
(priv->rx_ring_num * (3 + NUM_XDP_STATS));
|
||||||
case ETH_SS_TEST:
|
case ETH_SS_TEST:
|
||||||
return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.flags
|
return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.flags
|
||||||
& MLX4_DEV_CAP_FLAG_UC_LOOPBACK) * 2;
|
& MLX4_DEV_CAP_FLAG_UC_LOOPBACK) * 2;
|
||||||
|
@ -400,6 +404,10 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev,
|
||||||
if (bitmap_iterator_test(&it))
|
if (bitmap_iterator_test(&it))
|
||||||
data[index++] = ((unsigned long *)&priv->pkstats)[i];
|
data[index++] = ((unsigned long *)&priv->pkstats)[i];
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_XDP_STATS; i++, bitmap_iterator_inc(&it))
|
||||||
|
if (bitmap_iterator_test(&it))
|
||||||
|
data[index++] = ((unsigned long *)&priv->xdp_stats)[i];
|
||||||
|
|
||||||
for (i = 0; i < priv->tx_ring_num[TX]; i++) {
|
for (i = 0; i < priv->tx_ring_num[TX]; i++) {
|
||||||
data[index++] = priv->tx_ring[TX][i]->packets;
|
data[index++] = priv->tx_ring[TX][i]->packets;
|
||||||
data[index++] = priv->tx_ring[TX][i]->bytes;
|
data[index++] = priv->tx_ring[TX][i]->bytes;
|
||||||
|
@ -408,6 +416,9 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev,
|
||||||
data[index++] = priv->rx_ring[i]->packets;
|
data[index++] = priv->rx_ring[i]->packets;
|
||||||
data[index++] = priv->rx_ring[i]->bytes;
|
data[index++] = priv->rx_ring[i]->bytes;
|
||||||
data[index++] = priv->rx_ring[i]->dropped;
|
data[index++] = priv->rx_ring[i]->dropped;
|
||||||
|
data[index++] = priv->rx_ring[i]->xdp_drop;
|
||||||
|
data[index++] = priv->rx_ring[i]->xdp_tx;
|
||||||
|
data[index++] = priv->rx_ring[i]->xdp_tx_full;
|
||||||
}
|
}
|
||||||
spin_unlock_bh(&priv->stats_lock);
|
spin_unlock_bh(&priv->stats_lock);
|
||||||
|
|
||||||
|
@ -470,6 +481,12 @@ static void mlx4_en_get_strings(struct net_device *dev,
|
||||||
strcpy(data + (index++) * ETH_GSTRING_LEN,
|
strcpy(data + (index++) * ETH_GSTRING_LEN,
|
||||||
main_strings[strings]);
|
main_strings[strings]);
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_XDP_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[TX]; i++) {
|
for (i = 0; i < priv->tx_ring_num[TX]; i++) {
|
||||||
sprintf(data + (index++) * ETH_GSTRING_LEN,
|
sprintf(data + (index++) * ETH_GSTRING_LEN,
|
||||||
"tx%d_packets", i);
|
"tx%d_packets", i);
|
||||||
|
@ -483,6 +500,12 @@ static void mlx4_en_get_strings(struct net_device *dev,
|
||||||
"rx%d_bytes", i);
|
"rx%d_bytes", i);
|
||||||
sprintf(data + (index++) * ETH_GSTRING_LEN,
|
sprintf(data + (index++) * ETH_GSTRING_LEN,
|
||||||
"rx%d_dropped", i);
|
"rx%d_dropped", i);
|
||||||
|
sprintf(data + (index++) * ETH_GSTRING_LEN,
|
||||||
|
"rx%d_xdp_drop", i);
|
||||||
|
sprintf(data + (index++) * ETH_GSTRING_LEN,
|
||||||
|
"rx%d_xdp_tx", i);
|
||||||
|
sprintf(data + (index++) * ETH_GSTRING_LEN,
|
||||||
|
"rx%d_xdp_tx_full", i);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ETH_SS_PRIV_FLAGS:
|
case ETH_SS_PRIV_FLAGS:
|
||||||
|
|
|
@ -3125,6 +3125,10 @@ void mlx4_en_set_stats_bitmap(struct mlx4_dev *dev,
|
||||||
|
|
||||||
if (!mlx4_is_slave(dev))
|
if (!mlx4_is_slave(dev))
|
||||||
bitmap_set(stats_bitmap->bitmap, last_i, NUM_PKT_STATS);
|
bitmap_set(stats_bitmap->bitmap, last_i, NUM_PKT_STATS);
|
||||||
|
last_i += NUM_PKT_STATS;
|
||||||
|
|
||||||
|
bitmap_set(stats_bitmap->bitmap, last_i, NUM_XDP_STATS);
|
||||||
|
last_i += NUM_XDP_STATS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
|
int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
|
||||||
|
|
|
@ -179,6 +179,9 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
|
||||||
priv->port_stats.rx_chksum_good = 0;
|
priv->port_stats.rx_chksum_good = 0;
|
||||||
priv->port_stats.rx_chksum_none = 0;
|
priv->port_stats.rx_chksum_none = 0;
|
||||||
priv->port_stats.rx_chksum_complete = 0;
|
priv->port_stats.rx_chksum_complete = 0;
|
||||||
|
priv->xdp_stats.rx_xdp_drop = 0;
|
||||||
|
priv->xdp_stats.rx_xdp_tx = 0;
|
||||||
|
priv->xdp_stats.rx_xdp_tx_full = 0;
|
||||||
for (i = 0; i < priv->rx_ring_num; i++) {
|
for (i = 0; i < priv->rx_ring_num; i++) {
|
||||||
stats->rx_packets += priv->rx_ring[i]->packets;
|
stats->rx_packets += priv->rx_ring[i]->packets;
|
||||||
stats->rx_bytes += priv->rx_ring[i]->bytes;
|
stats->rx_bytes += priv->rx_ring[i]->bytes;
|
||||||
|
@ -186,6 +189,9 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
|
||||||
priv->port_stats.rx_chksum_good += priv->rx_ring[i]->csum_ok;
|
priv->port_stats.rx_chksum_good += priv->rx_ring[i]->csum_ok;
|
||||||
priv->port_stats.rx_chksum_none += priv->rx_ring[i]->csum_none;
|
priv->port_stats.rx_chksum_none += priv->rx_ring[i]->csum_none;
|
||||||
priv->port_stats.rx_chksum_complete += priv->rx_ring[i]->csum_complete;
|
priv->port_stats.rx_chksum_complete += priv->rx_ring[i]->csum_complete;
|
||||||
|
priv->xdp_stats.rx_xdp_drop += priv->rx_ring[i]->xdp_drop;
|
||||||
|
priv->xdp_stats.rx_xdp_tx += priv->rx_ring[i]->xdp_tx;
|
||||||
|
priv->xdp_stats.rx_xdp_tx_full += priv->rx_ring[i]->xdp_tx_full;
|
||||||
}
|
}
|
||||||
stats->tx_packets = 0;
|
stats->tx_packets = 0;
|
||||||
stats->tx_bytes = 0;
|
stats->tx_bytes = 0;
|
||||||
|
|
|
@ -875,8 +875,6 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
|
||||||
*/
|
*/
|
||||||
length = be32_to_cpu(cqe->byte_cnt);
|
length = be32_to_cpu(cqe->byte_cnt);
|
||||||
length -= ring->fcs_del;
|
length -= ring->fcs_del;
|
||||||
ring->bytes += length;
|
|
||||||
ring->packets++;
|
|
||||||
l2_tunnel = (dev->hw_enc_features & NETIF_F_RXCSUM) &&
|
l2_tunnel = (dev->hw_enc_features & NETIF_F_RXCSUM) &&
|
||||||
(cqe->vlan_my_qpn & cpu_to_be32(MLX4_CQE_L2_TUNNEL));
|
(cqe->vlan_my_qpn & cpu_to_be32(MLX4_CQE_L2_TUNNEL));
|
||||||
|
|
||||||
|
@ -902,22 +900,26 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
|
||||||
case XDP_PASS:
|
case XDP_PASS:
|
||||||
break;
|
break;
|
||||||
case XDP_TX:
|
case XDP_TX:
|
||||||
if (likely(!mlx4_en_xmit_frame(frags, dev,
|
if (likely(!mlx4_en_xmit_frame(ring, frags, dev,
|
||||||
length, cq->ring,
|
length, cq->ring,
|
||||||
&doorbell_pending)))
|
&doorbell_pending)))
|
||||||
goto consumed;
|
goto consumed;
|
||||||
goto xdp_drop; /* Drop on xmit failure */
|
goto xdp_drop_no_cnt; /* Drop on xmit failure */
|
||||||
default:
|
default:
|
||||||
bpf_warn_invalid_xdp_action(act);
|
bpf_warn_invalid_xdp_action(act);
|
||||||
case XDP_ABORTED:
|
case XDP_ABORTED:
|
||||||
case XDP_DROP:
|
case XDP_DROP:
|
||||||
xdp_drop:
|
ring->xdp_drop++;
|
||||||
|
xdp_drop_no_cnt:
|
||||||
if (likely(mlx4_en_rx_recycle(ring, frags)))
|
if (likely(mlx4_en_rx_recycle(ring, frags)))
|
||||||
goto consumed;
|
goto consumed;
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ring->bytes += length;
|
||||||
|
ring->packets++;
|
||||||
|
|
||||||
if (likely(dev->features & NETIF_F_RXCSUM)) {
|
if (likely(dev->features & NETIF_F_RXCSUM)) {
|
||||||
if (cqe->status & cpu_to_be16(MLX4_CQE_STATUS_TCP |
|
if (cqe->status & cpu_to_be16(MLX4_CQE_STATUS_TCP |
|
||||||
MLX4_CQE_STATUS_UDP)) {
|
MLX4_CQE_STATUS_UDP)) {
|
||||||
|
|
|
@ -1079,7 +1079,8 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
return NETDEV_TX_OK;
|
return NETDEV_TX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
netdev_tx_t mlx4_en_xmit_frame(struct mlx4_en_rx_alloc *frame,
|
netdev_tx_t mlx4_en_xmit_frame(struct mlx4_en_rx_ring *rx_ring,
|
||||||
|
struct mlx4_en_rx_alloc *frame,
|
||||||
struct net_device *dev, unsigned int length,
|
struct net_device *dev, unsigned int length,
|
||||||
int tx_ind, int *doorbell_pending)
|
int tx_ind, int *doorbell_pending)
|
||||||
{
|
{
|
||||||
|
@ -1154,8 +1155,7 @@ netdev_tx_t mlx4_en_xmit_frame(struct mlx4_en_rx_alloc *frame,
|
||||||
((ring->prod & ring->size) ?
|
((ring->prod & ring->size) ?
|
||||||
cpu_to_be32(MLX4_EN_BIT_DESC_OWN) : 0);
|
cpu_to_be32(MLX4_EN_BIT_DESC_OWN) : 0);
|
||||||
|
|
||||||
ring->packets++;
|
rx_ring->xdp_tx++;
|
||||||
ring->bytes += tx_info->nr_bytes;
|
|
||||||
AVG_PERF_COUNTER(priv->pstats.tx_pktsz_avg, length);
|
AVG_PERF_COUNTER(priv->pstats.tx_pktsz_avg, length);
|
||||||
|
|
||||||
ring->prod += nr_txbb;
|
ring->prod += nr_txbb;
|
||||||
|
@ -1179,7 +1179,7 @@ netdev_tx_t mlx4_en_xmit_frame(struct mlx4_en_rx_alloc *frame,
|
||||||
return NETDEV_TX_OK;
|
return NETDEV_TX_OK;
|
||||||
|
|
||||||
tx_drop_count:
|
tx_drop_count:
|
||||||
ring->tx_dropped++;
|
rx_ring->xdp_tx_full++;
|
||||||
tx_drop:
|
tx_drop:
|
||||||
return NETDEV_TX_BUSY;
|
return NETDEV_TX_BUSY;
|
||||||
}
|
}
|
||||||
|
|
|
@ -350,6 +350,9 @@ struct mlx4_en_rx_ring {
|
||||||
unsigned long csum_ok;
|
unsigned long csum_ok;
|
||||||
unsigned long csum_none;
|
unsigned long csum_none;
|
||||||
unsigned long csum_complete;
|
unsigned long csum_complete;
|
||||||
|
unsigned long xdp_drop;
|
||||||
|
unsigned long xdp_tx;
|
||||||
|
unsigned long xdp_tx_full;
|
||||||
unsigned long dropped;
|
unsigned long dropped;
|
||||||
int hwtstamp_rx_filter;
|
int hwtstamp_rx_filter;
|
||||||
cpumask_var_t affinity_mask;
|
cpumask_var_t affinity_mask;
|
||||||
|
@ -599,6 +602,7 @@ struct mlx4_en_priv {
|
||||||
struct mlx4_en_flow_stats_rx rx_flowstats;
|
struct mlx4_en_flow_stats_rx rx_flowstats;
|
||||||
struct mlx4_en_flow_stats_tx tx_flowstats;
|
struct mlx4_en_flow_stats_tx tx_flowstats;
|
||||||
struct mlx4_en_port_stats port_stats;
|
struct mlx4_en_port_stats port_stats;
|
||||||
|
struct mlx4_en_xdp_stats xdp_stats;
|
||||||
struct mlx4_en_stats_bitmap stats_bitmap;
|
struct mlx4_en_stats_bitmap stats_bitmap;
|
||||||
struct list_head mc_list;
|
struct list_head mc_list;
|
||||||
struct list_head curr_list;
|
struct list_head curr_list;
|
||||||
|
@ -687,7 +691,8 @@ void mlx4_en_tx_irq(struct mlx4_cq *mcq);
|
||||||
u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb,
|
u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb,
|
||||||
void *accel_priv, select_queue_fallback_t fallback);
|
void *accel_priv, select_queue_fallback_t fallback);
|
||||||
netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev);
|
netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev);
|
||||||
netdev_tx_t mlx4_en_xmit_frame(struct mlx4_en_rx_alloc *frame,
|
netdev_tx_t mlx4_en_xmit_frame(struct mlx4_en_rx_ring *rx_ring,
|
||||||
|
struct mlx4_en_rx_alloc *frame,
|
||||||
struct net_device *dev, unsigned int length,
|
struct net_device *dev, unsigned int length,
|
||||||
int tx_ind, int *doorbell_pending);
|
int tx_ind, int *doorbell_pending);
|
||||||
void mlx4_en_xmit_doorbell(struct mlx4_en_tx_ring *ring);
|
void mlx4_en_xmit_doorbell(struct mlx4_en_tx_ring *ring);
|
||||||
|
|
|
@ -55,6 +55,13 @@ struct mlx4_en_perf_stats {
|
||||||
#define NUM_PERF_COUNTERS 6
|
#define NUM_PERF_COUNTERS 6
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mlx4_en_xdp_stats {
|
||||||
|
unsigned long rx_xdp_drop;
|
||||||
|
unsigned long rx_xdp_tx;
|
||||||
|
unsigned long rx_xdp_tx_full;
|
||||||
|
#define NUM_XDP_STATS 3
|
||||||
|
};
|
||||||
|
|
||||||
#define NUM_MAIN_STATS 21
|
#define NUM_MAIN_STATS 21
|
||||||
|
|
||||||
#define MLX4_NUM_PRIORITIES 8
|
#define MLX4_NUM_PRIORITIES 8
|
||||||
|
@ -107,7 +114,8 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NUM_ALL_STATS (NUM_MAIN_STATS + NUM_PORT_STATS + NUM_PKT_STATS + \
|
#define NUM_ALL_STATS (NUM_MAIN_STATS + NUM_PORT_STATS + NUM_PKT_STATS + \
|
||||||
NUM_FLOW_STATS + NUM_PERF_STATS + NUM_PF_STATS)
|
NUM_FLOW_STATS + NUM_PERF_STATS + NUM_PF_STATS + \
|
||||||
|
NUM_XDP_STATS)
|
||||||
|
|
||||||
#define MLX4_FIND_NETDEV_STAT(n) (offsetof(struct net_device_stats, n) / \
|
#define MLX4_FIND_NETDEV_STAT(n) (offsetof(struct net_device_stats, n) / \
|
||||||
sizeof(((struct net_device_stats *)0)->n))
|
sizeof(((struct net_device_stats *)0)->n))
|
||||||
|
|
Loading…
Reference in New Issue