[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20200715154842.305-3-irusskikh@marvell.com>
Date: Wed, 15 Jul 2020 18:48:34 +0300
From: Igor Russkikh <irusskikh@...vell.com>
To: <netdev@...r.kernel.org>
CC: "David S . Miller" <davem@...emloft.net>,
Mark Starovoytov <mstarovoitov@...vell.com>,
Jakub Kicinski <kuba@...nel.org>,
Dmitry Bogdanov <dbogdanov@...vell.com>,
Igor Russkikh <irusskikh@...vell.com>
Subject: [PATCH v2 net-next 02/10] net: atlantic: additional per-queue stats
From: Dmitry Bogdanov <dbogdanov@...vell.com>
This patch adds additional per-queue stats, these could
be useful for debugging and diagnostics.
Signed-off-by: Dmitry Bogdanov <dbogdanov@...vell.com>
Signed-off-by: Mark Starovoytov <mstarovoitov@...vell.com>
Signed-off-by: Igor Russkikh <irusskikh@...vell.com>
---
.../ethernet/aquantia/atlantic/aq_ethtool.c | 3 ++
.../net/ethernet/aquantia/atlantic/aq_nic.c | 42 ++++++++++++++++-
.../net/ethernet/aquantia/atlantic/aq_nic.h | 6 +++
.../net/ethernet/aquantia/atlantic/aq_ring.c | 4 ++
.../net/ethernet/aquantia/atlantic/aq_ring.h | 10 ++--
.../net/ethernet/aquantia/atlantic/aq_vec.c | 46 +++++--------------
.../net/ethernet/aquantia/atlantic/aq_vec.h | 14 ++++--
7 files changed, 81 insertions(+), 44 deletions(-)
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
index a8f0fbbbd91a..420fa5b791f9 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
@@ -96,6 +96,9 @@ static const char * const aq_ethtool_queue_stat_names[] = {
"%sQueue[%d] InJumboPackets",
"%sQueue[%d] InLroPackets",
"%sQueue[%d] InErrors",
+ "%sQueue[%d] AllocFails",
+ "%sQueue[%d] SkbAllocFails",
+ "%sQueue[%d] Polls",
};
#if IS_ENABLED(CONFIG_MACSEC)
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 43b8914c3ef5..45d99c1a9635 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -857,6 +857,20 @@ int aq_nic_get_regs_count(struct aq_nic_s *self)
return self->aq_nic_cfg.aq_hw_caps->mac_regs_count;
}
+static int aq_nic_get_tc_stats(struct aq_vec_s *vec, 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;
+
+ 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(vec, tc, &stats_rx, &stats_tx);
+
+ return aq_nic_fill_stats_data(&stats_rx, &stats_tx, data, p_count);
+}
+
u64 *aq_nic_get_stats(struct aq_nic_s *self, u64 *data)
{
struct aq_vec_s *aq_vec = NULL;
@@ -907,13 +921,13 @@ u64 *aq_nic_get_stats(struct aq_nic_s *self, u64 *data)
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);
+ aq_nic_get_tc_stats(aq_vec, tc, data, &count);
}
}
data += count;
-err_exit:;
+err_exit:
return data;
}
@@ -932,6 +946,30 @@ static void aq_nic_update_ndev_stats(struct aq_nic_s *self)
ndev->stats.multicast = stats->mprc;
}
+int aq_nic_fill_stats_data(struct aq_ring_stats_rx_s *stats_rx,
+ struct aq_ring_stats_tx_s *stats_tx,
+ u64 *data,
+ unsigned int *p_count)
+{
+ unsigned int count = 0U;
+ /* This data should mimic aq_ethtool_queue_stat_names structure
+ */
+ data[count] += stats_rx->packets;
+ data[++count] += stats_tx->packets;
+ data[++count] += stats_tx->queue_restarts;
+ data[++count] += stats_rx->jumbo_packets;
+ data[++count] += stats_rx->lro_packets;
+ data[++count] += stats_rx->errors;
+ data[++count] += stats_rx->alloc_fails;
+ data[++count] += stats_rx->skb_alloc_fails;
+ data[++count] += stats_rx->polls;
+
+ if (p_count)
+ *p_count = ++count;
+
+ return 0;
+}
+
void aq_nic_get_link_ksettings(struct aq_nic_s *self,
struct ethtool_link_ksettings *cmd)
{
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
index 317bfc646f0a..0c7233d8ecd6 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
@@ -15,6 +15,8 @@
#include "aq_hw.h"
struct aq_ring_s;
+struct aq_ring_stats_rx_s;
+struct aq_ring_stats_tx_s;
struct aq_hw_ops;
struct aq_fw_s;
struct aq_vec_s;
@@ -175,6 +177,10 @@ int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb);
int aq_nic_get_regs(struct aq_nic_s *self, struct ethtool_regs *regs, void *p);
int aq_nic_get_regs_count(struct aq_nic_s *self);
u64 *aq_nic_get_stats(struct aq_nic_s *self, u64 *data);
+int aq_nic_fill_stats_data(struct aq_ring_stats_rx_s *stats_rx,
+ struct aq_ring_stats_tx_s *stats_tx,
+ u64 *data,
+ unsigned int *p_count);
int aq_nic_stop(struct aq_nic_s *self);
void aq_nic_deinit(struct aq_nic_s *self, bool link_down);
void aq_nic_set_power(struct aq_nic_s *self);
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
index 8dd59e9fc3aa..20b606aa7974 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
@@ -88,6 +88,8 @@ static int aq_get_rxpages(struct aq_ring_s *self, struct aq_ring_buff_s *rxbuf,
if (!rxbuf->rxdata.page) {
ret = aq_get_rxpage(&rxbuf->rxdata, order,
aq_nic_get_dev(self->aq_nic));
+ if (ret)
+ self->stats.rx.alloc_fails++;
return ret;
}
@@ -392,6 +394,7 @@ int aq_ring_rx_clean(struct aq_ring_s *self,
skb = build_skb(aq_buf_vaddr(&buff->rxdata),
AQ_CFG_RX_FRAME_MAX);
if (unlikely(!skb)) {
+ self->stats.rx.skb_alloc_fails++;
err = -ENOMEM;
goto err_exit;
}
@@ -405,6 +408,7 @@ int aq_ring_rx_clean(struct aq_ring_s *self,
} else {
skb = napi_alloc_skb(napi, AQ_CFG_RX_HDR_SIZE);
if (unlikely(!skb)) {
+ self->stats.rx.skb_alloc_fails++;
err = -ENOMEM;
goto err_exit;
}
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
index 2c96f20f6289..0e40ccbaf19a 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
@@ -1,7 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * aQuantia Corporation Network Driver
- * Copyright (C) 2014-2019 aQuantia Corporation. All rights reserved
+/* Atlantic Network Driver
+ *
+ * Copyright (C) 2014-2019 aQuantia Corporation
+ * Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File aq_ring.h: Declaration of functions for Rx/Tx rings. */
@@ -93,6 +94,9 @@ struct aq_ring_stats_rx_s {
u64 bytes;
u64 lro_packets;
u64 jumbo_packets;
+ u64 alloc_fails;
+ u64 skb_alloc_fails;
+ u64 polls;
u64 pg_losts;
u64 pg_flips;
u64 pg_reuses;
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
index d1d43c8ce400..eafcb98c274f 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
@@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-only
-/*
- * aQuantia Corporation Network Driver
- * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
+/* Atlantic Network Driver
+ *
+ * Copyright (C) 2014-2019 aQuantia Corporation
+ * Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File aq_vec.c: Definition of common structure for vector of Rx and Tx rings.
@@ -44,6 +45,7 @@ static int aq_vec_poll(struct napi_struct *napi, int budget)
} else {
for (i = 0U, ring = self->ring[0];
self->tx_rings > i; ++i, ring = self->ring[i]) {
+ ring[AQ_VEC_RX_ID].stats.rx.polls++;
if (self->aq_hw_ops->hw_ring_tx_head_update) {
err = self->aq_hw_ops->hw_ring_tx_head_update(
self->aq_hw,
@@ -349,10 +351,10 @@ cpumask_t *aq_vec_get_affinity_mask(struct aq_vec_s *self)
return &self->aq_ring_param.affinity_mask;
}
-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)
+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 = self->ring[tc];
@@ -364,6 +366,9 @@ static void aq_vec_add_stats(struct aq_vec_s *self,
stats_rx->errors += rx->errors;
stats_rx->jumbo_packets += rx->jumbo_packets;
stats_rx->lro_packets += rx->lro_packets;
+ stats_rx->alloc_fails += rx->alloc_fails;
+ stats_rx->skb_alloc_fails += rx->skb_alloc_fails;
+ stats_rx->polls += rx->polls;
stats_rx->pg_losts += rx->pg_losts;
stats_rx->pg_flips += rx->pg_flips;
stats_rx->pg_reuses += rx->pg_reuses;
@@ -378,30 +383,3 @@ static void aq_vec_add_stats(struct aq_vec_s *self,
stats_tx->queue_restarts += tx->queue_restarts;
}
}
-
-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;
- unsigned int count = 0U;
-
- 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, tc, &stats_rx, &stats_tx);
-
- /* This data should mimic aq_ethtool_queue_stat_names structure
- */
- data[count] += stats_rx.packets;
- data[++count] += stats_tx.packets;
- data[++count] += stats_tx.queue_restarts;
- data[++count] += stats_rx.jumbo_packets;
- data[++count] += stats_rx.lro_packets;
- data[++count] += stats_rx.errors;
-
- if (p_count)
- *p_count = ++count;
-
- return 0;
-}
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_vec.h b/drivers/net/ethernet/aquantia/atlantic/aq_vec.h
index 541af85e6510..876781a1e2b3 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_vec.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_vec.h
@@ -1,7 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * aQuantia Corporation Network Driver
- * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
+/* Atlantic Network Driver
+ *
+ * Copyright (C) 2014-2019 aQuantia Corporation
+ * Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File aq_vec.h: Definition of common structures for vector of Rx and Tx rings.
@@ -35,7 +36,10 @@ 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, const unsigned int tc, u64 *data,
- unsigned int *p_count);
+
+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);
#endif /* AQ_VEC_H */
--
2.25.1
Powered by blists - more mailing lists