You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
250 lines
8.7 KiB
250 lines
8.7 KiB
From a4477af740ee30edca0c22965bb75d9a59a68e96 Mon Sep 17 00:00:00 2001
|
|
From: Igor Russkikh <irusskik@redhat.com>
|
|
Date: Fri, 6 Nov 2020 18:37:54 -0500
|
|
Subject: [PATCH 097/139] [netdrv] net: atlantic: per-TC queue statistics
|
|
|
|
Message-id: <1604687916-15087-98-git-send-email-irusskik@redhat.com>
|
|
Patchwork-id: 338522
|
|
Patchwork-instance: patchwork
|
|
O-Subject: [RHEL8.4 BZ 1857861 097/139] net: atlantic: per-TC queue statistics
|
|
Bugzilla: 1857861
|
|
RH-Acked-by: David Arcari <darcari@redhat.com>
|
|
RH-Acked-by: John Linville <linville@redhat.com>
|
|
RH-Acked-by: Tony Camuso <tcamuso@redhat.com>
|
|
|
|
Bugzilla: http://bugzilla.redhat.com/1857861
|
|
|
|
commit 4272ba8b11f88be8daca5e2477bfe110145d559c
|
|
Author: Mark Starovoytov <mstarovoitov@marvell.com>
|
|
Date: Fri May 22 11:19:41 2020 +0300
|
|
|
|
net: atlantic: per-TC queue statistics
|
|
|
|
This patch adds support for per-TC queue statistics.
|
|
|
|
By default (single TC), the output is the same as it used to be, e.g.:
|
|
Queue[0] InPackets: 2
|
|
Queue[0] OutPackets: 8
|
|
Queue[0] Restarts: 0
|
|
Queue[0] InJumboPackets: 0
|
|
Queue[0] InLroPackets: 0
|
|
Queue[0] InErrors: 0
|
|
|
|
If several TCs are enabled, then each queue statistics line is prefixed
|
|
with TC number, e.g.:
|
|
TC0 Queue[0] InPackets: 6
|
|
TC0 Queue[0] OutPackets: 11
|
|
Queue numbering is end-to-end, so:
|
|
TC1 Queue[4] InPackets: 0
|
|
TC1 Queue[4] OutPackets: 22
|
|
|
|
Signed-off-by: Mark Starovoytov <mstarovoitov@marvell.com>
|
|
Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
|
|
Signed-off-by: Igor Russkikh <irusskik@redhat.com>
|
|
|
|
Cc: David Arcari <darcari@redhat.com>
|
|
Cc: Igor Russkikh <irusskik@redhat.com>
|
|
Signed-off-by: Jan Stancek <jstancek@redhat.com>
|
|
---
|
|
.../net/ethernet/aquantia/atlantic/aq_ethtool.c | 49 ++++++++++++++--------
|
|
drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 12 ++++--
|
|
drivers/net/ethernet/aquantia/atlantic/aq_vec.c | 24 ++++++-----
|
|
drivers/net/ethernet/aquantia/atlantic/aq_vec.h | 5 +--
|
|
4 files changed, 54 insertions(+), 36 deletions(-)
|
|
|
|
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
|
|
index a0d8f9366e1b..e0d45cda1d11 100644
|
|
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
|
|
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
|
|
@@ -87,13 +87,13 @@ static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = {
|
|
"InDroppedDma",
|
|
};
|
|
|
|
-static const char aq_ethtool_queue_stat_names[][ETH_GSTRING_LEN] = {
|
|
- "Queue[%d] InPackets",
|
|
- "Queue[%d] OutPackets",
|
|
- "Queue[%d] Restarts",
|
|
- "Queue[%d] InJumboPackets",
|
|
- "Queue[%d] InLroPackets",
|
|
- "Queue[%d] InErrors",
|
|
+static const char * const aq_ethtool_queue_stat_names[] = {
|
|
+ "%sQueue[%d] InPackets",
|
|
+ "%sQueue[%d] OutPackets",
|
|
+ "%sQueue[%d] Restarts",
|
|
+ "%sQueue[%d] InJumboPackets",
|
|
+ "%sQueue[%d] InLroPackets",
|
|
+ "%sQueue[%d] InErrors",
|
|
};
|
|
|
|
static const char aq_ethtool_priv_flag_names[][ETH_GSTRING_LEN] = {
|
|
@@ -109,7 +109,8 @@ static u32 aq_ethtool_n_stats(struct net_device *ndev)
|
|
struct aq_nic_s *nic = netdev_priv(ndev);
|
|
struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(nic);
|
|
u32 n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
|
|
- ARRAY_SIZE(aq_ethtool_queue_stat_names) * cfg->vecs;
|
|
+ ARRAY_SIZE(aq_ethtool_queue_stat_names) * cfg->vecs *
|
|
+ cfg->tcs;
|
|
|
|
return n_stats;
|
|
}
|
|
@@ -151,28 +152,40 @@ static void aq_ethtool_get_drvinfo(struct net_device *ndev,
|
|
static void aq_ethtool_get_strings(struct net_device *ndev,
|
|
u32 stringset, u8 *data)
|
|
{
|
|
- struct aq_nic_s *aq_nic = netdev_priv(ndev);
|
|
+ struct aq_nic_s *nic = netdev_priv(ndev);
|
|
struct aq_nic_cfg_s *cfg;
|
|
u8 *p = data;
|
|
int i, si;
|
|
|
|
- cfg = aq_nic_get_cfg(aq_nic);
|
|
+ cfg = aq_nic_get_cfg(nic);
|
|
|
|
switch (stringset) {
|
|
- case ETH_SS_STATS:
|
|
+ case ETH_SS_STATS: {
|
|
+ const int stat_cnt = ARRAY_SIZE(aq_ethtool_queue_stat_names);
|
|
+ char tc_string[8];
|
|
+ int tc;
|
|
+
|
|
+ memset(tc_string, 0, sizeof(tc_string));
|
|
memcpy(p, aq_ethtool_stat_names,
|
|
sizeof(aq_ethtool_stat_names));
|
|
p = p + sizeof(aq_ethtool_stat_names);
|
|
- for (i = 0; i < cfg->vecs; i++) {
|
|
- for (si = 0;
|
|
- si < ARRAY_SIZE(aq_ethtool_queue_stat_names);
|
|
- si++) {
|
|
- snprintf(p, ETH_GSTRING_LEN,
|
|
- aq_ethtool_queue_stat_names[si], i);
|
|
- p += ETH_GSTRING_LEN;
|
|
+
|
|
+ for (tc = 0; tc < cfg->tcs; tc++) {
|
|
+ if (cfg->is_qos)
|
|
+ snprintf(tc_string, 8, "TC%d ", tc);
|
|
+
|
|
+ for (i = 0; i < cfg->vecs; i++) {
|
|
+ for (si = 0; si < stat_cnt; si++) {
|
|
+ snprintf(p, ETH_GSTRING_LEN,
|
|
+ aq_ethtool_queue_stat_names[si],
|
|
+ tc_string,
|
|
+ AQ_NIC_TCVEC2RING(nic, tc, i));
|
|
+ p += ETH_GSTRING_LEN;
|
|
+ }
|
|
}
|
|
}
|
|
break;
|
|
+ }
|
|
case ETH_SS_PRIV_FLAGS:
|
|
memcpy(p, aq_ethtool_priv_flag_names,
|
|
sizeof(aq_ethtool_priv_flag_names));
|
|
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
|
|
index 4cd6b599f31f..ab6f42d6f26f 100644
|
|
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
|
|
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
|
|
@@ -839,6 +839,7 @@ u64 *aq_nic_get_stats(struct aq_nic_s *self, u64 *data)
|
|
struct aq_stats_s *stats;
|
|
unsigned int count = 0U;
|
|
unsigned int i = 0U;
|
|
+ unsigned int tc;
|
|
|
|
if (self->aq_fw_ops->update_stats) {
|
|
mutex_lock(&self->fwreq_mutex);
|
|
@@ -877,10 +878,13 @@ u64 *aq_nic_get_stats(struct aq_nic_s *self, u64 *data)
|
|
|
|
data += i;
|
|
|
|
- for (i = 0U, aq_vec = self->aq_vec[0];
|
|
- aq_vec && self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) {
|
|
- data += count;
|
|
- aq_vec_get_sw_stats(aq_vec, data, &count);
|
|
+ for (tc = 0U; tc < self->aq_nic_cfg.tcs; tc++) {
|
|
+ for (i = 0U, aq_vec = self->aq_vec[0];
|
|
+ aq_vec && self->aq_vecs > i;
|
|
+ ++i, aq_vec = self->aq_vec[i]) {
|
|
+ data += count;
|
|
+ aq_vec_get_sw_stats(aq_vec, tc, data, &count);
|
|
+ }
|
|
}
|
|
|
|
data += count;
|
|
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
|
|
index d5650cd6e236..41826c10700f 100644
|
|
--- a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
|
|
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
|
|
@@ -348,16 +348,14 @@ cpumask_t *aq_vec_get_affinity_mask(struct aq_vec_s *self)
|
|
return &self->aq_ring_param.affinity_mask;
|
|
}
|
|
|
|
-void aq_vec_add_stats(struct aq_vec_s *self,
|
|
- struct aq_ring_stats_rx_s *stats_rx,
|
|
- struct aq_ring_stats_tx_s *stats_tx)
|
|
+static void aq_vec_add_stats(struct aq_vec_s *self,
|
|
+ const unsigned int tc,
|
|
+ struct aq_ring_stats_rx_s *stats_rx,
|
|
+ struct aq_ring_stats_tx_s *stats_tx)
|
|
{
|
|
- struct aq_ring_s *ring = NULL;
|
|
- unsigned int r = 0U;
|
|
+ struct aq_ring_s *ring = self->ring[tc];
|
|
|
|
- for (r = 0U, ring = self->ring[0];
|
|
- self->tx_rings > r; ++r, ring = self->ring[r]) {
|
|
- struct aq_ring_stats_tx_s *tx = &ring[AQ_VEC_TX_ID].stats.tx;
|
|
+ if (tc < self->rx_rings) {
|
|
struct aq_ring_stats_rx_s *rx = &ring[AQ_VEC_RX_ID].stats.rx;
|
|
|
|
stats_rx->packets += rx->packets;
|
|
@@ -368,6 +366,10 @@ void aq_vec_add_stats(struct aq_vec_s *self,
|
|
stats_rx->pg_losts += rx->pg_losts;
|
|
stats_rx->pg_flips += rx->pg_flips;
|
|
stats_rx->pg_reuses += rx->pg_reuses;
|
|
+ }
|
|
+
|
|
+ if (tc < self->tx_rings) {
|
|
+ struct aq_ring_stats_tx_s *tx = &ring[AQ_VEC_TX_ID].stats.tx;
|
|
|
|
stats_tx->packets += tx->packets;
|
|
stats_tx->bytes += tx->bytes;
|
|
@@ -376,7 +378,8 @@ void aq_vec_add_stats(struct aq_vec_s *self,
|
|
}
|
|
}
|
|
|
|
-int aq_vec_get_sw_stats(struct aq_vec_s *self, u64 *data, unsigned int *p_count)
|
|
+int aq_vec_get_sw_stats(struct aq_vec_s *self, const unsigned int tc, u64 *data,
|
|
+ unsigned int *p_count)
|
|
{
|
|
struct aq_ring_stats_rx_s stats_rx;
|
|
struct aq_ring_stats_tx_s stats_tx;
|
|
@@ -384,7 +387,8 @@ int aq_vec_get_sw_stats(struct aq_vec_s *self, u64 *data, unsigned int *p_count)
|
|
|
|
memset(&stats_rx, 0U, sizeof(struct aq_ring_stats_rx_s));
|
|
memset(&stats_tx, 0U, sizeof(struct aq_ring_stats_tx_s));
|
|
- aq_vec_add_stats(self, &stats_rx, &stats_tx);
|
|
+
|
|
+ aq_vec_add_stats(self, tc, &stats_rx, &stats_tx);
|
|
|
|
/* This data should mimic aq_ethtool_queue_stat_names structure
|
|
*/
|
|
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_vec.h b/drivers/net/ethernet/aquantia/atlantic/aq_vec.h
|
|
index 0ee86b26df8a..541af85e6510 100644
|
|
--- a/drivers/net/ethernet/aquantia/atlantic/aq_vec.h
|
|
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_vec.h
|
|
@@ -35,10 +35,7 @@ void aq_vec_ring_free(struct aq_vec_s *self);
|
|
int aq_vec_start(struct aq_vec_s *self);
|
|
void aq_vec_stop(struct aq_vec_s *self);
|
|
cpumask_t *aq_vec_get_affinity_mask(struct aq_vec_s *self);
|
|
-int aq_vec_get_sw_stats(struct aq_vec_s *self, u64 *data,
|
|
+int aq_vec_get_sw_stats(struct aq_vec_s *self, const unsigned int tc, u64 *data,
|
|
unsigned int *p_count);
|
|
-void aq_vec_add_stats(struct aq_vec_s *self,
|
|
- struct aq_ring_stats_rx_s *stats_rx,
|
|
- struct aq_ring_stats_tx_s *stats_tx);
|
|
|
|
#endif /* AQ_VEC_H */
|
|
--
|
|
2.13.6
|
|
|