All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
To: dev@dpdk.org
Cc: Ivan Ilchenko <ivan.ilchenko@oktetlabs.ru>,
	Andy Moreton <amoreton@xilinx.com>
Subject: [dpdk-dev] [PATCH 10/11] net/sfc: add xstats for Rx/Tx doorbells
Date: Fri,  4 Jun 2021 17:42:24 +0300	[thread overview]
Message-ID: <20210604144225.287678-11-andrew.rybchenko@oktetlabs.ru> (raw)
In-Reply-To: <20210604144225.287678-1-andrew.rybchenko@oktetlabs.ru>

From: Ivan Ilchenko <ivan.ilchenko@oktetlabs.ru>

Rx/Tx doorbells statistics are collected in software and
available per queue. These stats are useful for performance
investigation.

Signed-off-by: Ivan Ilchenko <ivan.ilchenko@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
---
 drivers/net/sfc/meson.build        |   1 +
 drivers/net/sfc/sfc.c              |  16 +
 drivers/net/sfc/sfc.h              |   9 +
 drivers/net/sfc/sfc_dp.h           |  10 +
 drivers/net/sfc/sfc_ef10.h         |   3 +-
 drivers/net/sfc/sfc_ef100_rx.c     |   1 +
 drivers/net/sfc/sfc_ef100_tx.c     |   1 +
 drivers/net/sfc/sfc_ef10_essb_rx.c |   3 +-
 drivers/net/sfc/sfc_ef10_rx.c      |   3 +-
 drivers/net/sfc/sfc_ef10_tx.c      |   1 +
 drivers/net/sfc/sfc_ethdev.c       | 124 +++++--
 drivers/net/sfc/sfc_port.c         |  10 +-
 drivers/net/sfc/sfc_rx.c           |   1 +
 drivers/net/sfc/sfc_sw_stats.c     | 572 +++++++++++++++++++++++++++++
 drivers/net/sfc/sfc_sw_stats.h     |  49 +++
 drivers/net/sfc/sfc_tx.c           |   4 +-
 16 files changed, 772 insertions(+), 36 deletions(-)
 create mode 100644 drivers/net/sfc/sfc_sw_stats.c
 create mode 100644 drivers/net/sfc/sfc_sw_stats.h

diff --git a/drivers/net/sfc/meson.build b/drivers/net/sfc/meson.build
index 32b58e3d76..c40c8e12fe 100644
--- a/drivers/net/sfc/meson.build
+++ b/drivers/net/sfc/meson.build
@@ -56,6 +56,7 @@ sources = files(
         'sfc.c',
         'sfc_mcdi.c',
         'sfc_sriov.c',
+        'sfc_sw_stats.c',
         'sfc_intr.c',
         'sfc_ev.c',
         'sfc_port.c',
diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index 4097cf39de..274a98e228 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -24,6 +24,7 @@
 #include "sfc_tx.h"
 #include "sfc_kvargs.h"
 #include "sfc_tweak.h"
+#include "sfc_sw_stats.h"
 
 
 int
@@ -636,10 +637,17 @@ sfc_configure(struct sfc_adapter *sa)
 	if (rc != 0)
 		goto fail_tx_configure;
 
+	rc = sfc_sw_xstats_configure(sa);
+	if (rc != 0)
+		goto fail_sw_xstats_configure;
+
 	sa->state = SFC_ADAPTER_CONFIGURED;
 	sfc_log_init(sa, "done");
 	return 0;
 
+fail_sw_xstats_configure:
+	sfc_tx_close(sa);
+
 fail_tx_configure:
 	sfc_rx_close(sa);
 
@@ -666,6 +674,7 @@ sfc_close(struct sfc_adapter *sa)
 	SFC_ASSERT(sa->state == SFC_ADAPTER_CONFIGURED);
 	sa->state = SFC_ADAPTER_CLOSING;
 
+	sfc_sw_xstats_close(sa);
 	sfc_tx_close(sa);
 	sfc_rx_close(sa);
 	sfc_port_close(sa);
@@ -891,6 +900,10 @@ sfc_attach(struct sfc_adapter *sa)
 
 	sfc_flow_init(sa);
 
+	rc = sfc_sw_xstats_init(sa);
+	if (rc != 0)
+		goto fail_sw_xstats_init;
+
 	/*
 	 * Create vSwitch to be able to use VFs when PF is not started yet
 	 * as DPDK port. VFs should be able to talk to each other even
@@ -906,6 +919,9 @@ sfc_attach(struct sfc_adapter *sa)
 	return 0;
 
 fail_sriov_vswitch_create:
+	sfc_sw_xstats_close(sa);
+
+fail_sw_xstats_init:
 	sfc_flow_fini(sa);
 	sfc_mae_detach(sa);
 
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 58b8c2c2ad..331e06bac6 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -217,6 +217,14 @@ struct sfc_counter_rxq {
 	struct rte_mempool		*mp;
 };
 
+struct sfc_sw_xstats {
+	uint64_t			*reset_vals;
+
+	rte_spinlock_t			queues_bitmap_lock;
+	void				*queues_bitmap_mem;
+	struct rte_bitmap		*queues_bitmap;
+};
+
 /* Adapter private data */
 struct sfc_adapter {
 	/*
@@ -249,6 +257,7 @@ struct sfc_adapter {
 	struct sfc_sriov		sriov;
 	struct sfc_intr			intr;
 	struct sfc_port			port;
+	struct sfc_sw_xstats		sw_xstats;
 	struct sfc_filter		filter;
 	struct sfc_mae			mae;
 
diff --git a/drivers/net/sfc/sfc_dp.h b/drivers/net/sfc/sfc_dp.h
index 61c1a3fbac..7fd8f34b0f 100644
--- a/drivers/net/sfc/sfc_dp.h
+++ b/drivers/net/sfc/sfc_dp.h
@@ -42,6 +42,16 @@ enum sfc_dp_type {
 
 /** Datapath queue run-time information */
 struct sfc_dp_queue {
+	/*
+	 * Typically the structure is located at the end of Rx/Tx queue
+	 * data structure and not used on datapath. So, it is not a
+	 * problem to have extra fields even if not used. However,
+	 * put stats at top of the structure to be closer to fields
+	 * used on datapath or reap to have more chances to be cache-hot.
+	 */
+	uint32_t			rx_dbells;
+	uint32_t			tx_dbells;
+
 	uint16_t			port_id;
 	uint16_t			queue_id;
 	struct rte_pci_addr		pci_addr;
diff --git a/drivers/net/sfc/sfc_ef10.h b/drivers/net/sfc/sfc_ef10.h
index ad4c1fdbef..e9bb72e28b 100644
--- a/drivers/net/sfc/sfc_ef10.h
+++ b/drivers/net/sfc/sfc_ef10.h
@@ -99,7 +99,7 @@ sfc_ef10_ev_present(const efx_qword_t ev)
 
 static inline void
 sfc_ef10_rx_qpush(volatile void *doorbell, unsigned int added,
-		  unsigned int ptr_mask)
+		  unsigned int ptr_mask, uint32_t *dbell_counter)
 {
 	efx_dword_t dword;
 
@@ -118,6 +118,7 @@ sfc_ef10_rx_qpush(volatile void *doorbell, unsigned int added,
 	 * operations that follow it (i.e. doorbell write).
 	 */
 	rte_write32(dword.ed_u32[0], doorbell);
+	(*dbell_counter)++;
 }
 
 static inline void
diff --git a/drivers/net/sfc/sfc_ef100_rx.c b/drivers/net/sfc/sfc_ef100_rx.c
index 7447f8b9de..832236a6d0 100644
--- a/drivers/net/sfc/sfc_ef100_rx.c
+++ b/drivers/net/sfc/sfc_ef100_rx.c
@@ -119,6 +119,7 @@ sfc_ef100_rx_qpush(struct sfc_ef100_rxq *rxq, unsigned int added)
 	 * operations that follow it (i.e. doorbell write).
 	 */
 	rte_write32(dword.ed_u32[0], rxq->doorbell);
+	rxq->dp.dpq.rx_dbells++;
 
 	sfc_ef100_rx_debug(rxq, "RxQ pushed doorbell at pidx %u (added=%u)",
 			   EFX_DWORD_FIELD(dword, ERF_GZ_RX_RING_PIDX),
diff --git a/drivers/net/sfc/sfc_ef100_tx.c b/drivers/net/sfc/sfc_ef100_tx.c
index f9ad6f7b73..522e9a0d34 100644
--- a/drivers/net/sfc/sfc_ef100_tx.c
+++ b/drivers/net/sfc/sfc_ef100_tx.c
@@ -489,6 +489,7 @@ sfc_ef100_tx_qpush(struct sfc_ef100_txq *txq, unsigned int added)
 	 * operations that follow it (i.e. doorbell write).
 	 */
 	rte_write32(dword.ed_u32[0], txq->doorbell);
+	txq->dp.dpq.tx_dbells++;
 
 	sfc_ef100_tx_debug(txq, "TxQ pushed doorbell at pidx %u (added=%u)",
 			   EFX_DWORD_FIELD(dword, ERF_GZ_TX_RING_PIDX),
diff --git a/drivers/net/sfc/sfc_ef10_essb_rx.c b/drivers/net/sfc/sfc_ef10_essb_rx.c
index 3c246eb149..991329e86f 100644
--- a/drivers/net/sfc/sfc_ef10_essb_rx.c
+++ b/drivers/net/sfc/sfc_ef10_essb_rx.c
@@ -220,7 +220,8 @@ sfc_ef10_essb_rx_qrefill(struct sfc_ef10_essb_rxq *rxq)
 
 	SFC_ASSERT(rxq->added != added);
 	rxq->added = added;
-	sfc_ef10_rx_qpush(rxq->doorbell, added, rxq_ptr_mask);
+	sfc_ef10_rx_qpush(rxq->doorbell, added, rxq_ptr_mask,
+			  &rxq->dp.dpq.rx_dbells);
 }
 
 static bool
diff --git a/drivers/net/sfc/sfc_ef10_rx.c b/drivers/net/sfc/sfc_ef10_rx.c
index 2b4393d232..49a7d4fb42 100644
--- a/drivers/net/sfc/sfc_ef10_rx.c
+++ b/drivers/net/sfc/sfc_ef10_rx.c
@@ -171,7 +171,8 @@ sfc_ef10_rx_qrefill(struct sfc_ef10_rxq *rxq)
 
 	SFC_ASSERT(rxq->added != added);
 	rxq->added = added;
-	sfc_ef10_rx_qpush(rxq->doorbell, added, ptr_mask);
+	sfc_ef10_rx_qpush(rxq->doorbell, added, ptr_mask,
+			  &rxq->dp.dpq.rx_dbells);
 }
 
 static void
diff --git a/drivers/net/sfc/sfc_ef10_tx.c b/drivers/net/sfc/sfc_ef10_tx.c
index a8d34ead33..ed43adb4ca 100644
--- a/drivers/net/sfc/sfc_ef10_tx.c
+++ b/drivers/net/sfc/sfc_ef10_tx.c
@@ -248,6 +248,7 @@ sfc_ef10_tx_qpush(struct sfc_ef10_txq *txq, unsigned int added,
 	rte_io_wmb();
 
 	*(volatile efsys_uint128_t *)txq->doorbell = oword.eo_u128[0];
+	txq->dp.dpq.tx_dbells++;
 }
 
 static unsigned int
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index dd7e5c253a..2db0d000c3 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -28,6 +28,10 @@
 #include "sfc_flow.h"
 #include "sfc_dp.h"
 #include "sfc_dp_rx.h"
+#include "sfc_sw_stats.h"
+
+#define SFC_XSTAT_ID_INVALID_VAL  UINT64_MAX
+#define SFC_XSTAT_ID_INVALID_NAME '\0'
 
 uint32_t sfc_logtype_driver;
 
@@ -714,29 +718,49 @@ sfc_stats_reset(struct rte_eth_dev *dev)
 	if (rc != 0)
 		sfc_err(sa, "failed to reset statistics (rc = %d)", rc);
 
+	sfc_sw_xstats_reset(sa);
+
 	sfc_adapter_unlock(sa);
 
 	SFC_ASSERT(rc >= 0);
 	return -rc;
 }
 
+static unsigned int
+sfc_xstats_get_nb_supported(struct sfc_adapter *sa)
+{
+	struct sfc_port *port = &sa->port;
+	unsigned int nb_supported;
+
+	sfc_adapter_lock(sa);
+	nb_supported = port->mac_stats_nb_supported +
+		       sfc_sw_xstats_get_nb_supported(sa);
+	sfc_adapter_unlock(sa);
+
+	return nb_supported;
+}
+
 static int
 sfc_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
 	       unsigned int xstats_count)
 {
 	struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
-	struct sfc_port *port = &sa->port;
 	unsigned int nb_written = 0;
-	unsigned int nb_supp;
+	unsigned int nb_supported = 0;
+	int rc;
 
-	if (unlikely(xstats == NULL)) {
-		sfc_adapter_lock(sa);
-		nb_supp = port->mac_stats_nb_supported;
-		sfc_adapter_unlock(sa);
-		return nb_supp;
-	}
+	if (unlikely(xstats == NULL))
+		return sfc_xstats_get_nb_supported(sa);
+
+	rc = sfc_port_get_mac_stats(sa, xstats, xstats_count, &nb_written);
+	if (rc < 0)
+		return rc;
 
-	return sfc_port_get_mac_stats(sa, xstats, xstats_count, &nb_written);
+	nb_supported = rc;
+	sfc_sw_xstats_get_vals(sa, xstats, xstats_count, &nb_written,
+			       &nb_supported);
+
+	return nb_supported;
 }
 
 static int
@@ -748,24 +772,31 @@ sfc_xstats_get_names(struct rte_eth_dev *dev,
 	struct sfc_port *port = &sa->port;
 	unsigned int i;
 	unsigned int nstats = 0;
+	unsigned int nb_written = 0;
+	int ret;
 
-	if (unlikely(xstats_names == NULL)) {
-		sfc_adapter_lock(sa);
-		nstats = port->mac_stats_nb_supported;
-		sfc_adapter_unlock(sa);
-		return nstats;
-	}
+	if (unlikely(xstats_names == NULL))
+		return sfc_xstats_get_nb_supported(sa);
 
 	for (i = 0; i < EFX_MAC_NSTATS; ++i) {
 		if (EFX_MAC_STAT_SUPPORTED(port->mac_stats_mask, i)) {
-			if (nstats < xstats_count)
+			if (nstats < xstats_count) {
 				strlcpy(xstats_names[nstats].name,
 					efx_mac_stat_name(sa->nic, i),
 					sizeof(xstats_names[0].name));
+				nb_written++;
+			}
 			nstats++;
 		}
 	}
 
+	ret = sfc_sw_xstats_get_names(sa, xstats_names, xstats_count,
+				      &nb_written, &nstats);
+	if (ret != 0) {
+		SFC_ASSERT(ret < 0);
+		return ret;
+	}
+
 	return nstats;
 }
 
@@ -774,11 +805,35 @@ sfc_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
 		     uint64_t *values, unsigned int n)
 {
 	struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
+	struct sfc_port *port = &sa->port;
+	unsigned int nb_supported;
+	unsigned int i;
+	int rc;
 
 	if (unlikely(ids == NULL || values == NULL))
 		return -EINVAL;
 
-	return sfc_port_get_mac_stats_by_id(sa, ids, values, n);
+	/*
+	 * Values array could be filled in nonsequential order. Fill values with
+	 * constant indicating invalid ID first.
+	 */
+	for (i = 0; i < n; i++)
+		values[i] = SFC_XSTAT_ID_INVALID_VAL;
+
+	rc = sfc_port_get_mac_stats_by_id(sa, ids, values, n);
+	if (rc != 0)
+		return rc;
+
+	nb_supported = port->mac_stats_nb_supported;
+	sfc_sw_xstats_get_vals_by_id(sa, ids, values, n, &nb_supported);
+
+	/* Return number of written stats before invalid ID is encountered. */
+	for (i = 0; i < n; i++) {
+		if (values[i] == SFC_XSTAT_ID_INVALID_VAL)
+			return i;
+	}
+
+	return n;
 }
 
 static int
@@ -790,18 +845,23 @@ sfc_xstats_get_names_by_id(struct rte_eth_dev *dev,
 	struct sfc_port *port = &sa->port;
 	unsigned int nb_supported;
 	unsigned int i;
+	int ret;
 
 	if (unlikely(xstats_names == NULL && ids != NULL) ||
 	    unlikely(xstats_names != NULL && ids == NULL))
 		return -EINVAL;
 
-	sfc_adapter_lock(sa);
+	if (unlikely(xstats_names == NULL && ids == NULL))
+		return sfc_xstats_get_nb_supported(sa);
 
-	if (unlikely(xstats_names == NULL && ids == NULL)) {
-		nb_supported = port->mac_stats_nb_supported;
-		sfc_adapter_unlock(sa);
-		return nb_supported;
-	}
+	/*
+	 * Names array could be filled in nonsequential order. Fill names with
+	 * string indicating invalid ID first.
+	 */
+	for (i = 0; i < size; i++)
+		xstats_names[i].name[0] = SFC_XSTAT_ID_INVALID_NAME;
+
+	sfc_adapter_lock(sa);
 
 	SFC_ASSERT(port->mac_stats_nb_supported <=
 		   RTE_DIM(port->mac_stats_by_id));
@@ -812,14 +872,26 @@ sfc_xstats_get_names_by_id(struct rte_eth_dev *dev,
 				efx_mac_stat_name(sa->nic,
 						 port->mac_stats_by_id[ids[i]]),
 				sizeof(xstats_names[0].name));
-		} else {
-			sfc_adapter_unlock(sa);
-			return i;
 		}
 	}
 
+	nb_supported = port->mac_stats_nb_supported;
+
 	sfc_adapter_unlock(sa);
 
+	ret = sfc_sw_xstats_get_names_by_id(sa, ids, xstats_names, size,
+					    &nb_supported);
+	if (ret != 0) {
+		SFC_ASSERT(ret < 0);
+		return ret;
+	}
+
+	/* Return number of written names before invalid ID is encountered. */
+	for (i = 0; i < size; i++) {
+		if (xstats_names[i].name[0] == SFC_XSTAT_ID_INVALID_NAME)
+			return i;
+	}
+
 	return size;
 }
 
diff --git a/drivers/net/sfc/sfc_port.c b/drivers/net/sfc/sfc_port.c
index f6689a17c0..adb2b2cb81 100644
--- a/drivers/net/sfc/sfc_port.c
+++ b/drivers/net/sfc/sfc_port.c
@@ -7,6 +7,8 @@
  * for Solarflare) and Solarflare Communications, Inc.
  */
 
+#include <rte_bitmap.h>
+
 #include "efx.h"
 
 #include "sfc.h"
@@ -701,15 +703,11 @@ sfc_port_get_mac_stats_by_id(struct sfc_adapter *sa, const uint64_t *ids,
 		   RTE_DIM(port->mac_stats_by_id));
 
 	for (i = 0; i < n; i++) {
-		if (ids[i] < port->mac_stats_nb_supported) {
+		if (ids[i] < port->mac_stats_nb_supported)
 			values[i] = mac_stats[port->mac_stats_by_id[ids[i]]];
-		} else {
-			ret = i;
-			goto unlock;
-		}
 	}
 
-	ret = n;
+	ret = 0;
 
 unlock:
 	sfc_adapter_unlock(sa);
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index f6a8ac68e8..280e8a61f9 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -138,6 +138,7 @@ sfc_efx_rx_qrefill(struct sfc_efx_rxq *rxq)
 	SFC_ASSERT(added != rxq->added);
 	rxq->added = added;
 	efx_rx_qpush(rxq->common, added, &rxq->pushed);
+	rxq->dp.dpq.rx_dbells++;
 }
 
 static uint64_t
diff --git a/drivers/net/sfc/sfc_sw_stats.c b/drivers/net/sfc/sfc_sw_stats.c
new file mode 100644
index 0000000000..8489b603f5
--- /dev/null
+++ b/drivers/net/sfc/sfc_sw_stats.c
@@ -0,0 +1,572 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright(c) 2021 Xilinx, Inc.
+ */
+#include <rte_dev.h>
+#include <rte_bitmap.h>
+
+#include "sfc.h"
+#include "sfc_rx.h"
+#include "sfc_tx.h"
+#include "sfc_sw_stats.h"
+
+enum sfc_sw_stats_type {
+	SFC_SW_STATS_RX,
+	SFC_SW_STATS_TX,
+};
+
+typedef uint64_t sfc_get_sw_xstat_val_t(struct sfc_adapter *sa, uint16_t qid);
+
+struct sfc_sw_xstat_descr {
+	const char *name;
+	enum sfc_sw_stats_type type;
+	sfc_get_sw_xstat_val_t *get_val;
+};
+
+static sfc_get_sw_xstat_val_t sfc_get_sw_xstat_val_rx_dbells;
+static uint64_t
+sfc_get_sw_xstat_val_rx_dbells(struct sfc_adapter *sa, uint16_t qid)
+{
+	struct sfc_adapter_shared *sas = sfc_sa2shared(sa);
+	struct sfc_rxq_info *rxq_info;
+
+	rxq_info = sfc_rxq_info_by_ethdev_qid(sas, qid);
+	if (rxq_info->state & SFC_RXQ_INITIALIZED)
+		return rxq_info->dp->dpq.rx_dbells;
+	return 0;
+}
+
+static sfc_get_sw_xstat_val_t sfc_get_sw_xstat_val_tx_dbells;
+static uint64_t
+sfc_get_sw_xstat_val_tx_dbells(struct sfc_adapter *sa, uint16_t qid)
+{
+	struct sfc_adapter_shared *sas = sfc_sa2shared(sa);
+	struct sfc_txq_info *txq_info;
+
+	txq_info = sfc_txq_info_by_ethdev_qid(sas, qid);
+	if (txq_info->state & SFC_TXQ_INITIALIZED)
+		return txq_info->dp->dpq.tx_dbells;
+	return 0;
+}
+
+struct sfc_sw_xstat_descr sfc_sw_xstats[] = {
+	{
+		.name = "dbells",
+		.type = SFC_SW_STATS_RX,
+		.get_val  = sfc_get_sw_xstat_val_rx_dbells,
+	},
+	{
+		.name = "dbells",
+		.type = SFC_SW_STATS_TX,
+		.get_val  = sfc_get_sw_xstat_val_tx_dbells,
+	}
+};
+
+static int
+sfc_sw_stat_get_name(struct sfc_adapter *sa,
+		     const struct sfc_sw_xstat_descr *sw_xstat, char *name,
+		     size_t name_size, unsigned int id_off)
+{
+	const char *prefix;
+	int ret;
+
+	switch (sw_xstat->type) {
+	case SFC_SW_STATS_RX:
+		prefix = "rx";
+		break;
+	case SFC_SW_STATS_TX:
+		prefix = "tx";
+		break;
+	default:
+		sfc_err(sa, "%s: unknown software statistics type %d",
+			__func__, sw_xstat->type);
+		return -EINVAL;
+	}
+
+	if (id_off == 0) {
+		ret = snprintf(name, name_size, "%s_%s", prefix,
+							 sw_xstat->name);
+		if (ret < 0 || ret >= (int)name_size) {
+			sfc_err(sa, "%s: failed to fill xstat name %s_%s, err %d",
+				__func__, prefix, sw_xstat->name, ret);
+			return ret > 0 ? -EINVAL : ret;
+		}
+	} else {
+		uint16_t qid = id_off - 1;
+		ret = snprintf(name, name_size, "%s_q%u_%s", prefix, qid,
+							sw_xstat->name);
+		if (ret < 0 || ret >= (int)name_size) {
+			sfc_err(sa, "%s: failed to fill xstat name %s_q%u_%s, err %d",
+				__func__, prefix, qid, sw_xstat->name, ret);
+			return ret > 0 ? -EINVAL : ret;
+		}
+	}
+
+	return 0;
+}
+
+static unsigned int
+sfc_sw_stat_get_queue_count(struct sfc_adapter *sa,
+			    const struct sfc_sw_xstat_descr *sw_xstat)
+{
+	struct sfc_adapter_shared *sas = sfc_sa2shared(sa);
+
+	switch (sw_xstat->type) {
+	case SFC_SW_STATS_RX:
+		return sas->ethdev_rxq_count;
+	case SFC_SW_STATS_TX:
+		return sas->ethdev_txq_count;
+	default:
+		sfc_err(sa, "%s: unknown software statistics type %d",
+			__func__, sw_xstat->type);
+		return 0;
+	}
+}
+
+static unsigned int
+sfc_sw_xstat_per_queue_get_count(unsigned int nb_queues)
+{
+	/* Take into account the accumulative xstat of all queues */
+	return nb_queues > 0 ? 1 + nb_queues : 0;
+}
+
+static unsigned int
+sfc_sw_xstat_get_nb_supported(struct sfc_adapter *sa,
+			      const struct sfc_sw_xstat_descr *sw_xstat)
+{
+	unsigned int nb_queues;
+
+	nb_queues = sfc_sw_stat_get_queue_count(sa, sw_xstat);
+	return sfc_sw_xstat_per_queue_get_count(nb_queues);
+}
+
+static int
+sfc_sw_stat_get_names(struct sfc_adapter *sa,
+		      const struct sfc_sw_xstat_descr *sw_xstat,
+		      struct rte_eth_xstat_name *xstats_names,
+		      unsigned int xstats_names_sz,
+		      unsigned int *nb_written,
+		      unsigned int *nb_supported)
+{
+	const size_t name_size = sizeof(xstats_names[0].name);
+	unsigned int id_base = *nb_supported;
+	unsigned int nb_queues;
+	unsigned int qid;
+	int rc;
+
+	nb_queues = sfc_sw_stat_get_queue_count(sa, sw_xstat);
+	if (nb_queues == 0)
+		return 0;
+	*nb_supported += sfc_sw_xstat_per_queue_get_count(nb_queues);
+
+	/*
+	 * The order of each software xstat type is the accumulative xstat
+	 * followed by per-queue xstats.
+	 */
+	if (*nb_written < xstats_names_sz) {
+		rc = sfc_sw_stat_get_name(sa, sw_xstat,
+					  xstats_names[*nb_written].name,
+					  name_size, *nb_written - id_base);
+		if (rc != 0)
+			return rc;
+		(*nb_written)++;
+	}
+
+	for (qid = 0; qid < nb_queues; ++qid) {
+		if (*nb_written < xstats_names_sz) {
+			rc = sfc_sw_stat_get_name(sa, sw_xstat,
+					      xstats_names[*nb_written].name,
+					      name_size, *nb_written - id_base);
+			if (rc != 0)
+				return rc;
+			(*nb_written)++;
+		}
+	}
+
+	return 0;
+}
+
+static int
+sfc_sw_xstat_get_names_by_id(struct sfc_adapter *sa,
+			     const struct sfc_sw_xstat_descr *sw_xstat,
+			     const uint64_t *ids,
+			     struct rte_eth_xstat_name *xstats_names,
+			     unsigned int size,
+			     unsigned int *nb_supported)
+{
+	const size_t name_size = sizeof(xstats_names[0].name);
+	unsigned int id_base = *nb_supported;
+	unsigned int nb_queues;
+	unsigned int i;
+	int rc;
+
+	nb_queues = sfc_sw_stat_get_queue_count(sa, sw_xstat);
+	if (nb_queues == 0)
+		return 0;
+	*nb_supported += sfc_sw_xstat_per_queue_get_count(nb_queues);
+
+	/*
+	 * The order of each software xstat type is the accumulative xstat
+	 * followed by per-queue xstats.
+	 */
+	for (i = 0; i < size; i++) {
+		if (id_base <= ids[i] && ids[i] <= id_base + nb_queues) {
+			rc = sfc_sw_stat_get_name(sa, sw_xstat,
+						  xstats_names[i].name,
+						  name_size, ids[i] - id_base);
+			if (rc != 0)
+				return rc;
+		}
+	}
+
+	return 0;
+}
+
+static void
+sfc_sw_xstat_get_values(struct sfc_adapter *sa,
+			const struct sfc_sw_xstat_descr *sw_xstat,
+			struct rte_eth_xstat *xstats,
+			unsigned int xstats_size,
+			unsigned int *nb_written,
+			unsigned int *nb_supported)
+{
+	unsigned int qid;
+	uint64_t value;
+	struct rte_eth_xstat *accum_xstat;
+	bool count_accum_value = false;
+	unsigned int nb_queues;
+
+	nb_queues = sfc_sw_stat_get_queue_count(sa, sw_xstat);
+	if (nb_queues == 0)
+		return;
+	*nb_supported += sfc_sw_xstat_per_queue_get_count(nb_queues);
+
+	/*
+	 * The order of each software xstat type is the accumulative xstat
+	 * followed by per-queue xstats.
+	 */
+	if (*nb_written < xstats_size) {
+		count_accum_value = true;
+		accum_xstat = &xstats[*nb_written];
+		xstats[*nb_written].id = *nb_written;
+		xstats[*nb_written].value = 0;
+		(*nb_written)++;
+	}
+
+	for (qid = 0; qid < nb_queues; ++qid) {
+		value = sw_xstat->get_val(sa, qid);
+
+		if (*nb_written < xstats_size) {
+			xstats[*nb_written].id = *nb_written;
+			xstats[*nb_written].value = value;
+			(*nb_written)++;
+		}
+
+		if (count_accum_value)
+			accum_xstat->value += value;
+	}
+}
+
+static void
+sfc_sw_xstat_get_values_by_id(struct sfc_adapter *sa,
+			      const struct sfc_sw_xstat_descr *sw_xstat,
+			      const uint64_t *ids,
+			      uint64_t *values,
+			      unsigned int ids_size,
+			      unsigned int *nb_supported)
+{
+	rte_spinlock_t *bmp_lock = &sa->sw_xstats.queues_bitmap_lock;
+	struct rte_bitmap *bmp = sa->sw_xstats.queues_bitmap;
+	unsigned int id_base = *nb_supported;
+	bool count_accum_value = false;
+	unsigned int accum_value_idx;
+	uint64_t accum_value = 0;
+	unsigned int i, qid;
+	unsigned int nb_queues;
+
+
+	rte_spinlock_lock(bmp_lock);
+	rte_bitmap_reset(bmp);
+
+	nb_queues = sfc_sw_stat_get_queue_count(sa, sw_xstat);
+	if (nb_queues == 0)
+		goto unlock;
+	*nb_supported += sfc_sw_xstat_per_queue_get_count(nb_queues);
+
+	/*
+	 * The order of each software xstat type is the accumulative xstat
+	 * followed by per-queue xstats.
+	 */
+	for (i = 0; i < ids_size; i++) {
+		if (id_base <= ids[i] && ids[i] <= (id_base + nb_queues)) {
+			if (ids[i] == id_base) { /* Accumulative value */
+				count_accum_value = true;
+				accum_value_idx = i;
+				continue;
+			}
+			qid = ids[i] - id_base - 1;
+			values[i] = sw_xstat->get_val(sa, qid);
+			accum_value += values[i];
+
+			rte_bitmap_set(bmp, qid);
+		}
+	}
+
+	if (count_accum_value) {
+		for (qid = 0; qid < nb_queues; ++qid) {
+			if (rte_bitmap_get(bmp, qid) != 0)
+				continue;
+			values[accum_value_idx] += sw_xstat->get_val(sa, qid);
+		}
+		values[accum_value_idx] += accum_value;
+	}
+
+unlock:
+	rte_spinlock_unlock(bmp_lock);
+}
+
+unsigned int
+sfc_sw_xstats_get_nb_supported(struct sfc_adapter *sa)
+{
+	unsigned int nb_supported = 0;
+	unsigned int i;
+
+	SFC_ASSERT(sfc_adapter_is_locked(sa));
+
+	for (i = 0; i < RTE_DIM(sfc_sw_xstats); i++) {
+		nb_supported += sfc_sw_xstat_get_nb_supported(sa,
+							     &sfc_sw_xstats[i]);
+	}
+
+	return nb_supported;
+}
+
+void
+sfc_sw_xstats_get_vals(struct sfc_adapter *sa,
+		       struct rte_eth_xstat *xstats,
+		       unsigned int xstats_count,
+		       unsigned int *nb_written,
+		       unsigned int *nb_supported)
+{
+	uint64_t *reset_vals = sa->sw_xstats.reset_vals;
+	unsigned int sw_xstats_offset;
+	unsigned int i;
+
+	sfc_adapter_lock(sa);
+
+	sw_xstats_offset = *nb_supported;
+
+	for (i = 0; i < RTE_DIM(sfc_sw_xstats); i++) {
+		sfc_sw_xstat_get_values(sa, &sfc_sw_xstats[i], xstats,
+					xstats_count, nb_written, nb_supported);
+	}
+
+	for (i = sw_xstats_offset; i < *nb_written; i++)
+		xstats[i].value -= reset_vals[i - sw_xstats_offset];
+
+	sfc_adapter_unlock(sa);
+}
+
+int
+sfc_sw_xstats_get_names(struct sfc_adapter *sa,
+			struct rte_eth_xstat_name *xstats_names,
+			unsigned int xstats_count,
+			unsigned int *nb_written,
+			unsigned int *nb_supported)
+{
+	unsigned int i;
+	int ret;
+
+	sfc_adapter_lock(sa);
+
+	for (i = 0; i < RTE_DIM(sfc_sw_xstats); i++) {
+		ret = sfc_sw_stat_get_names(sa, &sfc_sw_xstats[i],
+					    xstats_names, xstats_count,
+					    nb_written, nb_supported);
+		if (ret != 0) {
+			sfc_adapter_unlock(sa);
+			return ret;
+		}
+	}
+
+	sfc_adapter_unlock(sa);
+
+	return 0;
+}
+
+void
+sfc_sw_xstats_get_vals_by_id(struct sfc_adapter *sa,
+			     const uint64_t *ids,
+			     uint64_t *values,
+			     unsigned int n,
+			     unsigned int *nb_supported)
+{
+	uint64_t *reset_vals = sa->sw_xstats.reset_vals;
+	unsigned int sw_xstats_offset;
+	unsigned int i;
+
+	sfc_adapter_lock(sa);
+
+	sw_xstats_offset = *nb_supported;
+
+	for (i = 0; i < RTE_DIM(sfc_sw_xstats); i++) {
+		sfc_sw_xstat_get_values_by_id(sa, &sfc_sw_xstats[i], ids,
+					      values, n, nb_supported);
+	}
+
+	for (i = 0; i < n; i++) {
+		if (sw_xstats_offset <= ids[i] && ids[i] < *nb_supported)
+			values[i] -= reset_vals[ids[i] - sw_xstats_offset];
+	}
+
+	sfc_adapter_unlock(sa);
+}
+
+int
+sfc_sw_xstats_get_names_by_id(struct sfc_adapter *sa,
+			      const uint64_t *ids,
+			      struct rte_eth_xstat_name *xstats_names,
+			      unsigned int size,
+			      unsigned int *nb_supported)
+{
+	unsigned int i;
+	int ret;
+
+	sfc_adapter_lock(sa);
+
+	for (i = 0; i < RTE_DIM(sfc_sw_xstats); i++) {
+		ret = sfc_sw_xstat_get_names_by_id(sa, &sfc_sw_xstats[i], ids,
+						   xstats_names, size,
+						   nb_supported);
+		if (ret != 0) {
+			sfc_adapter_unlock(sa);
+			SFC_ASSERT(ret < 0);
+			return ret;
+		}
+	}
+
+	sfc_adapter_unlock(sa);
+
+	return 0;
+}
+
+static void
+sfc_sw_xstat_reset(struct sfc_adapter *sa, struct sfc_sw_xstat_descr *sw_xstat,
+		   uint64_t *reset_vals)
+{
+	unsigned int nb_queues;
+	unsigned int qid;
+	uint64_t *accum_xstat_reset;
+
+	SFC_ASSERT(sfc_adapter_is_locked(sa));
+
+	nb_queues = sfc_sw_stat_get_queue_count(sa, sw_xstat);
+	if (nb_queues == 0)
+		return;
+
+	/*
+	 * The order of each software xstat type is the accumulative xstat
+	 * followed by per-queue xstats.
+	 */
+	accum_xstat_reset = reset_vals;
+	*accum_xstat_reset = 0;
+	reset_vals++;
+
+	for (qid = 0; qid < nb_queues; ++qid) {
+		reset_vals[qid] = sw_xstat->get_val(sa, qid);
+		*accum_xstat_reset += reset_vals[qid];
+	}
+}
+
+void
+sfc_sw_xstats_reset(struct sfc_adapter *sa)
+{
+	uint64_t *reset_vals = sa->sw_xstats.reset_vals;
+	struct sfc_sw_xstat_descr *sw_xstat;
+	unsigned int i;
+
+	SFC_ASSERT(sfc_adapter_is_locked(sa));
+
+	for (i = 0; i < RTE_DIM(sfc_sw_xstats); i++) {
+		sw_xstat = &sfc_sw_xstats[i];
+		sfc_sw_xstat_reset(sa, sw_xstat, reset_vals);
+		reset_vals += sfc_sw_xstat_get_nb_supported(sa, sw_xstat);
+	}
+}
+
+int
+sfc_sw_xstats_configure(struct sfc_adapter *sa)
+{
+	uint64_t **reset_vals = &sa->sw_xstats.reset_vals;
+	size_t nb_supported = 0;
+	unsigned int i;
+
+	for (i = 0; i < RTE_DIM(sfc_sw_xstats); i++)
+		nb_supported += sfc_sw_xstat_get_nb_supported(sa,
+							&sfc_sw_xstats[i]);
+
+	*reset_vals = rte_realloc(*reset_vals,
+				  nb_supported * sizeof(**reset_vals), 0);
+	if (*reset_vals == NULL)
+		return ENOMEM;
+
+	memset(*reset_vals, 0, nb_supported * sizeof(**reset_vals));
+
+	return 0;
+}
+
+static void
+sfc_sw_xstats_free_queues_bitmap(struct sfc_adapter *sa)
+{
+	rte_bitmap_free(sa->sw_xstats.queues_bitmap);
+	rte_free(sa->sw_xstats.queues_bitmap_mem);
+}
+
+static int
+sfc_sw_xstats_alloc_queues_bitmap(struct sfc_adapter *sa)
+{
+	struct rte_bitmap **queues_bitmap = &sa->sw_xstats.queues_bitmap;
+	void **queues_bitmap_mem = &sa->sw_xstats.queues_bitmap_mem;
+	uint32_t bmp_size;
+	int rc;
+
+	bmp_size = rte_bitmap_get_memory_footprint(RTE_MAX_QUEUES_PER_PORT);
+	*queues_bitmap_mem = NULL;
+	*queues_bitmap = NULL;
+
+	*queues_bitmap_mem = rte_calloc_socket("bitmap_mem", bmp_size, 1, 0,
+					       sa->socket_id);
+	if (*queues_bitmap_mem == NULL)
+		return ENOMEM;
+
+	*queues_bitmap = rte_bitmap_init(RTE_MAX_QUEUES_PER_PORT,
+					 *queues_bitmap_mem, bmp_size);
+	if (*queues_bitmap == NULL) {
+		rc = EINVAL;
+		goto fail;
+	}
+
+	rte_spinlock_init(&sa->sw_xstats.queues_bitmap_lock);
+	return 0;
+
+fail:
+	sfc_sw_xstats_free_queues_bitmap(sa);
+	return rc;
+}
+
+int
+sfc_sw_xstats_init(struct sfc_adapter *sa)
+{
+	sa->sw_xstats.reset_vals = NULL;
+
+	return sfc_sw_xstats_alloc_queues_bitmap(sa);
+}
+
+void
+sfc_sw_xstats_close(struct sfc_adapter *sa)
+{
+	rte_free(sa->sw_xstats.reset_vals);
+	sa->sw_xstats.reset_vals = NULL;
+
+	sfc_sw_xstats_free_queues_bitmap(sa);
+}
diff --git a/drivers/net/sfc/sfc_sw_stats.h b/drivers/net/sfc/sfc_sw_stats.h
new file mode 100644
index 0000000000..1abded8018
--- /dev/null
+++ b/drivers/net/sfc/sfc_sw_stats.h
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright(c) 2021 Xilinx, Inc.
+ */
+#ifndef _SFC_SW_STATS_H
+#define _SFC_SW_STATS_H
+
+#include <rte_dev.h>
+
+#include "sfc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void sfc_sw_xstats_get_vals(struct sfc_adapter *sa,
+			    struct rte_eth_xstat *xstats,
+			    unsigned int xstats_count, unsigned int *nb_written,
+			    unsigned int *nb_supported);
+
+int sfc_sw_xstats_get_names(struct sfc_adapter *sa,
+			    struct rte_eth_xstat_name *xstats_names,
+			    unsigned int xstats_count, unsigned int *nb_written,
+			    unsigned int *nb_supported);
+
+void sfc_sw_xstats_get_vals_by_id(struct sfc_adapter *sa, const uint64_t *ids,
+				  uint64_t *values, unsigned int n,
+				  unsigned int *nb_supported);
+
+int sfc_sw_xstats_get_names_by_id(struct sfc_adapter *sa, const uint64_t *ids,
+				  struct rte_eth_xstat_name *xstats_names,
+				  unsigned int size,
+				  unsigned int *nb_supported);
+
+unsigned int sfc_sw_xstats_get_nb_supported(struct sfc_adapter *sa);
+
+int sfc_sw_xstats_configure(struct sfc_adapter *sa);
+
+void sfc_sw_xstats_reset(struct sfc_adapter *sa);
+
+int sfc_sw_xstats_init(struct sfc_adapter *sa);
+
+void sfc_sw_xstats_close(struct sfc_adapter *sa);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* _SFC_SW_STATS_H */
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index ce2a9a6a4f..49b239f4d2 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -980,8 +980,10 @@ sfc_efx_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 				       txq->completed, &txq->added);
 		SFC_ASSERT(rc == 0);
 
-		if (likely(pushed != txq->added))
+		if (likely(pushed != txq->added)) {
 			efx_tx_qpush(txq->common, txq->added, pushed);
+			txq->dp.dpq.tx_dbells++;
+		}
 	}
 
 #if SFC_TX_XMIT_PKTS_REAP_AT_LEAST_ONCE
-- 
2.30.2


  parent reply	other threads:[~2021-06-04 14:43 UTC|newest]

Thread overview: 114+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-04 14:42 [dpdk-dev] [PATCH 00/11] net/sfc: provide Rx/Tx doorbells stats Andrew Rybchenko
2021-06-04 14:42 ` [dpdk-dev] [PATCH 01/11] net/sfc: fix get xstats by ID callback to use MAC stats lock Andrew Rybchenko
2021-06-04 14:42 ` [dpdk-dev] [PATCH 02/11] net/sfc: fix reading adapter state without locking Andrew Rybchenko
2021-06-04 14:42 ` [dpdk-dev] [PATCH 03/11] ethdev: fix docs of functions getting xstats by IDs Andrew Rybchenko
2021-07-20 16:25   ` Ferruh Yigit
2021-07-22  9:12     ` Andrew Rybchenko
2021-07-23 14:19       ` Ferruh Yigit
2021-07-24 12:06         ` Andrew Rybchenko
2021-06-04 14:42 ` [dpdk-dev] [PATCH 04/11] ethdev: fix docs of drivers callbacks " Andrew Rybchenko
2021-07-20 16:51   ` Ferruh Yigit
2021-07-22  9:33     ` Andrew Rybchenko
2021-07-23 14:31       ` Ferruh Yigit
2021-07-23 18:47         ` Andrew Rybchenko
2021-06-04 14:42 ` [dpdk-dev] [PATCH 05/11] net/sfc: fix xstats by ID callbacks according to ethdev Andrew Rybchenko
2021-06-04 14:42 ` [dpdk-dev] [PATCH 06/11] net/sfc: fix accessing xstats by an unsorted list of IDs Andrew Rybchenko
2021-06-04 14:42 ` [dpdk-dev] [PATCH 07/11] net/sfc: fix MAC stats update to work for stopped device Andrew Rybchenko
2021-06-04 14:42 ` [dpdk-dev] [PATCH 08/11] net/sfc: simplify getting of available xstats case Andrew Rybchenko
2021-06-04 14:42 ` [dpdk-dev] [PATCH 09/11] net/sfc: prepare to add more xstats Andrew Rybchenko
2021-06-04 14:42 ` Andrew Rybchenko [this message]
2021-06-04 14:42 ` [dpdk-dev] [PATCH 11/11] app/testpmd: add option to display extended statistics Andrew Rybchenko
2021-07-05  7:10   ` David Marchand
2021-07-06  8:54   ` Li, Xiaoyun
2021-07-22  9:54 ` [dpdk-dev] [PATCH v2 00/11] net/sfc: provide Rx/Tx doorbells stats Andrew Rybchenko
2021-07-22  9:54   ` [dpdk-dev] [PATCH v2 01/11] net/sfc: fix get xstats by ID callback to use MAC stats lock Andrew Rybchenko
2021-07-22  9:54   ` [dpdk-dev] [PATCH v2 02/11] net/sfc: fix reading adapter state without locking Andrew Rybchenko
2021-07-22  9:54   ` [dpdk-dev] [PATCH v2 03/11] ethdev: fix docs of functions getting xstats by IDs Andrew Rybchenko
2021-07-22  9:54   ` [dpdk-dev] [PATCH v2 04/11] ethdev: fix docs of drivers callbacks " Andrew Rybchenko
2021-07-22  9:54   ` [dpdk-dev] [PATCH v2 05/11] net/sfc: fix xstats by ID callbacks according to ethdev Andrew Rybchenko
2021-07-22  9:54   ` [dpdk-dev] [PATCH v2 06/11] net/sfc: fix accessing xstats by an unsorted list of IDs Andrew Rybchenko
2021-07-22  9:54   ` [dpdk-dev] [PATCH v2 07/11] net/sfc: fix MAC stats update to work for stopped device Andrew Rybchenko
2021-07-22  9:54   ` [dpdk-dev] [PATCH v2 08/11] net/sfc: simplify getting of available xstats case Andrew Rybchenko
2021-07-22  9:54   ` [dpdk-dev] [PATCH v2 09/11] net/sfc: prepare to add more xstats Andrew Rybchenko
2021-07-22  9:54   ` [dpdk-dev] [PATCH v2 10/11] net/sfc: add xstats for Rx/Tx doorbells Andrew Rybchenko
2021-07-22  9:54   ` [dpdk-dev] [PATCH v2 11/11] app/testpmd: add option to display extended statistics Andrew Rybchenko
2021-07-22 19:43     ` David Marchand
2021-07-22 20:15     ` David Marchand
2021-07-23 13:08       ` Andrew Rybchenko
2021-07-23 13:15 ` [dpdk-dev] [PATCH v3 00/11] net/sfc: provide Rx/Tx doorbells stats Andrew Rybchenko
2021-07-23 13:15   ` [dpdk-dev] [PATCH v3 01/11] net/sfc: fix get xstats by ID callback to use MAC stats lock Andrew Rybchenko
2021-07-23 13:15   ` [dpdk-dev] [PATCH v3 02/11] net/sfc: fix reading adapter state without locking Andrew Rybchenko
2021-07-23 13:15   ` [dpdk-dev] [PATCH v3 03/11] ethdev: fix docs of functions getting xstats by IDs Andrew Rybchenko
2021-07-23 14:42     ` Ferruh Yigit
2021-07-24 12:07       ` Andrew Rybchenko
2021-07-23 13:15   ` [dpdk-dev] [PATCH v3 04/11] ethdev: fix docs of drivers callbacks " Andrew Rybchenko
2021-07-23 14:46     ` Ferruh Yigit
2021-07-23 13:15   ` [dpdk-dev] [PATCH v3 05/11] net/sfc: fix xstats by ID callbacks according to ethdev Andrew Rybchenko
2021-07-23 13:15   ` [dpdk-dev] [PATCH v3 06/11] net/sfc: fix accessing xstats by an unsorted list of IDs Andrew Rybchenko
2021-07-23 13:15   ` [dpdk-dev] [PATCH v3 07/11] net/sfc: fix MAC stats update to work for stopped device Andrew Rybchenko
2021-07-23 13:15   ` [dpdk-dev] [PATCH v3 08/11] net/sfc: simplify getting of available xstats case Andrew Rybchenko
2021-07-23 13:15   ` [dpdk-dev] [PATCH v3 09/11] net/sfc: prepare to add more xstats Andrew Rybchenko
2021-07-23 13:15   ` [dpdk-dev] [PATCH v3 10/11] net/sfc: add xstats for Rx/Tx doorbells Andrew Rybchenko
2021-07-23 13:15   ` [dpdk-dev] [PATCH v3 11/11] app/testpmd: add option to display extended statistics Andrew Rybchenko
2021-08-20 13:55     ` [dpdk-dev] [PATCH v4] " Andrew Rybchenko
2021-08-21  1:09       ` Ajit Khaparde
2021-08-23  9:59         ` Andrew Rybchenko
2021-09-02 16:08       ` Ferruh Yigit
2021-09-15 10:25         ` Ivan Ilchenko
2021-09-15 11:27     ` [dpdk-dev] [PATCH v5] " Andrew Rybchenko
2021-10-14  7:43       ` Ferruh Yigit
2021-10-14  9:00     ` [dpdk-dev] [PATCH v6] " Andrew Rybchenko
2021-10-14 12:41       ` Ferruh Yigit
2021-07-23 21:34   ` [dpdk-dev] [PATCH v3 00/11] net/sfc: provide Rx/Tx doorbells stats Thomas Monjalon
2021-07-24 12:33 ` [dpdk-dev] [PATCH v4 1/2] ethdev: fix docs of functions getting xstats by IDs Andrew Rybchenko
2021-07-24 12:33   ` [dpdk-dev] [PATCH v4 2/2] ethdev: fix docs of drivers callbacks " Andrew Rybchenko
2021-07-26 10:13     ` Olivier Matz
2021-09-28 12:04       ` Andrew Rybchenko
2021-07-26 10:13   ` [dpdk-dev] [PATCH v4 1/2] ethdev: fix docs of functions " Olivier Matz
2021-09-28 12:01     ` Andrew Rybchenko
2021-09-28 12:05 ` [dpdk-dev] [PATCH v5 " Andrew Rybchenko
2021-09-28 12:05   ` [dpdk-dev] [PATCH v5 2/2] ethdev: fix docs of drivers callbacks " Andrew Rybchenko
2021-09-28 16:50     ` Ferruh Yigit
2021-09-28 16:53       ` Andrew Rybchenko
2021-09-29  8:44         ` [dpdk-dev] [dpdk-stable] " Ferruh Yigit
2021-09-29 11:54           ` Andrew Rybchenko
2021-09-30 12:08             ` Ferruh Yigit
2021-09-30 14:01               ` Andrew Rybchenko
2021-09-30 15:30                 ` Ferruh Yigit
2021-09-30 16:01                   ` Andrew Rybchenko
2021-09-28 16:46   ` [dpdk-dev] [PATCH v5 1/2] ethdev: fix docs of functions " Ferruh Yigit
2021-09-30 14:04 ` [dpdk-dev] [PATCH v6 1/4] " Andrew Rybchenko
2021-09-30 14:04   ` [dpdk-dev] [PATCH v6 2/4] ethdev: fix docs of drivers callbacks " Andrew Rybchenko
2021-09-30 14:04   ` [dpdk-dev] [PATCH v6 3/4] ethdev: improve xstats names by IDs get prototype Andrew Rybchenko
2021-09-30 14:04   ` [dpdk-dev] [PATCH v6 4/4] ethdev: merge driver ops to get all xstats names and by ID Andrew Rybchenko
2021-09-30 16:01 ` [dpdk-dev] [PATCH v7 1/4] ethdev: do not use get xstats names by IDs to obtain count Andrew Rybchenko
2021-09-30 16:01   ` [dpdk-dev] [PATCH v7 1/5] ethdev: fix docs of functions getting xstats by IDs Andrew Rybchenko
2021-09-30 16:01   ` [dpdk-dev] [PATCH v7 2/5] ethdev: do not use get xstats names by IDs to obtain count Andrew Rybchenko
2021-09-30 16:01   ` [dpdk-dev] [PATCH v7 2/4] ethdev: fix docs of drivers callbacks getting xstats by IDs Andrew Rybchenko
2021-09-30 16:01   ` [dpdk-dev] [PATCH v7 3/5] " Andrew Rybchenko
2021-09-30 16:01   ` [dpdk-dev] [PATCH v7 3/4] ethdev: improve xstats names by IDs get prototype Andrew Rybchenko
2021-09-30 16:01   ` [dpdk-dev] [PATCH v7 4/5] " Andrew Rybchenko
2021-09-30 16:01   ` [dpdk-dev] [PATCH v7 4/4] ethdev: merge driver ops to get all xstats names and by ID Andrew Rybchenko
2021-09-30 16:01   ` [dpdk-dev] [PATCH v7 5/5] " Andrew Rybchenko
2021-09-30 16:05 ` [dpdk-dev] [PATCH v8 1/5] ethdev: fix docs of functions getting xstats by IDs Andrew Rybchenko
2021-09-30 16:05   ` [dpdk-dev] [PATCH v8 2/5] ethdev: do not use get xstats names by IDs to obtain count Andrew Rybchenko
2021-09-30 16:32     ` Ferruh Yigit
2021-09-30 16:05   ` [dpdk-dev] [PATCH v8 3/5] ethdev: fix docs of drivers callbacks getting xstats by IDs Andrew Rybchenko
2021-09-30 16:33     ` Ferruh Yigit
2021-10-01  9:07       ` Andrew Rybchenko
2021-09-30 16:05   ` [dpdk-dev] [PATCH v8 4/5] ethdev: improve xstats names by IDs get prototype Andrew Rybchenko
2021-09-30 16:05   ` [dpdk-dev] [PATCH v8 5/5] ethdev: merge driver ops to get all xstats names and by ID Andrew Rybchenko
2021-09-30 16:47     ` Ferruh Yigit
2021-10-01  9:06       ` Andrew Rybchenko
2021-10-01  9:07 ` [dpdk-dev] [PATCH v9 1/5] ethdev: fix docs of functions getting xstats by IDs Andrew Rybchenko
2021-10-01  9:07   ` [dpdk-dev] [PATCH v9 2/5] ethdev: do not use get xstats names by IDs to obtain count Andrew Rybchenko
2021-10-01  9:07   ` [dpdk-dev] [PATCH v9 3/5] ethdev: fix docs of drivers callbacks getting xstats by IDs Andrew Rybchenko
2021-10-01  9:42     ` [dpdk-dev] [dpdk-stable] " Ferruh Yigit
2021-10-01 10:22       ` Andrew Rybchenko
2021-10-06 10:37         ` Ferruh Yigit
2021-10-01  9:07   ` [dpdk-dev] [PATCH v9 4/5] ethdev: improve xstats names by IDs get prototype Andrew Rybchenko
2021-10-01  9:42     ` Ferruh Yigit
2021-10-01  9:07   ` [dpdk-dev] [PATCH v9 5/5] ethdev: merge driver ops to get all xstats names and by ID Andrew Rybchenko
2021-10-06 11:06     ` Ferruh Yigit
2023-06-09 10:09       ` Ferruh Yigit
2021-10-06 11:08   ` [dpdk-dev] [PATCH v9 1/5] ethdev: fix docs of functions getting xstats by IDs Ferruh Yigit

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210604144225.287678-11-andrew.rybchenko@oktetlabs.ru \
    --to=andrew.rybchenko@oktetlabs.ru \
    --cc=amoreton@xilinx.com \
    --cc=dev@dpdk.org \
    --cc=ivan.ilchenko@oktetlabs.ru \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.