DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 00/11] net/sfc: support per-queue stats on EF100
@ 2021-09-28 11:29 Andrew Rybchenko
  2021-09-28 11:29 ` [dpdk-dev] [PATCH 01/11] net/sfc: rename array of SW stats descriptions Andrew Rybchenko
                   ` (11 more replies)
  0 siblings, 12 replies; 13+ messages in thread
From: Andrew Rybchenko @ 2021-09-28 11:29 UTC (permalink / raw)
  To: dev

Implement per-queue Rx and Tx statistics for EF100 in software.
Packets and bytes stats are collected by the driver.

Ivan Ilchenko (11):
  net/sfc: rename array of SW stats descriptions
  net/sfc: rename accumulative SW stats to total
  net/sfc: rename SW stats structures
  net/sfc: fix cleanup order of SW stats
  net/sfc: fix missing const of SW stats descriptions
  net/sfc: optimize getting number of SW stats
  net/sfc: prepare having no some SW stats on an adapter
  net/sfc: add toggle to disable total stat
  net/sfc: add support for SW stats groups
  net/sfc: collect per queue stats in EF100 Rx datapath
  net/sfc: collect per queue stats in EF100 Tx datapath

 drivers/net/sfc/sfc.h          |  26 +-
 drivers/net/sfc/sfc_dp.h       |   2 +
 drivers/net/sfc/sfc_dp_rx.h    |   1 +
 drivers/net/sfc/sfc_dp_tx.h    |   1 +
 drivers/net/sfc/sfc_ef100_rx.c |  10 +-
 drivers/net/sfc/sfc_ef100_tx.c |   6 +-
 drivers/net/sfc/sfc_ethdev.c   | 136 ++++++--
 drivers/net/sfc/sfc_sw_stats.c | 569 +++++++++++++++++++++++++--------
 8 files changed, 581 insertions(+), 170 deletions(-)

-- 
2.30.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [dpdk-dev] [PATCH 01/11] net/sfc: rename array of SW stats descriptions
  2021-09-28 11:29 [dpdk-dev] [PATCH 00/11] net/sfc: support per-queue stats on EF100 Andrew Rybchenko
@ 2021-09-28 11:29 ` Andrew Rybchenko
  2021-09-28 11:29 ` [dpdk-dev] [PATCH 02/11] net/sfc: rename accumulative SW stats to total Andrew Rybchenko
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Andrew Rybchenko @ 2021-09-28 11:29 UTC (permalink / raw)
  To: dev; +Cc: Ivan Ilchenko

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

Rename global array of SW stats descriptions declared as
'struct sfc_sw_xstat_descr sfc_sw_xstats[]' to
'sfc_sw_stats_descr[]' to avoid ambiguity since there is
structure declared as 'struct sfc_sw_xstats'.

Signed-off-by: Ivan Ilchenko <ivan.ilchenko@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 drivers/net/sfc/sfc_sw_stats.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/net/sfc/sfc_sw_stats.c b/drivers/net/sfc/sfc_sw_stats.c
index 2b28ba29e6..2b8b1b56e9 100644
--- a/drivers/net/sfc/sfc_sw_stats.c
+++ b/drivers/net/sfc/sfc_sw_stats.c
@@ -49,7 +49,7 @@ sfc_get_sw_xstat_val_tx_dbells(struct sfc_adapter *sa, uint16_t qid)
 	return 0;
 }
 
-struct sfc_sw_xstat_descr sfc_sw_xstats[] = {
+struct sfc_sw_xstat_descr sfc_sw_stats_descr[] = {
 	{
 		.name = "dbells",
 		.type = SFC_SW_STATS_RX,
@@ -334,9 +334,9 @@ sfc_sw_xstats_get_nb_supported(struct sfc_adapter *sa)
 
 	SFC_ASSERT(sfc_adapter_is_locked(sa));
 
-	for (i = 0; i < RTE_DIM(sfc_sw_xstats); i++) {
+	for (i = 0; i < RTE_DIM(sfc_sw_stats_descr); i++) {
 		nb_supported += sfc_sw_xstat_get_nb_supported(sa,
-							     &sfc_sw_xstats[i]);
+							&sfc_sw_stats_descr[i]);
 	}
 
 	return nb_supported;
@@ -357,8 +357,8 @@ sfc_sw_xstats_get_vals(struct sfc_adapter *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,
+	for (i = 0; i < RTE_DIM(sfc_sw_stats_descr); i++) {
+		sfc_sw_xstat_get_values(sa, &sfc_sw_stats_descr[i], xstats,
 					xstats_count, nb_written, nb_supported);
 	}
 
@@ -380,8 +380,8 @@ sfc_sw_xstats_get_names(struct sfc_adapter *sa,
 
 	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],
+	for (i = 0; i < RTE_DIM(sfc_sw_stats_descr); i++) {
+		ret = sfc_sw_stat_get_names(sa, &sfc_sw_stats_descr[i],
 					    xstats_names, xstats_count,
 					    nb_written, nb_supported);
 		if (ret != 0) {
@@ -410,8 +410,8 @@ sfc_sw_xstats_get_vals_by_id(struct sfc_adapter *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,
+	for (i = 0; i < RTE_DIM(sfc_sw_stats_descr); i++) {
+		sfc_sw_xstat_get_values_by_id(sa, &sfc_sw_stats_descr[i], ids,
 					      values, n, nb_supported);
 	}
 
@@ -435,9 +435,9 @@ sfc_sw_xstats_get_names_by_id(struct sfc_adapter *sa,
 
 	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,
+	for (i = 0; i < RTE_DIM(sfc_sw_stats_descr); i++) {
+		ret = sfc_sw_xstat_get_names_by_id(sa, &sfc_sw_stats_descr[i],
+						   ids, xstats_names, size,
 						   nb_supported);
 		if (ret != 0) {
 			sfc_adapter_unlock(sa);
@@ -488,8 +488,8 @@ sfc_sw_xstats_reset(struct sfc_adapter *sa)
 
 	SFC_ASSERT(sfc_adapter_is_locked(sa));
 
-	for (i = 0; i < RTE_DIM(sfc_sw_xstats); i++) {
-		sw_xstat = &sfc_sw_xstats[i];
+	for (i = 0; i < RTE_DIM(sfc_sw_stats_descr); i++) {
+		sw_xstat = &sfc_sw_stats_descr[i];
 		sfc_sw_xstat_reset(sa, sw_xstat, reset_vals);
 		reset_vals += sfc_sw_xstat_get_nb_supported(sa, sw_xstat);
 	}
@@ -502,9 +502,9 @@ sfc_sw_xstats_configure(struct sfc_adapter *sa)
 	size_t nb_supported = 0;
 	unsigned int i;
 
-	for (i = 0; i < RTE_DIM(sfc_sw_xstats); i++)
+	for (i = 0; i < RTE_DIM(sfc_sw_stats_descr); i++)
 		nb_supported += sfc_sw_xstat_get_nb_supported(sa,
-							&sfc_sw_xstats[i]);
+							&sfc_sw_stats_descr[i]);
 
 	*reset_vals = rte_realloc(*reset_vals,
 				  nb_supported * sizeof(**reset_vals), 0);
-- 
2.30.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [dpdk-dev] [PATCH 02/11] net/sfc: rename accumulative SW stats to total
  2021-09-28 11:29 [dpdk-dev] [PATCH 00/11] net/sfc: support per-queue stats on EF100 Andrew Rybchenko
  2021-09-28 11:29 ` [dpdk-dev] [PATCH 01/11] net/sfc: rename array of SW stats descriptions Andrew Rybchenko
@ 2021-09-28 11:29 ` Andrew Rybchenko
  2021-09-28 11:29 ` [dpdk-dev] [PATCH 03/11] net/sfc: rename SW stats structures Andrew Rybchenko
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Andrew Rybchenko @ 2021-09-28 11:29 UTC (permalink / raw)
  To: dev; +Cc: Ivan Ilchenko

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

This is a better word used in RTE docs.

Signed-off-by: Ivan Ilchenko <ivan.ilchenko@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 drivers/net/sfc/sfc_sw_stats.c | 52 +++++++++++++++++-----------------
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/drivers/net/sfc/sfc_sw_stats.c b/drivers/net/sfc/sfc_sw_stats.c
index 2b8b1b56e9..a9f1790d38 100644
--- a/drivers/net/sfc/sfc_sw_stats.c
+++ b/drivers/net/sfc/sfc_sw_stats.c
@@ -126,7 +126,7 @@ sfc_sw_stat_get_queue_count(struct sfc_adapter *sa,
 static unsigned int
 sfc_sw_xstat_per_queue_get_count(unsigned int nb_queues)
 {
-	/* Take into account the accumulative xstat of all queues */
+	/* Take into account the total xstat of all queues */
 	return nb_queues > 0 ? 1 + nb_queues : 0;
 }
 
@@ -160,7 +160,7 @@ sfc_sw_stat_get_names(struct sfc_adapter *sa,
 	*nb_supported += sfc_sw_xstat_per_queue_get_count(nb_queues);
 
 	/*
-	 * The order of each software xstat type is the accumulative xstat
+	 * The order of each software xstat type is the total xstat
 	 * followed by per-queue xstats.
 	 */
 	if (*nb_written < xstats_names_sz) {
@@ -206,7 +206,7 @@ sfc_sw_xstat_get_names_by_id(struct sfc_adapter *sa,
 	*nb_supported += sfc_sw_xstat_per_queue_get_count(nb_queues);
 
 	/*
-	 * The order of each software xstat type is the accumulative xstat
+	 * The order of each software xstat type is the total xstat
 	 * followed by per-queue xstats.
 	 */
 	for (i = 0; i < size; i++) {
@@ -232,8 +232,8 @@ sfc_sw_xstat_get_values(struct sfc_adapter *sa,
 {
 	unsigned int qid;
 	uint64_t value;
-	struct rte_eth_xstat *accum_xstat;
-	bool count_accum_value = false;
+	struct rte_eth_xstat *total_xstat;
+	bool count_total_value = false;
 	unsigned int nb_queues;
 
 	nb_queues = sfc_sw_stat_get_queue_count(sa, sw_xstat);
@@ -242,12 +242,12 @@ sfc_sw_xstat_get_values(struct sfc_adapter *sa,
 	*nb_supported += sfc_sw_xstat_per_queue_get_count(nb_queues);
 
 	/*
-	 * The order of each software xstat type is the accumulative xstat
+	 * The order of each software xstat type is the total xstat
 	 * followed by per-queue xstats.
 	 */
 	if (*nb_written < xstats_size) {
-		count_accum_value = true;
-		accum_xstat = &xstats[*nb_written];
+		count_total_value = true;
+		total_xstat = &xstats[*nb_written];
 		xstats[*nb_written].id = *nb_written;
 		xstats[*nb_written].value = 0;
 		(*nb_written)++;
@@ -262,8 +262,8 @@ sfc_sw_xstat_get_values(struct sfc_adapter *sa,
 			(*nb_written)++;
 		}
 
-		if (count_accum_value)
-			accum_xstat->value += value;
+		if (count_total_value)
+			total_xstat->value += value;
 	}
 }
 
@@ -278,9 +278,9 @@ sfc_sw_xstat_get_values_by_id(struct sfc_adapter *sa,
 	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;
+	bool count_total_value = false;
+	unsigned int total_value_idx;
+	uint64_t total_value = 0;
 	unsigned int i, qid;
 	unsigned int nb_queues;
 
@@ -294,32 +294,32 @@ sfc_sw_xstat_get_values_by_id(struct sfc_adapter *sa,
 	*nb_supported += sfc_sw_xstat_per_queue_get_count(nb_queues);
 
 	/*
-	 * The order of each software xstat type is the accumulative xstat
+	 * The order of each software xstat type is the total 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;
+				count_total_value = true;
+				total_value_idx = i;
 				continue;
 			}
 			qid = ids[i] - id_base - 1;
 			values[i] = sw_xstat->get_val(sa, qid);
-			accum_value += values[i];
+			total_value += values[i];
 
 			rte_bitmap_set(bmp, qid);
 		}
 	}
 
-	if (count_accum_value) {
-		values[accum_value_idx] = 0;
+	if (count_total_value) {
+		values[total_value_idx] = 0;
 		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[total_value_idx] += sw_xstat->get_val(sa, qid);
 		}
-		values[accum_value_idx] += accum_value;
+		values[total_value_idx] += total_value;
 	}
 
 unlock:
@@ -457,7 +457,7 @@ sfc_sw_xstat_reset(struct sfc_adapter *sa, struct sfc_sw_xstat_descr *sw_xstat,
 {
 	unsigned int nb_queues;
 	unsigned int qid;
-	uint64_t *accum_xstat_reset;
+	uint64_t *total_xstat_reset;
 
 	SFC_ASSERT(sfc_adapter_is_locked(sa));
 
@@ -466,16 +466,16 @@ sfc_sw_xstat_reset(struct sfc_adapter *sa, struct sfc_sw_xstat_descr *sw_xstat,
 		return;
 
 	/*
-	 * The order of each software xstat type is the accumulative xstat
+	 * The order of each software xstat type is the total xstat
 	 * followed by per-queue xstats.
 	 */
-	accum_xstat_reset = reset_vals;
-	*accum_xstat_reset = 0;
+	total_xstat_reset = reset_vals;
+	*total_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];
+		*total_xstat_reset += reset_vals[qid];
 	}
 }
 
-- 
2.30.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [dpdk-dev] [PATCH 03/11] net/sfc: rename SW stats structures
  2021-09-28 11:29 [dpdk-dev] [PATCH 00/11] net/sfc: support per-queue stats on EF100 Andrew Rybchenko
  2021-09-28 11:29 ` [dpdk-dev] [PATCH 01/11] net/sfc: rename array of SW stats descriptions Andrew Rybchenko
  2021-09-28 11:29 ` [dpdk-dev] [PATCH 02/11] net/sfc: rename accumulative SW stats to total Andrew Rybchenko
@ 2021-09-28 11:29 ` Andrew Rybchenko
  2021-09-28 11:29 ` [dpdk-dev] [PATCH 04/11] net/sfc: fix cleanup order of SW stats Andrew Rybchenko
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Andrew Rybchenko @ 2021-09-28 11:29 UTC (permalink / raw)
  To: dev; +Cc: Ivan Ilchenko

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

Delete 'x' in:
    1. per-adapter 'struct sfc_sw_xstats' with corresponding
       field 'sw_xstats'.
    2. 'struct sfc_sw_xstat_descr' and callback prototype
       'sfc_get_sw_xstat_val_t' with its implementations.

The 'x' stands for 'extended' in RTE but from sfc point of
view these are just SW stats.

Signed-off-by: Ivan Ilchenko <ivan.ilchenko@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 drivers/net/sfc/sfc.h          |   4 +-
 drivers/net/sfc/sfc_sw_stats.c | 114 ++++++++++++++++-----------------
 2 files changed, 59 insertions(+), 59 deletions(-)

diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 331e06bac6..93d5202a24 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -217,7 +217,7 @@ struct sfc_counter_rxq {
 	struct rte_mempool		*mp;
 };
 
-struct sfc_sw_xstats {
+struct sfc_sw_stats {
 	uint64_t			*reset_vals;
 
 	rte_spinlock_t			queues_bitmap_lock;
@@ -257,7 +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_sw_stats		sw_stats;
 	struct sfc_filter		filter;
 	struct sfc_mae			mae;
 
diff --git a/drivers/net/sfc/sfc_sw_stats.c b/drivers/net/sfc/sfc_sw_stats.c
index a9f1790d38..108f301822 100644
--- a/drivers/net/sfc/sfc_sw_stats.c
+++ b/drivers/net/sfc/sfc_sw_stats.c
@@ -15,17 +15,17 @@ enum sfc_sw_stats_type {
 	SFC_SW_STATS_TX,
 };
 
-typedef uint64_t sfc_get_sw_xstat_val_t(struct sfc_adapter *sa, uint16_t qid);
+typedef uint64_t sfc_get_sw_stat_val_t(struct sfc_adapter *sa, uint16_t qid);
 
-struct sfc_sw_xstat_descr {
+struct sfc_sw_stat_descr {
 	const char *name;
 	enum sfc_sw_stats_type type;
-	sfc_get_sw_xstat_val_t *get_val;
+	sfc_get_sw_stat_val_t *get_val;
 };
 
-static sfc_get_sw_xstat_val_t sfc_get_sw_xstat_val_rx_dbells;
+static sfc_get_sw_stat_val_t sfc_get_sw_stat_val_rx_dbells;
 static uint64_t
-sfc_get_sw_xstat_val_rx_dbells(struct sfc_adapter *sa, uint16_t qid)
+sfc_get_sw_stat_val_rx_dbells(struct sfc_adapter *sa, uint16_t qid)
 {
 	struct sfc_adapter_shared *sas = sfc_sa2shared(sa);
 	struct sfc_rxq_info *rxq_info;
@@ -36,9 +36,9 @@ sfc_get_sw_xstat_val_rx_dbells(struct sfc_adapter *sa, uint16_t qid)
 	return 0;
 }
 
-static sfc_get_sw_xstat_val_t sfc_get_sw_xstat_val_tx_dbells;
+static sfc_get_sw_stat_val_t sfc_get_sw_stat_val_tx_dbells;
 static uint64_t
-sfc_get_sw_xstat_val_tx_dbells(struct sfc_adapter *sa, uint16_t qid)
+sfc_get_sw_stat_val_tx_dbells(struct sfc_adapter *sa, uint16_t qid)
 {
 	struct sfc_adapter_shared *sas = sfc_sa2shared(sa);
 	struct sfc_txq_info *txq_info;
@@ -49,28 +49,28 @@ sfc_get_sw_xstat_val_tx_dbells(struct sfc_adapter *sa, uint16_t qid)
 	return 0;
 }
 
-struct sfc_sw_xstat_descr sfc_sw_stats_descr[] = {
+struct sfc_sw_stat_descr sfc_sw_stats_descr[] = {
 	{
 		.name = "dbells",
 		.type = SFC_SW_STATS_RX,
-		.get_val  = sfc_get_sw_xstat_val_rx_dbells,
+		.get_val  = sfc_get_sw_stat_val_rx_dbells,
 	},
 	{
 		.name = "dbells",
 		.type = SFC_SW_STATS_TX,
-		.get_val  = sfc_get_sw_xstat_val_tx_dbells,
+		.get_val  = sfc_get_sw_stat_val_tx_dbells,
 	}
 };
 
 static int
 sfc_sw_stat_get_name(struct sfc_adapter *sa,
-		     const struct sfc_sw_xstat_descr *sw_xstat, char *name,
+		     const struct sfc_sw_stat_descr *sw_stat, char *name,
 		     size_t name_size, unsigned int id_off)
 {
 	const char *prefix;
 	int ret;
 
-	switch (sw_xstat->type) {
+	switch (sw_stat->type) {
 	case SFC_SW_STATS_RX:
 		prefix = "rx";
 		break;
@@ -79,25 +79,25 @@ sfc_sw_stat_get_name(struct sfc_adapter *sa,
 		break;
 	default:
 		sfc_err(sa, "%s: unknown software statistics type %d",
-			__func__, sw_xstat->type);
+			__func__, sw_stat->type);
 		return -EINVAL;
 	}
 
 	if (id_off == 0) {
 		ret = snprintf(name, name_size, "%s_%s", prefix,
-							 sw_xstat->name);
+							 sw_stat->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);
+				__func__, prefix, sw_stat->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);
+							sw_stat->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);
+				__func__, prefix, qid, sw_stat->name, ret);
 			return ret > 0 ? -EINVAL : ret;
 		}
 	}
@@ -107,18 +107,18 @@ sfc_sw_stat_get_name(struct sfc_adapter *sa,
 
 static unsigned int
 sfc_sw_stat_get_queue_count(struct sfc_adapter *sa,
-			    const struct sfc_sw_xstat_descr *sw_xstat)
+			    const struct sfc_sw_stat_descr *sw_stat)
 {
 	struct sfc_adapter_shared *sas = sfc_sa2shared(sa);
 
-	switch (sw_xstat->type) {
+	switch (sw_stat->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);
+			__func__, sw_stat->type);
 		return 0;
 	}
 }
@@ -132,17 +132,17 @@ sfc_sw_xstat_per_queue_get_count(unsigned int nb_queues)
 
 static unsigned int
 sfc_sw_xstat_get_nb_supported(struct sfc_adapter *sa,
-			      const struct sfc_sw_xstat_descr *sw_xstat)
+			      const struct sfc_sw_stat_descr *sw_stat)
 {
 	unsigned int nb_queues;
 
-	nb_queues = sfc_sw_stat_get_queue_count(sa, sw_xstat);
+	nb_queues = sfc_sw_stat_get_queue_count(sa, sw_stat);
 	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,
+		      const struct sfc_sw_stat_descr *sw_stat,
 		      struct rte_eth_xstat_name *xstats_names,
 		      unsigned int xstats_names_sz,
 		      unsigned int *nb_written,
@@ -154,7 +154,7 @@ sfc_sw_stat_get_names(struct sfc_adapter *sa,
 	unsigned int qid;
 	int rc;
 
-	nb_queues = sfc_sw_stat_get_queue_count(sa, sw_xstat);
+	nb_queues = sfc_sw_stat_get_queue_count(sa, sw_stat);
 	if (nb_queues == 0)
 		return 0;
 	*nb_supported += sfc_sw_xstat_per_queue_get_count(nb_queues);
@@ -164,7 +164,7 @@ sfc_sw_stat_get_names(struct sfc_adapter *sa,
 	 * followed by per-queue xstats.
 	 */
 	if (*nb_written < xstats_names_sz) {
-		rc = sfc_sw_stat_get_name(sa, sw_xstat,
+		rc = sfc_sw_stat_get_name(sa, sw_stat,
 					  xstats_names[*nb_written].name,
 					  name_size, *nb_written - id_base);
 		if (rc != 0)
@@ -174,7 +174,7 @@ sfc_sw_stat_get_names(struct sfc_adapter *sa,
 
 	for (qid = 0; qid < nb_queues; ++qid) {
 		if (*nb_written < xstats_names_sz) {
-			rc = sfc_sw_stat_get_name(sa, sw_xstat,
+			rc = sfc_sw_stat_get_name(sa, sw_stat,
 					      xstats_names[*nb_written].name,
 					      name_size, *nb_written - id_base);
 			if (rc != 0)
@@ -188,7 +188,7 @@ sfc_sw_stat_get_names(struct sfc_adapter *sa,
 
 static int
 sfc_sw_xstat_get_names_by_id(struct sfc_adapter *sa,
-			     const struct sfc_sw_xstat_descr *sw_xstat,
+			     const struct sfc_sw_stat_descr *sw_stat,
 			     const uint64_t *ids,
 			     struct rte_eth_xstat_name *xstats_names,
 			     unsigned int size,
@@ -200,7 +200,7 @@ sfc_sw_xstat_get_names_by_id(struct sfc_adapter *sa,
 	unsigned int i;
 	int rc;
 
-	nb_queues = sfc_sw_stat_get_queue_count(sa, sw_xstat);
+	nb_queues = sfc_sw_stat_get_queue_count(sa, sw_stat);
 	if (nb_queues == 0)
 		return 0;
 	*nb_supported += sfc_sw_xstat_per_queue_get_count(nb_queues);
@@ -211,7 +211,7 @@ sfc_sw_xstat_get_names_by_id(struct sfc_adapter *sa,
 	 */
 	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,
+			rc = sfc_sw_stat_get_name(sa, sw_stat,
 						  xstats_names[i].name,
 						  name_size, ids[i] - id_base);
 			if (rc != 0)
@@ -224,7 +224,7 @@ sfc_sw_xstat_get_names_by_id(struct sfc_adapter *sa,
 
 static void
 sfc_sw_xstat_get_values(struct sfc_adapter *sa,
-			const struct sfc_sw_xstat_descr *sw_xstat,
+			const struct sfc_sw_stat_descr *sw_stat,
 			struct rte_eth_xstat *xstats,
 			unsigned int xstats_size,
 			unsigned int *nb_written,
@@ -236,7 +236,7 @@ sfc_sw_xstat_get_values(struct sfc_adapter *sa,
 	bool count_total_value = false;
 	unsigned int nb_queues;
 
-	nb_queues = sfc_sw_stat_get_queue_count(sa, sw_xstat);
+	nb_queues = sfc_sw_stat_get_queue_count(sa, sw_stat);
 	if (nb_queues == 0)
 		return;
 	*nb_supported += sfc_sw_xstat_per_queue_get_count(nb_queues);
@@ -254,7 +254,7 @@ sfc_sw_xstat_get_values(struct sfc_adapter *sa,
 	}
 
 	for (qid = 0; qid < nb_queues; ++qid) {
-		value = sw_xstat->get_val(sa, qid);
+		value = sw_stat->get_val(sa, qid);
 
 		if (*nb_written < xstats_size) {
 			xstats[*nb_written].id = *nb_written;
@@ -269,14 +269,14 @@ sfc_sw_xstat_get_values(struct sfc_adapter *sa,
 
 static void
 sfc_sw_xstat_get_values_by_id(struct sfc_adapter *sa,
-			      const struct sfc_sw_xstat_descr *sw_xstat,
+			      const struct sfc_sw_stat_descr *sw_stat,
 			      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;
+	rte_spinlock_t *bmp_lock = &sa->sw_stats.queues_bitmap_lock;
+	struct rte_bitmap *bmp = sa->sw_stats.queues_bitmap;
 	unsigned int id_base = *nb_supported;
 	bool count_total_value = false;
 	unsigned int total_value_idx;
@@ -288,7 +288,7 @@ sfc_sw_xstat_get_values_by_id(struct sfc_adapter *sa,
 	rte_spinlock_lock(bmp_lock);
 	rte_bitmap_reset(bmp);
 
-	nb_queues = sfc_sw_stat_get_queue_count(sa, sw_xstat);
+	nb_queues = sfc_sw_stat_get_queue_count(sa, sw_stat);
 	if (nb_queues == 0)
 		goto unlock;
 	*nb_supported += sfc_sw_xstat_per_queue_get_count(nb_queues);
@@ -305,7 +305,7 @@ sfc_sw_xstat_get_values_by_id(struct sfc_adapter *sa,
 				continue;
 			}
 			qid = ids[i] - id_base - 1;
-			values[i] = sw_xstat->get_val(sa, qid);
+			values[i] = sw_stat->get_val(sa, qid);
 			total_value += values[i];
 
 			rte_bitmap_set(bmp, qid);
@@ -317,7 +317,7 @@ sfc_sw_xstat_get_values_by_id(struct sfc_adapter *sa,
 		for (qid = 0; qid < nb_queues; ++qid) {
 			if (rte_bitmap_get(bmp, qid) != 0)
 				continue;
-			values[total_value_idx] += sw_xstat->get_val(sa, qid);
+			values[total_value_idx] += sw_stat->get_val(sa, qid);
 		}
 		values[total_value_idx] += total_value;
 	}
@@ -349,7 +349,7 @@ sfc_sw_xstats_get_vals(struct sfc_adapter *sa,
 		       unsigned int *nb_written,
 		       unsigned int *nb_supported)
 {
-	uint64_t *reset_vals = sa->sw_xstats.reset_vals;
+	uint64_t *reset_vals = sa->sw_stats.reset_vals;
 	unsigned int sw_xstats_offset;
 	unsigned int i;
 
@@ -402,7 +402,7 @@ sfc_sw_xstats_get_vals_by_id(struct sfc_adapter *sa,
 			     unsigned int n,
 			     unsigned int *nb_supported)
 {
-	uint64_t *reset_vals = sa->sw_xstats.reset_vals;
+	uint64_t *reset_vals = sa->sw_stats.reset_vals;
 	unsigned int sw_xstats_offset;
 	unsigned int i;
 
@@ -452,7 +452,7 @@ sfc_sw_xstats_get_names_by_id(struct sfc_adapter *sa,
 }
 
 static void
-sfc_sw_xstat_reset(struct sfc_adapter *sa, struct sfc_sw_xstat_descr *sw_xstat,
+sfc_sw_xstat_reset(struct sfc_adapter *sa, struct sfc_sw_stat_descr *sw_stat,
 		   uint64_t *reset_vals)
 {
 	unsigned int nb_queues;
@@ -461,7 +461,7 @@ sfc_sw_xstat_reset(struct sfc_adapter *sa, struct sfc_sw_xstat_descr *sw_xstat,
 
 	SFC_ASSERT(sfc_adapter_is_locked(sa));
 
-	nb_queues = sfc_sw_stat_get_queue_count(sa, sw_xstat);
+	nb_queues = sfc_sw_stat_get_queue_count(sa, sw_stat);
 	if (nb_queues == 0)
 		return;
 
@@ -474,7 +474,7 @@ sfc_sw_xstat_reset(struct sfc_adapter *sa, struct sfc_sw_xstat_descr *sw_xstat,
 	reset_vals++;
 
 	for (qid = 0; qid < nb_queues; ++qid) {
-		reset_vals[qid] = sw_xstat->get_val(sa, qid);
+		reset_vals[qid] = sw_stat->get_val(sa, qid);
 		*total_xstat_reset += reset_vals[qid];
 	}
 }
@@ -482,23 +482,23 @@ sfc_sw_xstat_reset(struct sfc_adapter *sa, struct sfc_sw_xstat_descr *sw_xstat,
 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;
+	uint64_t *reset_vals = sa->sw_stats.reset_vals;
+	struct sfc_sw_stat_descr *sw_stat;
 	unsigned int i;
 
 	SFC_ASSERT(sfc_adapter_is_locked(sa));
 
 	for (i = 0; i < RTE_DIM(sfc_sw_stats_descr); i++) {
-		sw_xstat = &sfc_sw_stats_descr[i];
-		sfc_sw_xstat_reset(sa, sw_xstat, reset_vals);
-		reset_vals += sfc_sw_xstat_get_nb_supported(sa, sw_xstat);
+		sw_stat = &sfc_sw_stats_descr[i];
+		sfc_sw_xstat_reset(sa, sw_stat, reset_vals);
+		reset_vals += sfc_sw_xstat_get_nb_supported(sa, sw_stat);
 	}
 }
 
 int
 sfc_sw_xstats_configure(struct sfc_adapter *sa)
 {
-	uint64_t **reset_vals = &sa->sw_xstats.reset_vals;
+	uint64_t **reset_vals = &sa->sw_stats.reset_vals;
 	size_t nb_supported = 0;
 	unsigned int i;
 
@@ -519,15 +519,15 @@ sfc_sw_xstats_configure(struct sfc_adapter *sa)
 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);
+	rte_bitmap_free(sa->sw_stats.queues_bitmap);
+	rte_free(sa->sw_stats.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;
+	struct rte_bitmap **queues_bitmap = &sa->sw_stats.queues_bitmap;
+	void **queues_bitmap_mem = &sa->sw_stats.queues_bitmap_mem;
 	uint32_t bmp_size;
 	int rc;
 
@@ -547,7 +547,7 @@ sfc_sw_xstats_alloc_queues_bitmap(struct sfc_adapter *sa)
 		goto fail;
 	}
 
-	rte_spinlock_init(&sa->sw_xstats.queues_bitmap_lock);
+	rte_spinlock_init(&sa->sw_stats.queues_bitmap_lock);
 	return 0;
 
 fail:
@@ -558,7 +558,7 @@ sfc_sw_xstats_alloc_queues_bitmap(struct sfc_adapter *sa)
 int
 sfc_sw_xstats_init(struct sfc_adapter *sa)
 {
-	sa->sw_xstats.reset_vals = NULL;
+	sa->sw_stats.reset_vals = NULL;
 
 	return sfc_sw_xstats_alloc_queues_bitmap(sa);
 }
@@ -566,8 +566,8 @@ sfc_sw_xstats_init(struct sfc_adapter *sa)
 void
 sfc_sw_xstats_close(struct sfc_adapter *sa)
 {
-	rte_free(sa->sw_xstats.reset_vals);
-	sa->sw_xstats.reset_vals = NULL;
+	rte_free(sa->sw_stats.reset_vals);
+	sa->sw_stats.reset_vals = NULL;
 
 	sfc_sw_xstats_free_queues_bitmap(sa);
 }
-- 
2.30.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [dpdk-dev] [PATCH 04/11] net/sfc: fix cleanup order of SW stats
  2021-09-28 11:29 [dpdk-dev] [PATCH 00/11] net/sfc: support per-queue stats on EF100 Andrew Rybchenko
                   ` (2 preceding siblings ...)
  2021-09-28 11:29 ` [dpdk-dev] [PATCH 03/11] net/sfc: rename SW stats structures Andrew Rybchenko
@ 2021-09-28 11:29 ` Andrew Rybchenko
  2021-09-28 11:29 ` [dpdk-dev] [PATCH 05/11] net/sfc: fix missing const of SW stats descriptions Andrew Rybchenko
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Andrew Rybchenko @ 2021-09-28 11:29 UTC (permalink / raw)
  To: dev; +Cc: Ivan Ilchenko, stable

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

Fix cleanup order of SW stats structures to be reversed
to initialization order.

Fixes: fdd7719eb3c ("net/sfc: add xstats for Rx/Tx doorbells")
Cc: stable@dpdk.org

Signed-off-by: Ivan Ilchenko <ivan.ilchenko@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 drivers/net/sfc/sfc_sw_stats.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/sfc/sfc_sw_stats.c b/drivers/net/sfc/sfc_sw_stats.c
index 108f301822..c297bb8294 100644
--- a/drivers/net/sfc/sfc_sw_stats.c
+++ b/drivers/net/sfc/sfc_sw_stats.c
@@ -566,8 +566,7 @@ sfc_sw_xstats_init(struct sfc_adapter *sa)
 void
 sfc_sw_xstats_close(struct sfc_adapter *sa)
 {
+	sfc_sw_xstats_free_queues_bitmap(sa);
 	rte_free(sa->sw_stats.reset_vals);
 	sa->sw_stats.reset_vals = NULL;
-
-	sfc_sw_xstats_free_queues_bitmap(sa);
 }
-- 
2.30.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [dpdk-dev] [PATCH 05/11] net/sfc: fix missing const of SW stats descriptions
  2021-09-28 11:29 [dpdk-dev] [PATCH 00/11] net/sfc: support per-queue stats on EF100 Andrew Rybchenko
                   ` (3 preceding siblings ...)
  2021-09-28 11:29 ` [dpdk-dev] [PATCH 04/11] net/sfc: fix cleanup order of SW stats Andrew Rybchenko
@ 2021-09-28 11:29 ` Andrew Rybchenko
  2021-09-28 11:29 ` [dpdk-dev] [PATCH 06/11] net/sfc: optimize getting number of SW stats Andrew Rybchenko
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Andrew Rybchenko @ 2021-09-28 11:29 UTC (permalink / raw)
  To: dev; +Cc: Ivan Ilchenko, stable

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

Description is a global variable shared by all adapters and must
not be modified.

Fixes: fdd7719eb3c ("net/sfc: add xstats for Rx/Tx doorbells")
Cc: stable@dpdk.org

Signed-off-by: Ivan Ilchenko <ivan.ilchenko@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 drivers/net/sfc/sfc_sw_stats.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/sfc/sfc_sw_stats.c b/drivers/net/sfc/sfc_sw_stats.c
index c297bb8294..de99e1cfaf 100644
--- a/drivers/net/sfc/sfc_sw_stats.c
+++ b/drivers/net/sfc/sfc_sw_stats.c
@@ -49,7 +49,7 @@ sfc_get_sw_stat_val_tx_dbells(struct sfc_adapter *sa, uint16_t qid)
 	return 0;
 }
 
-struct sfc_sw_stat_descr sfc_sw_stats_descr[] = {
+const struct sfc_sw_stat_descr sfc_sw_stats_descr[] = {
 	{
 		.name = "dbells",
 		.type = SFC_SW_STATS_RX,
@@ -452,7 +452,8 @@ sfc_sw_xstats_get_names_by_id(struct sfc_adapter *sa,
 }
 
 static void
-sfc_sw_xstat_reset(struct sfc_adapter *sa, struct sfc_sw_stat_descr *sw_stat,
+sfc_sw_xstat_reset(struct sfc_adapter *sa,
+		   const struct sfc_sw_stat_descr *sw_stat,
 		   uint64_t *reset_vals)
 {
 	unsigned int nb_queues;
@@ -483,7 +484,7 @@ void
 sfc_sw_xstats_reset(struct sfc_adapter *sa)
 {
 	uint64_t *reset_vals = sa->sw_stats.reset_vals;
-	struct sfc_sw_stat_descr *sw_stat;
+	const struct sfc_sw_stat_descr *sw_stat;
 	unsigned int i;
 
 	SFC_ASSERT(sfc_adapter_is_locked(sa));
-- 
2.30.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [dpdk-dev] [PATCH 06/11] net/sfc: optimize getting number of SW stats
  2021-09-28 11:29 [dpdk-dev] [PATCH 00/11] net/sfc: support per-queue stats on EF100 Andrew Rybchenko
                   ` (4 preceding siblings ...)
  2021-09-28 11:29 ` [dpdk-dev] [PATCH 05/11] net/sfc: fix missing const of SW stats descriptions Andrew Rybchenko
@ 2021-09-28 11:29 ` Andrew Rybchenko
  2021-09-28 11:29 ` [dpdk-dev] [PATCH 07/11] net/sfc: prepare having no some SW stats on an adapter Andrew Rybchenko
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Andrew Rybchenko @ 2021-09-28 11:29 UTC (permalink / raw)
  To: dev; +Cc: Ivan Ilchenko

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

Optimize getting number of SW stats by caching the
value during device configure since it's the only
place it may change.

Signed-off-by: Ivan Ilchenko <ivan.ilchenko@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 drivers/net/sfc/sfc.h          |  2 ++
 drivers/net/sfc/sfc_sw_stats.c | 14 ++++----------
 2 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 93d5202a24..b9ff8baed2 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -218,6 +218,8 @@ struct sfc_counter_rxq {
 };
 
 struct sfc_sw_stats {
+	/* Number extended statistics provided by SW stats */
+	unsigned int			xstats_count;
 	uint64_t			*reset_vals;
 
 	rte_spinlock_t			queues_bitmap_lock;
diff --git a/drivers/net/sfc/sfc_sw_stats.c b/drivers/net/sfc/sfc_sw_stats.c
index de99e1cfaf..0f93091500 100644
--- a/drivers/net/sfc/sfc_sw_stats.c
+++ b/drivers/net/sfc/sfc_sw_stats.c
@@ -329,17 +329,8 @@ sfc_sw_xstat_get_values_by_id(struct sfc_adapter *sa,
 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_stats_descr); i++) {
-		nb_supported += sfc_sw_xstat_get_nb_supported(sa,
-							&sfc_sw_stats_descr[i]);
-	}
-
-	return nb_supported;
+	return sa->sw_stats.xstats_count;
 }
 
 void
@@ -506,6 +497,7 @@ sfc_sw_xstats_configure(struct sfc_adapter *sa)
 	for (i = 0; i < RTE_DIM(sfc_sw_stats_descr); i++)
 		nb_supported += sfc_sw_xstat_get_nb_supported(sa,
 							&sfc_sw_stats_descr[i]);
+	sa->sw_stats.xstats_count = nb_supported;
 
 	*reset_vals = rte_realloc(*reset_vals,
 				  nb_supported * sizeof(**reset_vals), 0);
@@ -559,6 +551,7 @@ sfc_sw_xstats_alloc_queues_bitmap(struct sfc_adapter *sa)
 int
 sfc_sw_xstats_init(struct sfc_adapter *sa)
 {
+	sa->sw_stats.xstats_count = 0;
 	sa->sw_stats.reset_vals = NULL;
 
 	return sfc_sw_xstats_alloc_queues_bitmap(sa);
@@ -570,4 +563,5 @@ sfc_sw_xstats_close(struct sfc_adapter *sa)
 	sfc_sw_xstats_free_queues_bitmap(sa);
 	rte_free(sa->sw_stats.reset_vals);
 	sa->sw_stats.reset_vals = NULL;
+	sa->sw_stats.xstats_count = 0;
 }
-- 
2.30.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [dpdk-dev] [PATCH 07/11] net/sfc: prepare having no some SW stats on an adapter
  2021-09-28 11:29 [dpdk-dev] [PATCH 00/11] net/sfc: support per-queue stats on EF100 Andrew Rybchenko
                   ` (5 preceding siblings ...)
  2021-09-28 11:29 ` [dpdk-dev] [PATCH 06/11] net/sfc: optimize getting number of SW stats Andrew Rybchenko
@ 2021-09-28 11:29 ` Andrew Rybchenko
  2021-09-28 11:29 ` [dpdk-dev] [PATCH 08/11] net/sfc: add toggle to disable total stat Andrew Rybchenko
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Andrew Rybchenko @ 2021-09-28 11:29 UTC (permalink / raw)
  To: dev; +Cc: Ivan Ilchenko

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

Global description structure of SW stats is used currently.
Following patches introduce SW stats that may be unavailable
for some adapters, so add per-adapter descriptions to safely
work with multiple adapters.

Signed-off-by: Ivan Ilchenko <ivan.ilchenko@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 drivers/net/sfc/sfc.h          |  7 ++++
 drivers/net/sfc/sfc_sw_stats.c | 65 +++++++++++++++++++++++++---------
 2 files changed, 55 insertions(+), 17 deletions(-)

diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index b9ff8baed2..5a40a73c7f 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -217,9 +217,16 @@ struct sfc_counter_rxq {
 	struct rte_mempool		*mp;
 };
 
+struct sfc_sw_stat_data {
+	const struct sfc_sw_stat_descr *descr;
+};
+
 struct sfc_sw_stats {
 	/* Number extended statistics provided by SW stats */
 	unsigned int			xstats_count;
+	/* Supported SW statistics */
+	struct sfc_sw_stat_data		*supp;
+	unsigned int			supp_count;
 	uint64_t			*reset_vals;
 
 	rte_spinlock_t			queues_bitmap_lock;
diff --git a/drivers/net/sfc/sfc_sw_stats.c b/drivers/net/sfc/sfc_sw_stats.c
index 0f93091500..a9ab29064a 100644
--- a/drivers/net/sfc/sfc_sw_stats.c
+++ b/drivers/net/sfc/sfc_sw_stats.c
@@ -341,6 +341,7 @@ sfc_sw_xstats_get_vals(struct sfc_adapter *sa,
 		       unsigned int *nb_supported)
 {
 	uint64_t *reset_vals = sa->sw_stats.reset_vals;
+	struct sfc_sw_stats *sw_stats = &sa->sw_stats;
 	unsigned int sw_xstats_offset;
 	unsigned int i;
 
@@ -348,8 +349,8 @@ sfc_sw_xstats_get_vals(struct sfc_adapter *sa,
 
 	sw_xstats_offset = *nb_supported;
 
-	for (i = 0; i < RTE_DIM(sfc_sw_stats_descr); i++) {
-		sfc_sw_xstat_get_values(sa, &sfc_sw_stats_descr[i], xstats,
+	for (i = 0; i < sw_stats->xstats_count; i++) {
+		sfc_sw_xstat_get_values(sa, sw_stats->supp[i].descr, xstats,
 					xstats_count, nb_written, nb_supported);
 	}
 
@@ -366,13 +367,14 @@ sfc_sw_xstats_get_names(struct sfc_adapter *sa,
 			unsigned int *nb_written,
 			unsigned int *nb_supported)
 {
+	struct sfc_sw_stats *sw_stats = &sa->sw_stats;
 	unsigned int i;
 	int ret;
 
 	sfc_adapter_lock(sa);
 
-	for (i = 0; i < RTE_DIM(sfc_sw_stats_descr); i++) {
-		ret = sfc_sw_stat_get_names(sa, &sfc_sw_stats_descr[i],
+	for (i = 0; i < sw_stats->supp_count; i++) {
+		ret = sfc_sw_stat_get_names(sa, sw_stats->supp[i].descr,
 					    xstats_names, xstats_count,
 					    nb_written, nb_supported);
 		if (ret != 0) {
@@ -394,6 +396,7 @@ sfc_sw_xstats_get_vals_by_id(struct sfc_adapter *sa,
 			     unsigned int *nb_supported)
 {
 	uint64_t *reset_vals = sa->sw_stats.reset_vals;
+	struct sfc_sw_stats *sw_stats = &sa->sw_stats;
 	unsigned int sw_xstats_offset;
 	unsigned int i;
 
@@ -401,8 +404,8 @@ sfc_sw_xstats_get_vals_by_id(struct sfc_adapter *sa,
 
 	sw_xstats_offset = *nb_supported;
 
-	for (i = 0; i < RTE_DIM(sfc_sw_stats_descr); i++) {
-		sfc_sw_xstat_get_values_by_id(sa, &sfc_sw_stats_descr[i], ids,
+	for (i = 0; i < sw_stats->supp_count; i++) {
+		sfc_sw_xstat_get_values_by_id(sa, sw_stats->supp[i].descr, ids,
 					      values, n, nb_supported);
 	}
 
@@ -421,13 +424,14 @@ sfc_sw_xstats_get_names_by_id(struct sfc_adapter *sa,
 			      unsigned int size,
 			      unsigned int *nb_supported)
 {
+	struct sfc_sw_stats *sw_stats = &sa->sw_stats;
 	unsigned int i;
 	int ret;
 
 	sfc_adapter_lock(sa);
 
-	for (i = 0; i < RTE_DIM(sfc_sw_stats_descr); i++) {
-		ret = sfc_sw_xstat_get_names_by_id(sa, &sfc_sw_stats_descr[i],
+	for (i = 0; i < sw_stats->supp_count; i++) {
+		ret = sfc_sw_xstat_get_names_by_id(sa, sw_stats->supp[i].descr,
 						   ids, xstats_names, size,
 						   nb_supported);
 		if (ret != 0) {
@@ -475,15 +479,15 @@ void
 sfc_sw_xstats_reset(struct sfc_adapter *sa)
 {
 	uint64_t *reset_vals = sa->sw_stats.reset_vals;
-	const struct sfc_sw_stat_descr *sw_stat;
+	struct sfc_sw_stats *sw_stats = &sa->sw_stats;
 	unsigned int i;
 
 	SFC_ASSERT(sfc_adapter_is_locked(sa));
 
-	for (i = 0; i < RTE_DIM(sfc_sw_stats_descr); i++) {
-		sw_stat = &sfc_sw_stats_descr[i];
-		sfc_sw_xstat_reset(sa, sw_stat, reset_vals);
-		reset_vals += sfc_sw_xstat_get_nb_supported(sa, sw_stat);
+	for (i = 0; i < sw_stats->supp_count; i++) {
+		sfc_sw_xstat_reset(sa, sw_stats->supp[i].descr, reset_vals);
+		reset_vals += sfc_sw_xstat_get_nb_supported(sa,
+						       sw_stats->supp[i].descr);
 	}
 }
 
@@ -491,22 +495,44 @@ int
 sfc_sw_xstats_configure(struct sfc_adapter *sa)
 {
 	uint64_t **reset_vals = &sa->sw_stats.reset_vals;
+	struct sfc_sw_stats *sw_stats = &sa->sw_stats;
 	size_t nb_supported = 0;
 	unsigned int i;
+	int rc;
+
+	sw_stats->supp_count = RTE_DIM(sfc_sw_stats_descr);
+	if (sw_stats->supp == NULL) {
+		sw_stats->supp = rte_malloc(NULL, sw_stats->supp_count *
+					    sizeof(*sw_stats->supp), 0);
+		if (sw_stats->supp == NULL)
+			return -ENOMEM;
+	}
+	for (i = 0; i < sw_stats->supp_count; i++)
+		sw_stats->supp[i].descr = &sfc_sw_stats_descr[i];
 
-	for (i = 0; i < RTE_DIM(sfc_sw_stats_descr); i++)
+	for (i = 0; i < sw_stats->supp_count; i++)
 		nb_supported += sfc_sw_xstat_get_nb_supported(sa,
-							&sfc_sw_stats_descr[i]);
+						       sw_stats->supp[i].descr);
 	sa->sw_stats.xstats_count = nb_supported;
 
 	*reset_vals = rte_realloc(*reset_vals,
 				  nb_supported * sizeof(**reset_vals), 0);
-	if (*reset_vals == NULL)
-		return ENOMEM;
+	if (*reset_vals == NULL) {
+		rc = -ENOMEM;
+		goto fail_reset_vals;
+	}
 
 	memset(*reset_vals, 0, nb_supported * sizeof(**reset_vals));
 
 	return 0;
+
+fail_reset_vals:
+	sa->sw_stats.xstats_count = 0;
+	rte_free(sw_stats->supp);
+	sw_stats->supp = NULL;
+	sw_stats->supp_count = 0;
+
+	return rc;
 }
 
 static void
@@ -552,6 +578,8 @@ int
 sfc_sw_xstats_init(struct sfc_adapter *sa)
 {
 	sa->sw_stats.xstats_count = 0;
+	sa->sw_stats.supp = NULL;
+	sa->sw_stats.supp_count = 0;
 	sa->sw_stats.reset_vals = NULL;
 
 	return sfc_sw_xstats_alloc_queues_bitmap(sa);
@@ -563,5 +591,8 @@ sfc_sw_xstats_close(struct sfc_adapter *sa)
 	sfc_sw_xstats_free_queues_bitmap(sa);
 	rte_free(sa->sw_stats.reset_vals);
 	sa->sw_stats.reset_vals = NULL;
+	rte_free(sa->sw_stats.supp);
+	sa->sw_stats.supp = NULL;
+	sa->sw_stats.supp_count = 0;
 	sa->sw_stats.xstats_count = 0;
 }
-- 
2.30.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [dpdk-dev] [PATCH 08/11] net/sfc: add toggle to disable total stat
  2021-09-28 11:29 [dpdk-dev] [PATCH 00/11] net/sfc: support per-queue stats on EF100 Andrew Rybchenko
                   ` (6 preceding siblings ...)
  2021-09-28 11:29 ` [dpdk-dev] [PATCH 07/11] net/sfc: prepare having no some SW stats on an adapter Andrew Rybchenko
@ 2021-09-28 11:29 ` Andrew Rybchenko
  2021-09-28 11:29 ` [dpdk-dev] [PATCH 09/11] net/sfc: add support for SW stats groups Andrew Rybchenko
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Andrew Rybchenko @ 2021-09-28 11:29 UTC (permalink / raw)
  To: dev; +Cc: Ivan Ilchenko

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

Add toggle to disable total SW stat. This is useful
for per-queue 'packets' and 'bytes' to not conflict
with corresponding basic stats. These stats will be
added in the following patches.

Signed-off-by: Ivan Ilchenko <ivan.ilchenko@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 drivers/net/sfc/sfc_sw_stats.c | 54 +++++++++++++++++++++-------------
 1 file changed, 34 insertions(+), 20 deletions(-)

diff --git a/drivers/net/sfc/sfc_sw_stats.c b/drivers/net/sfc/sfc_sw_stats.c
index a9ab29064a..63fc334d2b 100644
--- a/drivers/net/sfc/sfc_sw_stats.c
+++ b/drivers/net/sfc/sfc_sw_stats.c
@@ -21,6 +21,7 @@ struct sfc_sw_stat_descr {
 	const char *name;
 	enum sfc_sw_stats_type type;
 	sfc_get_sw_stat_val_t *get_val;
+	bool provide_total;
 };
 
 static sfc_get_sw_stat_val_t sfc_get_sw_stat_val_rx_dbells;
@@ -54,11 +55,13 @@ const struct sfc_sw_stat_descr sfc_sw_stats_descr[] = {
 		.name = "dbells",
 		.type = SFC_SW_STATS_RX,
 		.get_val  = sfc_get_sw_stat_val_rx_dbells,
+		.provide_total = true,
 	},
 	{
 		.name = "dbells",
 		.type = SFC_SW_STATS_TX,
 		.get_val  = sfc_get_sw_stat_val_tx_dbells,
+		.provide_total = true,
 	}
 };
 
@@ -83,7 +86,7 @@ sfc_sw_stat_get_name(struct sfc_adapter *sa,
 		return -EINVAL;
 	}
 
-	if (id_off == 0) {
+	if (sw_stat->provide_total && id_off == 0) {
 		ret = snprintf(name, name_size, "%s_%s", prefix,
 							 sw_stat->name);
 		if (ret < 0 || ret >= (int)name_size) {
@@ -92,7 +95,7 @@ sfc_sw_stat_get_name(struct sfc_adapter *sa,
 			return ret > 0 ? -EINVAL : ret;
 		}
 	} else {
-		uint16_t qid = id_off - 1;
+		uint16_t qid = id_off - sw_stat->provide_total;
 		ret = snprintf(name, name_size, "%s_q%u_%s", prefix, qid,
 							sw_stat->name);
 		if (ret < 0 || ret >= (int)name_size) {
@@ -124,10 +127,11 @@ sfc_sw_stat_get_queue_count(struct sfc_adapter *sa,
 }
 
 static unsigned int
-sfc_sw_xstat_per_queue_get_count(unsigned int nb_queues)
+sfc_sw_xstat_per_queue_get_count(const struct sfc_sw_stat_descr *sw_stat,
+				 unsigned int nb_queues)
 {
 	/* Take into account the total xstat of all queues */
-	return nb_queues > 0 ? 1 + nb_queues : 0;
+	return nb_queues > 0 ? sw_stat->provide_total + nb_queues : 0;
 }
 
 static unsigned int
@@ -137,7 +141,7 @@ sfc_sw_xstat_get_nb_supported(struct sfc_adapter *sa,
 	unsigned int nb_queues;
 
 	nb_queues = sfc_sw_stat_get_queue_count(sa, sw_stat);
-	return sfc_sw_xstat_per_queue_get_count(nb_queues);
+	return sfc_sw_xstat_per_queue_get_count(sw_stat, nb_queues);
 }
 
 static int
@@ -157,13 +161,13 @@ sfc_sw_stat_get_names(struct sfc_adapter *sa,
 	nb_queues = sfc_sw_stat_get_queue_count(sa, sw_stat);
 	if (nb_queues == 0)
 		return 0;
-	*nb_supported += sfc_sw_xstat_per_queue_get_count(nb_queues);
+	*nb_supported += sfc_sw_xstat_per_queue_get_count(sw_stat, nb_queues);
 
 	/*
 	 * The order of each software xstat type is the total xstat
 	 * followed by per-queue xstats.
 	 */
-	if (*nb_written < xstats_names_sz) {
+	if (*nb_written < xstats_names_sz && sw_stat->provide_total) {
 		rc = sfc_sw_stat_get_name(sa, sw_stat,
 					  xstats_names[*nb_written].name,
 					  name_size, *nb_written - id_base);
@@ -196,6 +200,7 @@ sfc_sw_xstat_get_names_by_id(struct sfc_adapter *sa,
 {
 	const size_t name_size = sizeof(xstats_names[0].name);
 	unsigned int id_base = *nb_supported;
+	unsigned int id_end;
 	unsigned int nb_queues;
 	unsigned int i;
 	int rc;
@@ -203,14 +208,15 @@ sfc_sw_xstat_get_names_by_id(struct sfc_adapter *sa,
 	nb_queues = sfc_sw_stat_get_queue_count(sa, sw_stat);
 	if (nb_queues == 0)
 		return 0;
-	*nb_supported += sfc_sw_xstat_per_queue_get_count(nb_queues);
+	*nb_supported += sfc_sw_xstat_per_queue_get_count(sw_stat, nb_queues);
 
 	/*
 	 * The order of each software xstat type is the total xstat
 	 * followed by per-queue xstats.
 	 */
+	id_end = id_base + sw_stat->provide_total + nb_queues;
 	for (i = 0; i < size; i++) {
-		if (id_base <= ids[i] && ids[i] <= id_base + nb_queues) {
+		if (id_base <= ids[i] && ids[i] < id_end) {
 			rc = sfc_sw_stat_get_name(sa, sw_stat,
 						  xstats_names[i].name,
 						  name_size, ids[i] - id_base);
@@ -239,13 +245,13 @@ sfc_sw_xstat_get_values(struct sfc_adapter *sa,
 	nb_queues = sfc_sw_stat_get_queue_count(sa, sw_stat);
 	if (nb_queues == 0)
 		return;
-	*nb_supported += sfc_sw_xstat_per_queue_get_count(nb_queues);
+	*nb_supported += sfc_sw_xstat_per_queue_get_count(sw_stat, nb_queues);
 
 	/*
 	 * The order of each software xstat type is the total xstat
 	 * followed by per-queue xstats.
 	 */
-	if (*nb_written < xstats_size) {
+	if (*nb_written < xstats_size && sw_stat->provide_total) {
 		count_total_value = true;
 		total_xstat = &xstats[*nb_written];
 		xstats[*nb_written].id = *nb_written;
@@ -278,6 +284,8 @@ sfc_sw_xstat_get_values_by_id(struct sfc_adapter *sa,
 	rte_spinlock_t *bmp_lock = &sa->sw_stats.queues_bitmap_lock;
 	struct rte_bitmap *bmp = sa->sw_stats.queues_bitmap;
 	unsigned int id_base = *nb_supported;
+	unsigned int id_base_q;
+	unsigned int id_end;
 	bool count_total_value = false;
 	unsigned int total_value_idx;
 	uint64_t total_value = 0;
@@ -291,20 +299,23 @@ sfc_sw_xstat_get_values_by_id(struct sfc_adapter *sa,
 	nb_queues = sfc_sw_stat_get_queue_count(sa, sw_stat);
 	if (nb_queues == 0)
 		goto unlock;
-	*nb_supported += sfc_sw_xstat_per_queue_get_count(nb_queues);
+	*nb_supported += sfc_sw_xstat_per_queue_get_count(sw_stat, nb_queues);
 
 	/*
 	 * The order of each software xstat type is the total xstat
 	 * followed by per-queue xstats.
 	 */
+	id_end = id_base + sw_stat->provide_total + nb_queues;
 	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 */
+		if (id_base <= ids[i] && ids[i] < id_end) {
+			if (sw_stat->provide_total && ids[i] == id_base) {
+				/* Accumulative value */
 				count_total_value = true;
 				total_value_idx = i;
 				continue;
 			}
-			qid = ids[i] - id_base - 1;
+			id_base_q = id_base + sw_stat->provide_total;
+			qid = ids[i] - id_base_q;
 			values[i] = sw_stat->get_val(sa, qid);
 			total_value += values[i];
 
@@ -453,7 +464,7 @@ sfc_sw_xstat_reset(struct sfc_adapter *sa,
 {
 	unsigned int nb_queues;
 	unsigned int qid;
-	uint64_t *total_xstat_reset;
+	uint64_t *total_xstat_reset = NULL;
 
 	SFC_ASSERT(sfc_adapter_is_locked(sa));
 
@@ -465,13 +476,16 @@ sfc_sw_xstat_reset(struct sfc_adapter *sa,
 	 * The order of each software xstat type is the total xstat
 	 * followed by per-queue xstats.
 	 */
-	total_xstat_reset = reset_vals;
-	*total_xstat_reset = 0;
-	reset_vals++;
+	if (sw_stat->provide_total) {
+		total_xstat_reset = reset_vals;
+		*total_xstat_reset = 0;
+		reset_vals++;
+	}
 
 	for (qid = 0; qid < nb_queues; ++qid) {
 		reset_vals[qid] = sw_stat->get_val(sa, qid);
-		*total_xstat_reset += reset_vals[qid];
+		if (sw_stat->provide_total)
+			*total_xstat_reset += reset_vals[qid];
 	}
 }
 
-- 
2.30.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [dpdk-dev] [PATCH 09/11] net/sfc: add support for SW stats groups
  2021-09-28 11:29 [dpdk-dev] [PATCH 00/11] net/sfc: support per-queue stats on EF100 Andrew Rybchenko
                   ` (7 preceding siblings ...)
  2021-09-28 11:29 ` [dpdk-dev] [PATCH 08/11] net/sfc: add toggle to disable total stat Andrew Rybchenko
@ 2021-09-28 11:29 ` Andrew Rybchenko
  2021-09-28 11:29 ` [dpdk-dev] [PATCH 10/11] net/sfc: collect per queue stats in EF100 Rx datapath Andrew Rybchenko
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Andrew Rybchenko @ 2021-09-28 11:29 UTC (permalink / raw)
  To: dev; +Cc: Ivan Ilchenko

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

Add support for grouping SW stats together. When stats are
grouped the corresponding stats values for each queue
are obtained during calling one read callback. This is useful
to group per-queue stats 'packets' and 'bytes' to keep stats
consistent, i.e. a number of bytes corresponds to a number of
packets. These stats will be added in the following patches.

Signed-off-by: Ivan Ilchenko <ivan.ilchenko@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 drivers/net/sfc/sfc.h          |   8 ++
 drivers/net/sfc/sfc_sw_stats.c | 153 ++++++++++++++++++++++++++++-----
 2 files changed, 138 insertions(+), 23 deletions(-)

diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 5a40a73c7f..30679014e3 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -30,6 +30,7 @@
 #include "sfc_sriov.h"
 #include "sfc_mae.h"
 #include "sfc_dp.h"
+#include "sfc_sw_stats.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -219,6 +220,8 @@ struct sfc_counter_rxq {
 
 struct sfc_sw_stat_data {
 	const struct sfc_sw_stat_descr *descr;
+	/* Cache fragment */
+	uint64_t			*cache;
 };
 
 struct sfc_sw_stats {
@@ -227,6 +230,11 @@ struct sfc_sw_stats {
 	/* Supported SW statistics */
 	struct sfc_sw_stat_data		*supp;
 	unsigned int			supp_count;
+
+	/* Cache for all supported SW statistics */
+	uint64_t			*cache;
+	unsigned int			cache_count;
+
 	uint64_t			*reset_vals;
 
 	rte_spinlock_t			queues_bitmap_lock;
diff --git a/drivers/net/sfc/sfc_sw_stats.c b/drivers/net/sfc/sfc_sw_stats.c
index 63fc334d2b..81bd531a17 100644
--- a/drivers/net/sfc/sfc_sw_stats.c
+++ b/drivers/net/sfc/sfc_sw_stats.c
@@ -10,12 +10,17 @@
 #include "sfc_tx.h"
 #include "sfc_sw_stats.h"
 
+#define SFC_SW_STAT_INVALID		UINT64_MAX
+
+#define SFC_SW_STATS_GROUP_SIZE_MAX	1U
+
 enum sfc_sw_stats_type {
 	SFC_SW_STATS_RX,
 	SFC_SW_STATS_TX,
 };
 
-typedef uint64_t sfc_get_sw_stat_val_t(struct sfc_adapter *sa, uint16_t qid);
+typedef void sfc_get_sw_stat_val_t(struct sfc_adapter *sa, uint16_t qid,
+				   uint64_t *values, unsigned int values_count);
 
 struct sfc_sw_stat_descr {
 	const char *name;
@@ -25,31 +30,41 @@ struct sfc_sw_stat_descr {
 };
 
 static sfc_get_sw_stat_val_t sfc_get_sw_stat_val_rx_dbells;
-static uint64_t
-sfc_get_sw_stat_val_rx_dbells(struct sfc_adapter *sa, uint16_t qid)
+static void
+sfc_get_sw_stat_val_rx_dbells(struct sfc_adapter *sa, uint16_t qid,
+			       uint64_t *values, unsigned int values_count)
 {
 	struct sfc_adapter_shared *sas = sfc_sa2shared(sa);
 	struct sfc_rxq_info *rxq_info;
 
+	RTE_SET_USED(values_count);
+	SFC_ASSERT(values_count == 1);
 	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;
+	values[0] = rxq_info->state & SFC_RXQ_INITIALIZED ?
+		    rxq_info->dp->dpq.rx_dbells : 0;
 }
 
 static sfc_get_sw_stat_val_t sfc_get_sw_stat_val_tx_dbells;
-static uint64_t
-sfc_get_sw_stat_val_tx_dbells(struct sfc_adapter *sa, uint16_t qid)
+static void
+sfc_get_sw_stat_val_tx_dbells(struct sfc_adapter *sa, uint16_t qid,
+			       uint64_t *values, unsigned int values_count)
 {
 	struct sfc_adapter_shared *sas = sfc_sa2shared(sa);
 	struct sfc_txq_info *txq_info;
 
+	RTE_SET_USED(values_count);
+	SFC_ASSERT(values_count == 1);
 	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;
+	values[0] = txq_info->state & SFC_TXQ_INITIALIZED ?
+		    txq_info->dp->dpq.tx_dbells : 0;
 }
 
+/*
+ * SW stats can be grouped together. When stats are grouped the corresponding
+ * stats values for each queue are obtained during calling one get value
+ * callback. Stats of the same group are contiguous in the structure below.
+ * The start of the group is denoted by stat implementing get value callback.
+ */
 const struct sfc_sw_stat_descr sfc_sw_stats_descr[] = {
 	{
 		.name = "dbells",
@@ -228,9 +243,53 @@ sfc_sw_xstat_get_names_by_id(struct sfc_adapter *sa,
 	return 0;
 }
 
+static uint64_t
+sfc_sw_stat_get_val(struct sfc_adapter *sa,
+		    unsigned int sw_stat_idx, uint16_t qid)
+{
+	struct sfc_sw_stats *sw_stats = &sa->sw_stats;
+	uint64_t *res = &sw_stats->supp[sw_stat_idx].cache[qid];
+	uint64_t values[SFC_SW_STATS_GROUP_SIZE_MAX];
+	unsigned int group_start_idx;
+	unsigned int group_size;
+	unsigned int i;
+
+	if (*res != SFC_SW_STAT_INVALID)
+		return *res;
+
+	/*
+	 * Search for the group start, i.e. the stat that implements
+	 * get value callback.
+	 */
+	group_start_idx = sw_stat_idx;
+	while (sw_stats->supp[group_start_idx].descr->get_val == NULL)
+		group_start_idx--;
+
+	/*
+	 * Calculate number of elements in the group with loop till the next
+	 * group start or the list end.
+	 */
+	group_size = 1;
+	for (i = sw_stat_idx + 1; i < sw_stats->supp_count; i++) {
+		if (sw_stats->supp[i].descr->get_val != NULL)
+			break;
+		group_size++;
+	}
+	group_size += sw_stat_idx - group_start_idx;
+
+	SFC_ASSERT(group_size <= SFC_SW_STATS_GROUP_SIZE_MAX);
+	sw_stats->supp[group_start_idx].descr->get_val(sa, qid, values,
+						       group_size);
+	for (i = group_start_idx; i < (group_start_idx + group_size); i++)
+		sw_stats->supp[i].cache[qid] = values[i - group_start_idx];
+
+	return *res;
+}
+
 static void
 sfc_sw_xstat_get_values(struct sfc_adapter *sa,
 			const struct sfc_sw_stat_descr *sw_stat,
+			unsigned int sw_stat_idx,
 			struct rte_eth_xstat *xstats,
 			unsigned int xstats_size,
 			unsigned int *nb_written,
@@ -260,7 +319,7 @@ sfc_sw_xstat_get_values(struct sfc_adapter *sa,
 	}
 
 	for (qid = 0; qid < nb_queues; ++qid) {
-		value = sw_stat->get_val(sa, qid);
+		value = sfc_sw_stat_get_val(sa, sw_stat_idx, qid);
 
 		if (*nb_written < xstats_size) {
 			xstats[*nb_written].id = *nb_written;
@@ -276,6 +335,7 @@ sfc_sw_xstat_get_values(struct sfc_adapter *sa,
 static void
 sfc_sw_xstat_get_values_by_id(struct sfc_adapter *sa,
 			      const struct sfc_sw_stat_descr *sw_stat,
+			      unsigned int sw_stat_idx,
 			      const uint64_t *ids,
 			      uint64_t *values,
 			      unsigned int ids_size,
@@ -316,7 +376,7 @@ sfc_sw_xstat_get_values_by_id(struct sfc_adapter *sa,
 			}
 			id_base_q = id_base + sw_stat->provide_total;
 			qid = ids[i] - id_base_q;
-			values[i] = sw_stat->get_val(sa, qid);
+			values[i] = sfc_sw_stat_get_val(sa, sw_stat_idx, qid);
 			total_value += values[i];
 
 			rte_bitmap_set(bmp, qid);
@@ -328,7 +388,9 @@ sfc_sw_xstat_get_values_by_id(struct sfc_adapter *sa,
 		for (qid = 0; qid < nb_queues; ++qid) {
 			if (rte_bitmap_get(bmp, qid) != 0)
 				continue;
-			values[total_value_idx] += sw_stat->get_val(sa, qid);
+			values[total_value_idx] += sfc_sw_stat_get_val(sa,
+								    sw_stat_idx,
+								    qid);
 		}
 		values[total_value_idx] += total_value;
 	}
@@ -344,6 +406,16 @@ sfc_sw_xstats_get_nb_supported(struct sfc_adapter *sa)
 	return sa->sw_stats.xstats_count;
 }
 
+static void
+sfc_sw_stats_clear_cache(struct sfc_adapter *sa)
+{
+	unsigned int cache_count = sa->sw_stats.cache_count;
+	uint64_t *cache = sa->sw_stats.cache;
+
+	RTE_BUILD_BUG_ON(UINT64_C(0xffffffffffffffff) != SFC_SW_STAT_INVALID);
+	memset(cache, 0xff, cache_count * sizeof(*cache));
+}
+
 void
 sfc_sw_xstats_get_vals(struct sfc_adapter *sa,
 		       struct rte_eth_xstat *xstats,
@@ -358,11 +430,13 @@ sfc_sw_xstats_get_vals(struct sfc_adapter *sa,
 
 	sfc_adapter_lock(sa);
 
+	sfc_sw_stats_clear_cache(sa);
+
 	sw_xstats_offset = *nb_supported;
 
-	for (i = 0; i < sw_stats->xstats_count; i++) {
-		sfc_sw_xstat_get_values(sa, sw_stats->supp[i].descr, xstats,
-					xstats_count, nb_written, nb_supported);
+	for (i = 0; i < sw_stats->supp_count; i++) {
+		sfc_sw_xstat_get_values(sa, sw_stats->supp[i].descr, i,
+				xstats, xstats_count, nb_written, nb_supported);
 	}
 
 	for (i = sw_xstats_offset; i < *nb_written; i++)
@@ -413,11 +487,13 @@ sfc_sw_xstats_get_vals_by_id(struct sfc_adapter *sa,
 
 	sfc_adapter_lock(sa);
 
+	sfc_sw_stats_clear_cache(sa);
+
 	sw_xstats_offset = *nb_supported;
 
 	for (i = 0; i < sw_stats->supp_count; i++) {
-		sfc_sw_xstat_get_values_by_id(sa, sw_stats->supp[i].descr, ids,
-					      values, n, nb_supported);
+		sfc_sw_xstat_get_values_by_id(sa, sw_stats->supp[i].descr, i,
+					      ids, values, n, nb_supported);
 	}
 
 	for (i = 0; i < n; i++) {
@@ -460,6 +536,7 @@ sfc_sw_xstats_get_names_by_id(struct sfc_adapter *sa,
 static void
 sfc_sw_xstat_reset(struct sfc_adapter *sa,
 		   const struct sfc_sw_stat_descr *sw_stat,
+		   unsigned int sw_stat_idx,
 		   uint64_t *reset_vals)
 {
 	unsigned int nb_queues;
@@ -483,7 +560,7 @@ sfc_sw_xstat_reset(struct sfc_adapter *sa,
 	}
 
 	for (qid = 0; qid < nb_queues; ++qid) {
-		reset_vals[qid] = sw_stat->get_val(sa, qid);
+		reset_vals[qid] = sfc_sw_stat_get_val(sa, sw_stat_idx, qid);
 		if (sw_stat->provide_total)
 			*total_xstat_reset += reset_vals[qid];
 	}
@@ -498,8 +575,10 @@ sfc_sw_xstats_reset(struct sfc_adapter *sa)
 
 	SFC_ASSERT(sfc_adapter_is_locked(sa));
 
+	sfc_sw_stats_clear_cache(sa);
+
 	for (i = 0; i < sw_stats->supp_count; i++) {
-		sfc_sw_xstat_reset(sa, sw_stats->supp[i].descr, reset_vals);
+		sfc_sw_xstat_reset(sa, sw_stats->supp[i].descr, i, reset_vals);
 		reset_vals += sfc_sw_xstat_get_nb_supported(sa,
 						       sw_stats->supp[i].descr);
 	}
@@ -510,6 +589,9 @@ sfc_sw_xstats_configure(struct sfc_adapter *sa)
 {
 	uint64_t **reset_vals = &sa->sw_stats.reset_vals;
 	struct sfc_sw_stats *sw_stats = &sa->sw_stats;
+	unsigned int cache_count = 0;
+	uint64_t **cache =  &sa->sw_stats.cache;
+	uint64_t *stat_cache;
 	size_t nb_supported = 0;
 	unsigned int i;
 	int rc;
@@ -524,9 +606,12 @@ sfc_sw_xstats_configure(struct sfc_adapter *sa)
 	for (i = 0; i < sw_stats->supp_count; i++)
 		sw_stats->supp[i].descr = &sfc_sw_stats_descr[i];
 
-	for (i = 0; i < sw_stats->supp_count; i++)
+	for (i = 0; i < sw_stats->supp_count; i++) {
 		nb_supported += sfc_sw_xstat_get_nb_supported(sa,
 						       sw_stats->supp[i].descr);
+		cache_count += sfc_sw_stat_get_queue_count(sa,
+						       sw_stats->supp[i].descr);
+	}
 	sa->sw_stats.xstats_count = nb_supported;
 
 	*reset_vals = rte_realloc(*reset_vals,
@@ -538,8 +623,25 @@ sfc_sw_xstats_configure(struct sfc_adapter *sa)
 
 	memset(*reset_vals, 0, nb_supported * sizeof(**reset_vals));
 
+	*cache = rte_realloc(*cache, cache_count * sizeof(*cache), 0);
+	if (*cache == NULL) {
+		rc = ENOMEM;
+		goto fail_cache;
+	}
+	sa->sw_stats.cache_count = cache_count;
+	stat_cache = *cache;
+
+	for (i = 0; i < sw_stats->supp_count; i++) {
+		sw_stats->supp[i].cache = stat_cache;
+		stat_cache += sfc_sw_stat_get_queue_count(sa,
+						       sw_stats->supp[i].descr);
+	}
+
 	return 0;
 
+fail_cache:
+	rte_free(*reset_vals);
+	*reset_vals = NULL;
 fail_reset_vals:
 	sa->sw_stats.xstats_count = 0;
 	rte_free(sw_stats->supp);
@@ -594,6 +696,8 @@ sfc_sw_xstats_init(struct sfc_adapter *sa)
 	sa->sw_stats.xstats_count = 0;
 	sa->sw_stats.supp = NULL;
 	sa->sw_stats.supp_count = 0;
+	sa->sw_stats.cache = NULL;
+	sa->sw_stats.cache_count = 0;
 	sa->sw_stats.reset_vals = NULL;
 
 	return sfc_sw_xstats_alloc_queues_bitmap(sa);
@@ -603,8 +707,11 @@ void
 sfc_sw_xstats_close(struct sfc_adapter *sa)
 {
 	sfc_sw_xstats_free_queues_bitmap(sa);
-	rte_free(sa->sw_stats.reset_vals);
 	sa->sw_stats.reset_vals = NULL;
+	rte_free(sa->sw_stats.cache);
+	sa->sw_stats.cache = NULL;
+	sa->sw_stats.cache_count = 0;
+	rte_free(sa->sw_stats.reset_vals);
 	rte_free(sa->sw_stats.supp);
 	sa->sw_stats.supp = NULL;
 	sa->sw_stats.supp_count = 0;
-- 
2.30.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [dpdk-dev] [PATCH 10/11] net/sfc: collect per queue stats in EF100 Rx datapath
  2021-09-28 11:29 [dpdk-dev] [PATCH 00/11] net/sfc: support per-queue stats on EF100 Andrew Rybchenko
                   ` (8 preceding siblings ...)
  2021-09-28 11:29 ` [dpdk-dev] [PATCH 09/11] net/sfc: add support for SW stats groups Andrew Rybchenko
@ 2021-09-28 11:29 ` Andrew Rybchenko
  2021-09-28 11:29 ` [dpdk-dev] [PATCH 11/11] net/sfc: collect per queue stats in EF100 Tx datapath Andrew Rybchenko
  2021-10-11 16:38 ` [dpdk-dev] [PATCH 00/11] net/sfc: support per-queue stats on EF100 Ferruh Yigit
  11 siblings, 0 replies; 13+ messages in thread
From: Andrew Rybchenko @ 2021-09-28 11:29 UTC (permalink / raw)
  To: dev; +Cc: Ivan Ilchenko

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

If Rx datapath collects per queue statistics, use these stats
to provide ipackets and ibytes in basic ethdev stats.

Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Signed-off-by: Ivan Ilchenko <ivan.ilchenko@oktetlabs.ru>
---
 drivers/net/sfc/sfc.h          |   3 +
 drivers/net/sfc/sfc_dp.h       |   2 +
 drivers/net/sfc/sfc_dp_rx.h    |   1 +
 drivers/net/sfc/sfc_ef100_rx.c |  10 ++-
 drivers/net/sfc/sfc_ethdev.c   |  72 ++++++++++++++++-----
 drivers/net/sfc/sfc_sw_stats.c | 115 ++++++++++++++++++++++++++++++++-
 6 files changed, 182 insertions(+), 21 deletions(-)

diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 30679014e3..30bd109e8b 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -236,6 +236,9 @@ struct sfc_sw_stats {
 	unsigned int			cache_count;
 
 	uint64_t			*reset_vals;
+	/* Location of per-queue reset values for packets/bytes in reset_vals */
+	uint64_t			*reset_rx_pkts;
+	uint64_t			*reset_rx_bytes;
 
 	rte_spinlock_t			queues_bitmap_lock;
 	void				*queues_bitmap_mem;
diff --git a/drivers/net/sfc/sfc_dp.h b/drivers/net/sfc/sfc_dp.h
index 7fd8f34b0f..2edde61a68 100644
--- a/drivers/net/sfc/sfc_dp.h
+++ b/drivers/net/sfc/sfc_dp.h
@@ -16,6 +16,7 @@
 #include <rte_pci.h>
 
 #include "sfc_log.h"
+#include "sfc_stats.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -49,6 +50,7 @@ struct sfc_dp_queue {
 	 * 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.
 	 */
+	union sfc_pkts_bytes		stats;
 	uint32_t			rx_dbells;
 	uint32_t			tx_dbells;
 
diff --git a/drivers/net/sfc/sfc_dp_rx.h b/drivers/net/sfc/sfc_dp_rx.h
index b6c44085ce..d037acaa56 100644
--- a/drivers/net/sfc/sfc_dp_rx.h
+++ b/drivers/net/sfc/sfc_dp_rx.h
@@ -216,6 +216,7 @@ struct sfc_dp_rx {
 #define SFC_DP_RX_FEAT_FLOW_FLAG		0x2
 #define SFC_DP_RX_FEAT_FLOW_MARK		0x4
 #define SFC_DP_RX_FEAT_INTR			0x8
+#define SFC_DP_RX_FEAT_STATS			0x10
 	/**
 	 * Rx offload capabilities supported by the datapath on device
 	 * level only if HW/FW supports it.
diff --git a/drivers/net/sfc/sfc_ef100_rx.c b/drivers/net/sfc/sfc_ef100_rx.c
index 1bf04f565a..391c52487d 100644
--- a/drivers/net/sfc/sfc_ef100_rx.c
+++ b/drivers/net/sfc/sfc_ef100_rx.c
@@ -525,10 +525,13 @@ sfc_ef100_rx_process_ready_pkts(struct sfc_ef100_rxq *rxq,
 			lastseg = seg;
 		}
 
-		if (likely(deliver))
+		if (likely(deliver)) {
 			*rx_pkts++ = pkt;
-		else
+			sfc_pkts_bytes_add(&rxq->dp.dpq.stats, 1,
+					   rte_pktmbuf_pkt_len(pkt));
+		} else {
 			rte_pktmbuf_free(pkt);
+		}
 	}
 
 	return rx_pkts;
@@ -914,7 +917,8 @@ struct sfc_dp_rx sfc_ef100_rx = {
 		.hw_fw_caps	= SFC_DP_HW_FW_CAP_EF100,
 	},
 	.features		= SFC_DP_RX_FEAT_MULTI_PROCESS |
-				  SFC_DP_RX_FEAT_INTR,
+				  SFC_DP_RX_FEAT_INTR |
+				  SFC_DP_RX_FEAT_STATS,
 	.dev_offload_capa	= 0,
 	.queue_offload_capa	= DEV_RX_OFFLOAD_CHECKSUM |
 				  DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM |
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 2db0d000c3..20d808d15c 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -586,6 +586,33 @@ sfc_tx_queue_release(void *queue)
 	sfc_adapter_unlock(sa);
 }
 
+static void
+sfc_stats_get_dp_rx(struct sfc_adapter *sa, uint64_t *pkts, uint64_t *bytes)
+{
+	struct sfc_adapter_shared *sas = sfc_sa2shared(sa);
+	uint64_t pkts_sum = 0;
+	uint64_t bytes_sum = 0;
+	unsigned int i;
+
+	for (i = 0; i < sas->ethdev_rxq_count; ++i) {
+		struct sfc_rxq_info *rxq_info;
+
+		rxq_info = sfc_rxq_info_by_ethdev_qid(sas, i);
+		if (rxq_info->state & SFC_RXQ_INITIALIZED) {
+			union sfc_pkts_bytes qstats;
+
+			sfc_pkts_bytes_get(&rxq_info->dp->dpq.stats, &qstats);
+			pkts_sum += qstats.pkts -
+					sa->sw_stats.reset_rx_pkts[i];
+			bytes_sum += qstats.bytes -
+					sa->sw_stats.reset_rx_bytes[i];
+		}
+	}
+
+	*pkts = pkts_sum;
+	*bytes = bytes_sum;
+}
+
 /*
  * Some statistics are computed as A - B where A and B each increase
  * monotonically with some hardware counter(s) and the counters are read
@@ -612,6 +639,8 @@ sfc_update_diff_stat(uint64_t *stat, uint64_t newval)
 static int
 sfc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 {
+	const struct sfc_adapter_priv *sap = sfc_adapter_priv_by_eth_dev(dev);
+	bool have_dp_rx_stats = sap->dp_rx->features & SFC_DP_RX_FEAT_STATS;
 	struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
 	struct sfc_port *port = &sa->port;
 	uint64_t *mac_stats;
@@ -619,6 +648,9 @@ sfc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 
 	sfc_adapter_lock(sa);
 
+	if (have_dp_rx_stats)
+		sfc_stats_get_dp_rx(sa, &stats->ipackets, &stats->ibytes);
+
 	ret = sfc_port_update_mac_stats(sa, B_FALSE);
 	if (ret != 0)
 		goto unlock;
@@ -627,18 +659,23 @@ sfc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 
 	if (EFX_MAC_STAT_SUPPORTED(port->mac_stats_mask,
 				   EFX_MAC_VADAPTER_RX_UNICAST_PACKETS)) {
-		stats->ipackets =
-			mac_stats[EFX_MAC_VADAPTER_RX_UNICAST_PACKETS] +
-			mac_stats[EFX_MAC_VADAPTER_RX_MULTICAST_PACKETS] +
-			mac_stats[EFX_MAC_VADAPTER_RX_BROADCAST_PACKETS];
+		if (!have_dp_rx_stats) {
+			stats->ipackets =
+				mac_stats[EFX_MAC_VADAPTER_RX_UNICAST_PACKETS] +
+				mac_stats[EFX_MAC_VADAPTER_RX_MULTICAST_PACKETS] +
+				mac_stats[EFX_MAC_VADAPTER_RX_BROADCAST_PACKETS];
+			stats->ibytes =
+				mac_stats[EFX_MAC_VADAPTER_RX_UNICAST_BYTES] +
+				mac_stats[EFX_MAC_VADAPTER_RX_MULTICAST_BYTES] +
+				mac_stats[EFX_MAC_VADAPTER_RX_BROADCAST_BYTES];
+
+			/* CRC is included in these stats, but shouldn't be */
+			stats->ibytes -= stats->ipackets * RTE_ETHER_CRC_LEN;
+		}
 		stats->opackets =
 			mac_stats[EFX_MAC_VADAPTER_TX_UNICAST_PACKETS] +
 			mac_stats[EFX_MAC_VADAPTER_TX_MULTICAST_PACKETS] +
 			mac_stats[EFX_MAC_VADAPTER_TX_BROADCAST_PACKETS];
-		stats->ibytes =
-			mac_stats[EFX_MAC_VADAPTER_RX_UNICAST_BYTES] +
-			mac_stats[EFX_MAC_VADAPTER_RX_MULTICAST_BYTES] +
-			mac_stats[EFX_MAC_VADAPTER_RX_BROADCAST_BYTES];
 		stats->obytes =
 			mac_stats[EFX_MAC_VADAPTER_TX_UNICAST_BYTES] +
 			mac_stats[EFX_MAC_VADAPTER_TX_MULTICAST_BYTES] +
@@ -647,15 +684,12 @@ sfc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 		stats->oerrors = mac_stats[EFX_MAC_VADAPTER_TX_BAD_PACKETS];
 
 		/* CRC is included in these stats, but shouldn't be */
-		stats->ibytes -= stats->ipackets * RTE_ETHER_CRC_LEN;
 		stats->obytes -= stats->opackets * RTE_ETHER_CRC_LEN;
 	} else {
 		stats->opackets = mac_stats[EFX_MAC_TX_PKTS];
-		stats->ibytes = mac_stats[EFX_MAC_RX_OCTETS];
 		stats->obytes = mac_stats[EFX_MAC_TX_OCTETS];
 
 		/* CRC is included in these stats, but shouldn't be */
-		stats->ibytes -= mac_stats[EFX_MAC_RX_PKTS] * RTE_ETHER_CRC_LEN;
 		stats->obytes -= mac_stats[EFX_MAC_TX_PKTS] * RTE_ETHER_CRC_LEN;
 
 		/*
@@ -681,12 +715,16 @@ sfc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 			mac_stats[EFX_MAC_RX_JABBER_PKTS];
 		/* no oerrors counters supported on EF10 */
 
-		/* Exclude missed, errors and pauses from Rx packets */
-		sfc_update_diff_stat(&port->ipackets,
-			mac_stats[EFX_MAC_RX_PKTS] -
-			mac_stats[EFX_MAC_RX_PAUSE_PKTS] -
-			stats->imissed - stats->ierrors);
-		stats->ipackets = port->ipackets;
+		if (!have_dp_rx_stats) {
+			/* Exclude missed, errors and pauses from Rx packets */
+			sfc_update_diff_stat(&port->ipackets,
+				mac_stats[EFX_MAC_RX_PKTS] -
+				mac_stats[EFX_MAC_RX_PAUSE_PKTS] -
+				stats->imissed - stats->ierrors);
+			stats->ipackets = port->ipackets;
+			stats->ibytes = mac_stats[EFX_MAC_RX_OCTETS] -
+				mac_stats[EFX_MAC_RX_PKTS] * RTE_ETHER_CRC_LEN;
+		}
 	}
 
 unlock:
diff --git a/drivers/net/sfc/sfc_sw_stats.c b/drivers/net/sfc/sfc_sw_stats.c
index 81bd531a17..8ffa923215 100644
--- a/drivers/net/sfc/sfc_sw_stats.c
+++ b/drivers/net/sfc/sfc_sw_stats.c
@@ -12,13 +12,21 @@
 
 #define SFC_SW_STAT_INVALID		UINT64_MAX
 
-#define SFC_SW_STATS_GROUP_SIZE_MAX	1U
+#define SFC_SW_STATS_GROUP_SIZE_MAX	2U
+#define SFC_SW_STAT_GOOD_PACKETS	"packets"
+#define SFC_SW_STAT_GOOD_BYTES		"bytes"
 
 enum sfc_sw_stats_type {
 	SFC_SW_STATS_RX,
 	SFC_SW_STATS_TX,
 };
 
+enum sfc_sw_stats_group_basic {
+	SFC_SW_STATS_GROUP_BASIC_PKTS = 0,
+	SFC_SW_STATS_GROUP_BASIC_BYTES,
+	SFX_SW_STATS_GROUP_BASIC_MAX
+};
+
 typedef void sfc_get_sw_stat_val_t(struct sfc_adapter *sa, uint16_t qid,
 				   uint64_t *values, unsigned int values_count);
 
@@ -29,6 +37,29 @@ struct sfc_sw_stat_descr {
 	bool provide_total;
 };
 
+static sfc_get_sw_stat_val_t sfc_sw_stat_get_rx_good_pkts_bytes;
+static void
+sfc_sw_stat_get_rx_good_pkts_bytes(struct sfc_adapter *sa, uint16_t qid,
+				   uint64_t *values,
+				   unsigned int values_count)
+{
+	struct sfc_adapter_shared *sas = sfc_sa2shared(sa);
+	struct sfc_rxq_info *rxq_info;
+	union sfc_pkts_bytes qstats;
+
+	RTE_SET_USED(values_count);
+	SFC_ASSERT(values_count == SFX_SW_STATS_GROUP_BASIC_MAX);
+	rxq_info = sfc_rxq_info_by_ethdev_qid(sas, qid);
+	if (rxq_info->state & SFC_RXQ_INITIALIZED) {
+		sfc_pkts_bytes_get(&rxq_info->dp->dpq.stats, &qstats);
+		values[SFC_SW_STATS_GROUP_BASIC_PKTS] = qstats.pkts;
+		values[SFC_SW_STATS_GROUP_BASIC_BYTES] = qstats.bytes;
+	} else {
+		values[SFC_SW_STATS_GROUP_BASIC_PKTS] = 0;
+		values[SFC_SW_STATS_GROUP_BASIC_BYTES] = 0;
+	}
+}
+
 static sfc_get_sw_stat_val_t sfc_get_sw_stat_val_rx_dbells;
 static void
 sfc_get_sw_stat_val_rx_dbells(struct sfc_adapter *sa, uint16_t qid,
@@ -66,6 +97,20 @@ sfc_get_sw_stat_val_tx_dbells(struct sfc_adapter *sa, uint16_t qid,
  * The start of the group is denoted by stat implementing get value callback.
  */
 const struct sfc_sw_stat_descr sfc_sw_stats_descr[] = {
+	/* Group of Rx packets/bytes stats */
+	{
+		.name = SFC_SW_STAT_GOOD_PACKETS,
+		.type = SFC_SW_STATS_RX,
+		.get_val  = sfc_sw_stat_get_rx_good_pkts_bytes,
+		.provide_total = false,
+	},
+	{
+		.name = SFC_SW_STAT_GOOD_BYTES,
+		.type = SFC_SW_STATS_RX,
+		.get_val  = NULL,
+		.provide_total = false,
+	},
+	/* End of basic stats */
 	{
 		.name = "dbells",
 		.type = SFC_SW_STATS_RX,
@@ -584,6 +629,66 @@ sfc_sw_xstats_reset(struct sfc_adapter *sa)
 	}
 }
 
+static bool
+sfc_sw_stats_is_packets_or_bytes(const char *xstat_name)
+{
+	return strcmp(xstat_name, SFC_SW_STAT_GOOD_PACKETS) == 0 ||
+	       strcmp(xstat_name, SFC_SW_STAT_GOOD_BYTES) == 0;
+}
+
+static void
+sfc_sw_stats_fill_available_descr(struct sfc_adapter *sa)
+{
+	const struct sfc_adapter_priv *sap = &sa->priv;
+	bool have_dp_rx_stats = sap->dp_rx->features & SFC_DP_RX_FEAT_STATS;
+	struct sfc_sw_stats *sw_stats = &sa->sw_stats;
+	const struct sfc_sw_stat_descr *sw_stat_descr;
+	unsigned int i;
+
+	sw_stats->supp_count = 0;
+	for (i = 0; i < RTE_DIM(sfc_sw_stats_descr); i++) {
+		sw_stat_descr = &sfc_sw_stats_descr[i];
+		if (!have_dp_rx_stats &&
+		    sw_stat_descr->type == SFC_SW_STATS_RX &&
+		    sfc_sw_stats_is_packets_or_bytes(sw_stat_descr->name))
+			continue;
+		sw_stats->supp[sw_stats->supp_count].descr = sw_stat_descr;
+		sw_stats->supp_count++;
+	}
+}
+
+static int
+sfc_sw_stats_set_reset_basic_stats(struct sfc_adapter *sa)
+{
+	uint64_t *reset_vals = sa->sw_stats.reset_vals;
+	struct sfc_sw_stats *sw_stats = &sa->sw_stats;
+	const struct sfc_sw_stat_descr *sw_stat;
+	unsigned int i;
+
+	for (i = 0; i < sw_stats->supp_count; i++) {
+		sw_stat = sw_stats->supp[i].descr;
+
+		switch (sw_stat->type) {
+		case SFC_SW_STATS_RX:
+			if (strcmp(sw_stat->name,
+				   SFC_SW_STAT_GOOD_PACKETS) == 0)
+				sa->sw_stats.reset_rx_pkts = reset_vals;
+			else if (strcmp(sw_stat->name,
+					SFC_SW_STAT_GOOD_BYTES) == 0)
+				sa->sw_stats.reset_rx_bytes = reset_vals;
+			break;
+		case SFC_SW_STATS_TX:
+		default:
+			SFC_GENERIC_LOG(ERR, "Unknown SW stat type");
+			return -EINVAL;
+		}
+
+		reset_vals += sfc_sw_xstat_get_nb_supported(sa, sw_stat);
+	}
+
+	return 0;
+}
+
 int
 sfc_sw_xstats_configure(struct sfc_adapter *sa)
 {
@@ -605,6 +710,7 @@ sfc_sw_xstats_configure(struct sfc_adapter *sa)
 	}
 	for (i = 0; i < sw_stats->supp_count; i++)
 		sw_stats->supp[i].descr = &sfc_sw_stats_descr[i];
+	sfc_sw_stats_fill_available_descr(sa);
 
 	for (i = 0; i < sw_stats->supp_count; i++) {
 		nb_supported += sfc_sw_xstat_get_nb_supported(sa,
@@ -630,6 +736,9 @@ sfc_sw_xstats_configure(struct sfc_adapter *sa)
 	}
 	sa->sw_stats.cache_count = cache_count;
 	stat_cache = *cache;
+	rc = sfc_sw_stats_set_reset_basic_stats(sa);
+	if (rc != 0)
+		goto fail_reset_basic_stats;
 
 	for (i = 0; i < sw_stats->supp_count; i++) {
 		sw_stats->supp[i].cache = stat_cache;
@@ -639,6 +748,10 @@ sfc_sw_xstats_configure(struct sfc_adapter *sa)
 
 	return 0;
 
+fail_reset_basic_stats:
+	rte_free(*cache);
+	*cache = NULL;
+	sa->sw_stats.cache_count = 0;
 fail_cache:
 	rte_free(*reset_vals);
 	*reset_vals = NULL;
-- 
2.30.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [dpdk-dev] [PATCH 11/11] net/sfc: collect per queue stats in EF100 Tx datapath
  2021-09-28 11:29 [dpdk-dev] [PATCH 00/11] net/sfc: support per-queue stats on EF100 Andrew Rybchenko
                   ` (9 preceding siblings ...)
  2021-09-28 11:29 ` [dpdk-dev] [PATCH 10/11] net/sfc: collect per queue stats in EF100 Rx datapath Andrew Rybchenko
@ 2021-09-28 11:29 ` Andrew Rybchenko
  2021-10-11 16:38 ` [dpdk-dev] [PATCH 00/11] net/sfc: support per-queue stats on EF100 Ferruh Yigit
  11 siblings, 0 replies; 13+ messages in thread
From: Andrew Rybchenko @ 2021-09-28 11:29 UTC (permalink / raw)
  To: dev; +Cc: Ivan Ilchenko

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

If Tx datapath collects per queue statistics, use these stats
to provide opackets and obytes in basic ethdev stats.

Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Signed-off-by: Ivan Ilchenko <ivan.ilchenko@oktetlabs.ru>
---
 drivers/net/sfc/sfc.h          |  2 ++
 drivers/net/sfc/sfc_dp_tx.h    |  1 +
 drivers/net/sfc/sfc_ef100_tx.c |  6 +++-
 drivers/net/sfc/sfc_ethdev.c   | 64 +++++++++++++++++++++++++---------
 drivers/net/sfc/sfc_sw_stats.c | 48 +++++++++++++++++++++++++
 5 files changed, 104 insertions(+), 17 deletions(-)

diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 30bd109e8b..ace66d435c 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -239,6 +239,8 @@ struct sfc_sw_stats {
 	/* Location of per-queue reset values for packets/bytes in reset_vals */
 	uint64_t			*reset_rx_pkts;
 	uint64_t			*reset_rx_bytes;
+	uint64_t			*reset_tx_pkts;
+	uint64_t			*reset_tx_bytes;
 
 	rte_spinlock_t			queues_bitmap_lock;
 	void				*queues_bitmap_mem;
diff --git a/drivers/net/sfc/sfc_dp_tx.h b/drivers/net/sfc/sfc_dp_tx.h
index 777807985b..184711b887 100644
--- a/drivers/net/sfc/sfc_dp_tx.h
+++ b/drivers/net/sfc/sfc_dp_tx.h
@@ -168,6 +168,7 @@ struct sfc_dp_tx {
 
 	unsigned int			features;
 #define SFC_DP_TX_FEAT_MULTI_PROCESS	0x1
+#define SFC_DP_TX_FEAT_STATS		0x2
 	/**
 	 * Tx offload capabilities supported by the datapath on device
 	 * level only if HW/FW supports it.
diff --git a/drivers/net/sfc/sfc_ef100_tx.c b/drivers/net/sfc/sfc_ef100_tx.c
index 522e9a0d34..fce82795cc 100644
--- a/drivers/net/sfc/sfc_ef100_tx.c
+++ b/drivers/net/sfc/sfc_ef100_tx.c
@@ -710,6 +710,9 @@ sfc_ef100_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 		}
 
 		dma_desc_space -= (added - pkt_start);
+
+		sfc_pkts_bytes_add(&txq->dp.dpq.stats, 1,
+				   rte_pktmbuf_pkt_len(*pktp));
 	}
 
 	if (likely(added != txq->added)) {
@@ -940,7 +943,8 @@ struct sfc_dp_tx sfc_ef100_tx = {
 		.type		= SFC_DP_TX,
 		.hw_fw_caps	= SFC_DP_HW_FW_CAP_EF100,
 	},
-	.features		= SFC_DP_TX_FEAT_MULTI_PROCESS,
+	.features		= SFC_DP_TX_FEAT_MULTI_PROCESS |
+				  SFC_DP_TX_FEAT_STATS,
 	.dev_offload_capa	= 0,
 	.queue_offload_capa	= DEV_TX_OFFLOAD_VLAN_INSERT |
 				  DEV_TX_OFFLOAD_IPV4_CKSUM |
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 20d808d15c..fac9b27974 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -613,6 +613,33 @@ sfc_stats_get_dp_rx(struct sfc_adapter *sa, uint64_t *pkts, uint64_t *bytes)
 	*bytes = bytes_sum;
 }
 
+static void
+sfc_stats_get_dp_tx(struct sfc_adapter *sa, uint64_t *pkts, uint64_t *bytes)
+{
+	struct sfc_adapter_shared *sas = sfc_sa2shared(sa);
+	uint64_t pkts_sum = 0;
+	uint64_t bytes_sum = 0;
+	unsigned int i;
+
+	for (i = 0; i < sas->ethdev_txq_count; ++i) {
+		struct sfc_txq_info *txq_info;
+
+		txq_info = sfc_txq_info_by_ethdev_qid(sas, i);
+		if (txq_info->state & SFC_TXQ_INITIALIZED) {
+			union sfc_pkts_bytes qstats;
+
+			sfc_pkts_bytes_get(&txq_info->dp->dpq.stats, &qstats);
+			pkts_sum += qstats.pkts -
+					sa->sw_stats.reset_tx_pkts[i];
+			bytes_sum += qstats.bytes -
+					sa->sw_stats.reset_tx_bytes[i];
+		}
+	}
+
+	*pkts = pkts_sum;
+	*bytes = bytes_sum;
+}
+
 /*
  * Some statistics are computed as A - B where A and B each increase
  * monotonically with some hardware counter(s) and the counters are read
@@ -641,6 +668,7 @@ sfc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 {
 	const struct sfc_adapter_priv *sap = sfc_adapter_priv_by_eth_dev(dev);
 	bool have_dp_rx_stats = sap->dp_rx->features & SFC_DP_RX_FEAT_STATS;
+	bool have_dp_tx_stats = sap->dp_tx->features & SFC_DP_TX_FEAT_STATS;
 	struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
 	struct sfc_port *port = &sa->port;
 	uint64_t *mac_stats;
@@ -650,6 +678,8 @@ sfc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 
 	if (have_dp_rx_stats)
 		sfc_stats_get_dp_rx(sa, &stats->ipackets, &stats->ibytes);
+	if (have_dp_tx_stats)
+		sfc_stats_get_dp_tx(sa, &stats->opackets, &stats->obytes);
 
 	ret = sfc_port_update_mac_stats(sa, B_FALSE);
 	if (ret != 0)
@@ -672,25 +702,27 @@ sfc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 			/* CRC is included in these stats, but shouldn't be */
 			stats->ibytes -= stats->ipackets * RTE_ETHER_CRC_LEN;
 		}
-		stats->opackets =
-			mac_stats[EFX_MAC_VADAPTER_TX_UNICAST_PACKETS] +
-			mac_stats[EFX_MAC_VADAPTER_TX_MULTICAST_PACKETS] +
-			mac_stats[EFX_MAC_VADAPTER_TX_BROADCAST_PACKETS];
-		stats->obytes =
-			mac_stats[EFX_MAC_VADAPTER_TX_UNICAST_BYTES] +
-			mac_stats[EFX_MAC_VADAPTER_TX_MULTICAST_BYTES] +
-			mac_stats[EFX_MAC_VADAPTER_TX_BROADCAST_BYTES];
+		if (!have_dp_tx_stats) {
+			stats->opackets =
+				mac_stats[EFX_MAC_VADAPTER_TX_UNICAST_PACKETS] +
+				mac_stats[EFX_MAC_VADAPTER_TX_MULTICAST_PACKETS] +
+				mac_stats[EFX_MAC_VADAPTER_TX_BROADCAST_PACKETS];
+			stats->obytes =
+				mac_stats[EFX_MAC_VADAPTER_TX_UNICAST_BYTES] +
+				mac_stats[EFX_MAC_VADAPTER_TX_MULTICAST_BYTES] +
+				mac_stats[EFX_MAC_VADAPTER_TX_BROADCAST_BYTES];
+
+			/* CRC is included in these stats, but shouldn't be */
+			stats->obytes -= stats->opackets * RTE_ETHER_CRC_LEN;
+		}
 		stats->imissed = mac_stats[EFX_MAC_VADAPTER_RX_BAD_PACKETS];
 		stats->oerrors = mac_stats[EFX_MAC_VADAPTER_TX_BAD_PACKETS];
-
-		/* CRC is included in these stats, but shouldn't be */
-		stats->obytes -= stats->opackets * RTE_ETHER_CRC_LEN;
 	} else {
-		stats->opackets = mac_stats[EFX_MAC_TX_PKTS];
-		stats->obytes = mac_stats[EFX_MAC_TX_OCTETS];
-
-		/* CRC is included in these stats, but shouldn't be */
-		stats->obytes -= mac_stats[EFX_MAC_TX_PKTS] * RTE_ETHER_CRC_LEN;
+		if (!have_dp_tx_stats) {
+			stats->opackets = mac_stats[EFX_MAC_TX_PKTS];
+			stats->obytes = mac_stats[EFX_MAC_TX_OCTETS] -
+				mac_stats[EFX_MAC_TX_PKTS] * RTE_ETHER_CRC_LEN;
+		}
 
 		/*
 		 * Take into account stats which are whenever supported
diff --git a/drivers/net/sfc/sfc_sw_stats.c b/drivers/net/sfc/sfc_sw_stats.c
index 8ffa923215..6b3a01b3c6 100644
--- a/drivers/net/sfc/sfc_sw_stats.c
+++ b/drivers/net/sfc/sfc_sw_stats.c
@@ -60,6 +60,29 @@ sfc_sw_stat_get_rx_good_pkts_bytes(struct sfc_adapter *sa, uint16_t qid,
 	}
 }
 
+static sfc_get_sw_stat_val_t sfc_sw_stat_get_tx_good_pkts_bytes;
+static void
+sfc_sw_stat_get_tx_good_pkts_bytes(struct sfc_adapter *sa, uint16_t qid,
+				   uint64_t *values,
+				   unsigned int values_count)
+{
+	struct sfc_adapter_shared *sas = sfc_sa2shared(sa);
+	struct sfc_txq_info *txq_info;
+	union sfc_pkts_bytes qstats;
+
+	RTE_SET_USED(values_count);
+	SFC_ASSERT(values_count == SFX_SW_STATS_GROUP_BASIC_MAX);
+	txq_info = sfc_txq_info_by_ethdev_qid(sas, qid);
+	if (txq_info->state & SFC_TXQ_INITIALIZED) {
+		sfc_pkts_bytes_get(&txq_info->dp->dpq.stats, &qstats);
+		values[SFC_SW_STATS_GROUP_BASIC_PKTS] = qstats.pkts;
+		values[SFC_SW_STATS_GROUP_BASIC_BYTES] = qstats.bytes;
+	} else {
+		values[SFC_SW_STATS_GROUP_BASIC_PKTS] = 0;
+		values[SFC_SW_STATS_GROUP_BASIC_BYTES] = 0;
+	}
+}
+
 static sfc_get_sw_stat_val_t sfc_get_sw_stat_val_rx_dbells;
 static void
 sfc_get_sw_stat_val_rx_dbells(struct sfc_adapter *sa, uint16_t qid,
@@ -110,6 +133,19 @@ const struct sfc_sw_stat_descr sfc_sw_stats_descr[] = {
 		.get_val  = NULL,
 		.provide_total = false,
 	},
+	/* Group of Tx packets/bytes stats */
+	{
+		.name = SFC_SW_STAT_GOOD_PACKETS,
+		.type = SFC_SW_STATS_TX,
+		.get_val  = sfc_sw_stat_get_tx_good_pkts_bytes,
+		.provide_total = false,
+	},
+	{
+		.name = SFC_SW_STAT_GOOD_BYTES,
+		.type = SFC_SW_STATS_TX,
+		.get_val  = NULL,
+		.provide_total = false,
+	},
 	/* End of basic stats */
 	{
 		.name = "dbells",
@@ -641,6 +677,7 @@ sfc_sw_stats_fill_available_descr(struct sfc_adapter *sa)
 {
 	const struct sfc_adapter_priv *sap = &sa->priv;
 	bool have_dp_rx_stats = sap->dp_rx->features & SFC_DP_RX_FEAT_STATS;
+	bool have_dp_tx_stats = sap->dp_tx->features & SFC_DP_TX_FEAT_STATS;
 	struct sfc_sw_stats *sw_stats = &sa->sw_stats;
 	const struct sfc_sw_stat_descr *sw_stat_descr;
 	unsigned int i;
@@ -652,6 +689,10 @@ sfc_sw_stats_fill_available_descr(struct sfc_adapter *sa)
 		    sw_stat_descr->type == SFC_SW_STATS_RX &&
 		    sfc_sw_stats_is_packets_or_bytes(sw_stat_descr->name))
 			continue;
+		if (!have_dp_tx_stats &&
+		    sw_stat_descr->type == SFC_SW_STATS_TX &&
+		    sfc_sw_stats_is_packets_or_bytes(sw_stat_descr->name))
+			continue;
 		sw_stats->supp[sw_stats->supp_count].descr = sw_stat_descr;
 		sw_stats->supp_count++;
 	}
@@ -678,6 +719,13 @@ sfc_sw_stats_set_reset_basic_stats(struct sfc_adapter *sa)
 				sa->sw_stats.reset_rx_bytes = reset_vals;
 			break;
 		case SFC_SW_STATS_TX:
+			if (strcmp(sw_stat->name,
+				   SFC_SW_STAT_GOOD_PACKETS) == 0)
+				sa->sw_stats.reset_tx_pkts = reset_vals;
+			else if (strcmp(sw_stat->name,
+					SFC_SW_STAT_GOOD_BYTES) == 0)
+				sa->sw_stats.reset_tx_bytes = reset_vals;
+			break;
 		default:
 			SFC_GENERIC_LOG(ERR, "Unknown SW stat type");
 			return -EINVAL;
-- 
2.30.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [dpdk-dev] [PATCH 00/11] net/sfc: support per-queue stats on EF100
  2021-09-28 11:29 [dpdk-dev] [PATCH 00/11] net/sfc: support per-queue stats on EF100 Andrew Rybchenko
                   ` (10 preceding siblings ...)
  2021-09-28 11:29 ` [dpdk-dev] [PATCH 11/11] net/sfc: collect per queue stats in EF100 Tx datapath Andrew Rybchenko
@ 2021-10-11 16:38 ` Ferruh Yigit
  11 siblings, 0 replies; 13+ messages in thread
From: Ferruh Yigit @ 2021-10-11 16:38 UTC (permalink / raw)
  To: Andrew Rybchenko, dev

On 9/28/2021 12:29 PM, Andrew Rybchenko wrote:
> Implement per-queue Rx and Tx statistics for EF100 in software.
> Packets and bytes stats are collected by the driver.
> 
> Ivan Ilchenko (11):
>    net/sfc: rename array of SW stats descriptions
>    net/sfc: rename accumulative SW stats to total
>    net/sfc: rename SW stats structures
>    net/sfc: fix cleanup order of SW stats
>    net/sfc: fix missing const of SW stats descriptions
>    net/sfc: optimize getting number of SW stats
>    net/sfc: prepare having no some SW stats on an adapter
>    net/sfc: add toggle to disable total stat
>    net/sfc: add support for SW stats groups
>    net/sfc: collect per queue stats in EF100 Rx datapath
>    net/sfc: collect per queue stats in EF100 Tx datapath
> 

Series applied to dpdk-next-net/main, thanks.

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2021-10-11 16:44 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-28 11:29 [dpdk-dev] [PATCH 00/11] net/sfc: support per-queue stats on EF100 Andrew Rybchenko
2021-09-28 11:29 ` [dpdk-dev] [PATCH 01/11] net/sfc: rename array of SW stats descriptions Andrew Rybchenko
2021-09-28 11:29 ` [dpdk-dev] [PATCH 02/11] net/sfc: rename accumulative SW stats to total Andrew Rybchenko
2021-09-28 11:29 ` [dpdk-dev] [PATCH 03/11] net/sfc: rename SW stats structures Andrew Rybchenko
2021-09-28 11:29 ` [dpdk-dev] [PATCH 04/11] net/sfc: fix cleanup order of SW stats Andrew Rybchenko
2021-09-28 11:29 ` [dpdk-dev] [PATCH 05/11] net/sfc: fix missing const of SW stats descriptions Andrew Rybchenko
2021-09-28 11:29 ` [dpdk-dev] [PATCH 06/11] net/sfc: optimize getting number of SW stats Andrew Rybchenko
2021-09-28 11:29 ` [dpdk-dev] [PATCH 07/11] net/sfc: prepare having no some SW stats on an adapter Andrew Rybchenko
2021-09-28 11:29 ` [dpdk-dev] [PATCH 08/11] net/sfc: add toggle to disable total stat Andrew Rybchenko
2021-09-28 11:29 ` [dpdk-dev] [PATCH 09/11] net/sfc: add support for SW stats groups Andrew Rybchenko
2021-09-28 11:29 ` [dpdk-dev] [PATCH 10/11] net/sfc: collect per queue stats in EF100 Rx datapath Andrew Rybchenko
2021-09-28 11:29 ` [dpdk-dev] [PATCH 11/11] net/sfc: collect per queue stats in EF100 Tx datapath Andrew Rybchenko
2021-10-11 16:38 ` [dpdk-dev] [PATCH 00/11] net/sfc: support per-queue stats on EF100 Ferruh Yigit

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).