lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
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