DPDK-dev Archive on lore.kernel.org
 help / color / Atom feed
* [dpdk-dev] [PATCH 0/2] failsafe: add xstats
@ 2019-06-26 22:21 Stephen Hemminger
  2019-06-26 22:21 ` [dpdk-dev] [PATCH 1/2] ethdev: expose basic xstats for driver use Stephen Hemminger
                   ` (4 more replies)
  0 siblings, 5 replies; 27+ messages in thread
From: Stephen Hemminger @ 2019-06-26 22:21 UTC (permalink / raw)
  To: gaetan.rivet; +Cc: dev, Stephen Hemminger

A useful feature of netvsc PMD is the ability to see how many packets
were processed through the VF device. This patch set adds a similar
(but more limited) capability to failsafe driver.

Since failsafe doesn't have top level xstats, this set uses the generic
xstats that exist already as a base then adds the sub-device xstats
to that.

Stephen Hemminger (2):
  ethdev: expose basic xstats for driver use
  failsafe: implement xstats

 drivers/net/failsafe/failsafe_ops.c      | 144 +++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev.c           |  17 ++-
 lib/librte_ethdev/rte_ethdev_core.h      |  14 +++
 lib/librte_ethdev/rte_ethdev_version.map |   3 +
 4 files changed, 169 insertions(+), 9 deletions(-)

-- 
2.20.1


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

* [dpdk-dev] [PATCH 1/2] ethdev: expose basic xstats for driver use
  2019-06-26 22:21 [dpdk-dev] [PATCH 0/2] failsafe: add xstats Stephen Hemminger
@ 2019-06-26 22:21 ` Stephen Hemminger
  2019-06-26 22:21 ` [dpdk-dev] [PATCH 2/2] failsafe: implement xstats Stephen Hemminger
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 27+ messages in thread
From: Stephen Hemminger @ 2019-06-26 22:21 UTC (permalink / raw)
  To: gaetan.rivet; +Cc: dev, Stephen Hemminger

From: Stephen Hemminger <sthemmin@microsoft.com>

Avoid duplication by having generic basic xstats available
for use by drivers. A later patch uses this for failsafe
driver.

Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
---
 lib/librte_ethdev/rte_ethdev.c           | 17 ++++++++---------
 lib/librte_ethdev/rte_ethdev_core.h      | 14 ++++++++++++++
 lib/librte_ethdev/rte_ethdev_version.map |  3 +++
 3 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 8ac301608b9c..a83e9727c144 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -1996,8 +1996,8 @@ rte_eth_stats_reset(uint16_t port_id)
 	return 0;
 }
 
-static inline int
-get_xstats_basic_count(struct rte_eth_dev *dev)
+int
+rte_eth_basic_stats_count(struct rte_eth_dev *dev)
 {
 	uint16_t nb_rxqs, nb_txqs;
 	int count;
@@ -2034,7 +2034,7 @@ get_xstats_count(uint16_t port_id)
 		count = 0;
 
 
-	count += get_xstats_basic_count(dev);
+	count += rte_eth_basic_stats_count(dev);
 
 	return count;
 }
@@ -2084,7 +2084,7 @@ rte_eth_xstats_get_id_by_name(uint16_t port_id, const char *xstat_name,
 }
 
 /* retrieve basic stats names */
-static int
+int
 rte_eth_basic_stats_get_names(struct rte_eth_dev *dev,
 	struct rte_eth_xstat_name *xstats_names)
 {
@@ -2140,7 +2140,7 @@ rte_eth_xstats_get_names_by_id(uint16_t port_id,
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
-	basic_count = get_xstats_basic_count(dev);
+	basic_count = rte_eth_basic_stats_count(dev);
 	ret = get_xstats_count(port_id);
 	if (ret < 0)
 		return ret;
@@ -2268,8 +2268,7 @@ rte_eth_xstats_get_names(uint16_t port_id,
 	return cnt_used_entries;
 }
 
-
-static int
+int
 rte_eth_basic_stats_get(uint16_t port_id, struct rte_eth_xstat *xstats)
 {
 	struct rte_eth_dev *dev;
@@ -2341,7 +2340,7 @@ rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids,
 	expected_entries = (uint16_t)ret;
 	struct rte_eth_xstat xstats[expected_entries];
 	dev = &rte_eth_devices[port_id];
-	basic_count = get_xstats_basic_count(dev);
+	basic_count = rte_eth_basic_stats_count(dev);
 
 	/* Return max number of stats if no ids given */
 	if (!ids) {
@@ -2355,7 +2354,7 @@ rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids,
 		return -EINVAL;
 
 	if (ids && dev->dev_ops->xstats_get_by_id != NULL && size) {
-		unsigned int basic_count = get_xstats_basic_count(dev);
+		unsigned int basic_count = rte_eth_basic_stats_count(dev);
 		uint64_t ids_copy[size];
 
 		for (i = 0; i < size; i++) {
diff --git a/lib/librte_ethdev/rte_ethdev_core.h b/lib/librte_ethdev/rte_ethdev_core.h
index 2922d5b7cc95..91ce1880d1c6 100644
--- a/lib/librte_ethdev/rte_ethdev_core.h
+++ b/lib/librte_ethdev/rte_ethdev_core.h
@@ -517,6 +517,20 @@ struct eth_dev_ops {
 	/**< Test if a port supports specific mempool ops */
 };
 
+/**
+ * @internal
+ * Get basic stats for ethdev
+ */
+int __rte_experimental
+rte_eth_basic_stats_count(struct rte_eth_dev *dev);
+
+int  __rte_experimental
+rte_eth_basic_stats_get_names(struct rte_eth_dev *dev,
+			      struct rte_eth_xstat_name *xstats_names);
+
+int __rte_experimental
+rte_eth_basic_stats_get(uint16_t port_id, struct rte_eth_xstat *xstats);
+
 /**
  * @internal
  * Structure used to hold information about the callbacks to be called for a
diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map
index df9141825c3f..949a79800cbc 100644
--- a/lib/librte_ethdev/rte_ethdev_version.map
+++ b/lib/librte_ethdev/rte_ethdev_version.map
@@ -239,6 +239,9 @@ DPDK_19.05 {
 EXPERIMENTAL {
 	global:
 
+	rte_eth_basic_stats_count;
+	rte_eth_basic_stats_get;
+	rte_eth_basic_stats_get_names;
 	rte_eth_devargs_parse;
 	rte_eth_dev_create;
 	rte_eth_dev_destroy;
-- 
2.20.1


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

* [dpdk-dev] [PATCH 2/2] failsafe: implement xstats
  2019-06-26 22:21 [dpdk-dev] [PATCH 0/2] failsafe: add xstats Stephen Hemminger
  2019-06-26 22:21 ` [dpdk-dev] [PATCH 1/2] ethdev: expose basic xstats for driver use Stephen Hemminger
@ 2019-06-26 22:21 ` Stephen Hemminger
  2019-06-26 23:33 ` [dpdk-dev] [PATCH v2 0/2] failsafe: add xstats Stephen Hemminger
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 27+ messages in thread
From: Stephen Hemminger @ 2019-06-26 22:21 UTC (permalink / raw)
  To: gaetan.rivet; +Cc: dev, Stephen Hemminger

From: Stephen Hemminger <sthemmin@microsoft.com>

Add support for extended statistics in failsafe driver.
Reports basic statistics for the failsafe driver, and detailed
statistics for each sub device.

Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
---
 drivers/net/failsafe/failsafe_ops.c | 144 ++++++++++++++++++++++++++++
 1 file changed, 144 insertions(+)

diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
index 96e05d4dc4b1..9ab32457983d 100644
--- a/drivers/net/failsafe/failsafe_ops.c
+++ b/drivers/net/failsafe/failsafe_ops.c
@@ -789,6 +789,147 @@ fs_stats_reset(struct rte_eth_dev *dev)
 	fs_unlock(dev, 0);
 }
 
+static int
+fs_xstats_count(struct rte_eth_dev *dev)
+{
+	struct sub_device *sdev;
+	int r, count;
+	uint8_t i;
+
+	count = rte_eth_basic_stats_count(dev);
+
+	fs_lock(dev, 0);
+	FOREACH_SUBDEV(sdev, i, dev) {
+		if (sdev->state < DEV_ACTIVE)
+			continue;
+
+		r = rte_eth_xstats_get_names(PORT_ID(sdev), NULL, 0);
+		if (r < 0) {
+			fs_unlock(dev, 0);
+			return r;
+		}
+
+		count += r;
+	}
+	fs_unlock(dev, 0);
+
+	return count;
+}
+
+static int
+fs_xstats_get_names(struct rte_eth_dev *dev,
+		    struct rte_eth_xstat_name *xstats_names,
+		    unsigned int limit)
+{
+	struct sub_device *sdev;
+	unsigned int count;
+	uint8_t i;
+	char tmp[RTE_ETH_XSTATS_NAME_SIZE];
+	int j,r;
+
+	if (!xstats_names)
+		return fs_xstats_count(dev);
+
+	r = rte_eth_basic_stats_get_names(dev, xstats_names);
+	if (r < 0)
+		return r;
+
+	count = r;
+
+	fs_lock(dev, 0);
+	FOREACH_SUBDEV(sdev, i, dev) {
+		struct rte_eth_xstat_name *sub_names = xstats_names + count;
+
+		if (sdev->state < DEV_ACTIVE)
+			continue;
+
+		if (count >= limit)
+			break;
+
+		r = rte_eth_xstats_get_names(PORT_ID(sdev), sub_names,
+					     count < limit ? limit - count: 0);
+		if (r < 0) {
+			fs_unlock(dev, 0);
+			return r;
+		}
+
+		/* add sub_ prefix to names */
+		for (j = 0; j < r; j++) {
+			snprintf(tmp, sizeof(tmp), "sub%u_%s",
+				 i, sub_names[j].name);
+			memcpy(sub_names[j].name, tmp,
+			       RTE_ETH_XSTATS_NAME_SIZE);
+		}
+
+		count += r;
+	}
+	fs_unlock(dev, 0);
+
+	return count;
+}
+
+static int
+fs_xstats_get(struct rte_eth_dev *dev,
+	      struct rte_eth_xstat *xstats,
+	      unsigned int n)
+{
+	unsigned int nstats, j, count, scount;
+	struct sub_device *sdev;
+	uint8_t i;
+	int ret;
+
+	nstats = fs_xstats_count(dev);
+	if (n < nstats || xstats == NULL)
+		return nstats;
+
+	ret = rte_eth_basic_stats_get(dev->data->port_id, xstats);
+	if (ret < 0)
+		return ret;
+
+	count = ret;
+	for (j = 0; j < count; j++)
+		xstats[j].id = j;
+
+	fs_lock(dev, 0);
+	FOREACH_SUBDEV(sdev, i, dev) {
+		if (sdev->state < DEV_ACTIVE)
+			continue;
+
+		ret = rte_eth_xstats_get(PORT_ID(sdev),
+					 xstats + count,
+					 n > count ? n - count : 0);
+		if (ret < 0) {
+			fs_unlock(dev, 0);
+			return ret;
+		}
+		scount = ret;
+
+		/* add offset to id's from sub-device */
+		for (j = 0; j < scount; j++)
+			xstats[count + j].id += count;
+
+		count += scount;
+	}
+	fs_unlock(dev, 0);
+
+	return count;
+}
+
+static void
+fs_xstats_reset(struct rte_eth_dev *dev)
+{
+	struct sub_device *sdev;
+	uint8_t i;
+
+	rte_eth_stats_reset(dev->data->port_id);
+
+	fs_lock(dev, 0);
+	FOREACH_SUBDEV(sdev, i, dev) {
+		rte_eth_xstats_reset(PORT_ID(sdev));
+	}
+	fs_unlock(dev, 0);
+}
+
 static void
 fs_dev_merge_desc_lim(struct rte_eth_desc_lim *to,
 		      const struct rte_eth_desc_lim *from)
@@ -1233,6 +1374,9 @@ const struct eth_dev_ops failsafe_ops = {
 	.link_update = fs_link_update,
 	.stats_get = fs_stats_get,
 	.stats_reset = fs_stats_reset,
+	.xstats_get = fs_xstats_get,
+	.xstats_get_names = fs_xstats_get_names,
+	.xstats_reset = fs_xstats_reset,
 	.dev_infos_get = fs_dev_infos_get,
 	.dev_supported_ptypes_get = fs_dev_supported_ptypes_get,
 	.mtu_set = fs_mtu_set,
-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 0/2] failsafe: add xstats
  2019-06-26 22:21 [dpdk-dev] [PATCH 0/2] failsafe: add xstats Stephen Hemminger
  2019-06-26 22:21 ` [dpdk-dev] [PATCH 1/2] ethdev: expose basic xstats for driver use Stephen Hemminger
  2019-06-26 22:21 ` [dpdk-dev] [PATCH 2/2] failsafe: implement xstats Stephen Hemminger
@ 2019-06-26 23:33 ` Stephen Hemminger
  2019-06-26 23:33   ` [dpdk-dev] [PATCH v2 1/2] ethdev: expose basic xstats for driver use Stephen Hemminger
  2019-06-26 23:33   ` [dpdk-dev] [PATCH v2 2/2] failsafe: implement xstats Stephen Hemminger
  2019-07-03 17:25 ` [dpdk-dev] [PATCH v2 0/2] *failsafe: add xstats Stephen Hemminger
  2019-08-11 16:06 ` [dpdk-dev] [PATCH v3 0/2] failsafe: " Stephen Hemminger
  4 siblings, 2 replies; 27+ messages in thread
From: Stephen Hemminger @ 2019-06-26 23:33 UTC (permalink / raw)
  To: gaetan.rivet; +Cc: dev, Stephen Hemminger

A useful feature of netvsc PMD is the ability to see how many packets
were processed through the VF device. This patch set adds a similar
(but more limited) capability to failsafe driver.

Since failsafe doesn't have top level xstats, this set uses the generic
xstats that exist already as a base then adds the sub-device xstats
to that.

v2 - fix checkpatch complaints

Stephen Hemminger (2):
  ethdev: expose basic xstats for driver use
  failsafe: implement xstats

 drivers/net/failsafe/failsafe_ops.c      | 130 +++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev.c           |  17 ++-
 lib/librte_ethdev/rte_ethdev_core.h      |  14 +++
 lib/librte_ethdev/rte_ethdev_version.map |   3 +
 4 files changed, 155 insertions(+), 9 deletions(-)

-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 1/2] ethdev: expose basic xstats for driver use
  2019-06-26 23:33 ` [dpdk-dev] [PATCH v2 0/2] failsafe: add xstats Stephen Hemminger
@ 2019-06-26 23:33   ` Stephen Hemminger
  2019-07-01 10:54     ` Andrew Rybchenko
  2019-06-26 23:33   ` [dpdk-dev] [PATCH v2 2/2] failsafe: implement xstats Stephen Hemminger
  1 sibling, 1 reply; 27+ messages in thread
From: Stephen Hemminger @ 2019-06-26 23:33 UTC (permalink / raw)
  To: gaetan.rivet; +Cc: dev, Stephen Hemminger, Stephen Hemminger

Avoid duplication by having generic basic xstats available
for use by drivers. A later patch uses this for failsafe
driver.

Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
---
 lib/librte_ethdev/rte_ethdev.c           | 17 ++++++++---------
 lib/librte_ethdev/rte_ethdev_core.h      | 14 ++++++++++++++
 lib/librte_ethdev/rte_ethdev_version.map |  3 +++
 3 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 8ac301608b9c..a83e9727c144 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -1996,8 +1996,8 @@ rte_eth_stats_reset(uint16_t port_id)
 	return 0;
 }
 
-static inline int
-get_xstats_basic_count(struct rte_eth_dev *dev)
+int
+rte_eth_basic_stats_count(struct rte_eth_dev *dev)
 {
 	uint16_t nb_rxqs, nb_txqs;
 	int count;
@@ -2034,7 +2034,7 @@ get_xstats_count(uint16_t port_id)
 		count = 0;
 
 
-	count += get_xstats_basic_count(dev);
+	count += rte_eth_basic_stats_count(dev);
 
 	return count;
 }
@@ -2084,7 +2084,7 @@ rte_eth_xstats_get_id_by_name(uint16_t port_id, const char *xstat_name,
 }
 
 /* retrieve basic stats names */
-static int
+int
 rte_eth_basic_stats_get_names(struct rte_eth_dev *dev,
 	struct rte_eth_xstat_name *xstats_names)
 {
@@ -2140,7 +2140,7 @@ rte_eth_xstats_get_names_by_id(uint16_t port_id,
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
-	basic_count = get_xstats_basic_count(dev);
+	basic_count = rte_eth_basic_stats_count(dev);
 	ret = get_xstats_count(port_id);
 	if (ret < 0)
 		return ret;
@@ -2268,8 +2268,7 @@ rte_eth_xstats_get_names(uint16_t port_id,
 	return cnt_used_entries;
 }
 
-
-static int
+int
 rte_eth_basic_stats_get(uint16_t port_id, struct rte_eth_xstat *xstats)
 {
 	struct rte_eth_dev *dev;
@@ -2341,7 +2340,7 @@ rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids,
 	expected_entries = (uint16_t)ret;
 	struct rte_eth_xstat xstats[expected_entries];
 	dev = &rte_eth_devices[port_id];
-	basic_count = get_xstats_basic_count(dev);
+	basic_count = rte_eth_basic_stats_count(dev);
 
 	/* Return max number of stats if no ids given */
 	if (!ids) {
@@ -2355,7 +2354,7 @@ rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids,
 		return -EINVAL;
 
 	if (ids && dev->dev_ops->xstats_get_by_id != NULL && size) {
-		unsigned int basic_count = get_xstats_basic_count(dev);
+		unsigned int basic_count = rte_eth_basic_stats_count(dev);
 		uint64_t ids_copy[size];
 
 		for (i = 0; i < size; i++) {
diff --git a/lib/librte_ethdev/rte_ethdev_core.h b/lib/librte_ethdev/rte_ethdev_core.h
index 2922d5b7cc95..91ce1880d1c6 100644
--- a/lib/librte_ethdev/rte_ethdev_core.h
+++ b/lib/librte_ethdev/rte_ethdev_core.h
@@ -517,6 +517,20 @@ struct eth_dev_ops {
 	/**< Test if a port supports specific mempool ops */
 };
 
+/**
+ * @internal
+ * Get basic stats for ethdev
+ */
+int __rte_experimental
+rte_eth_basic_stats_count(struct rte_eth_dev *dev);
+
+int  __rte_experimental
+rte_eth_basic_stats_get_names(struct rte_eth_dev *dev,
+			      struct rte_eth_xstat_name *xstats_names);
+
+int __rte_experimental
+rte_eth_basic_stats_get(uint16_t port_id, struct rte_eth_xstat *xstats);
+
 /**
  * @internal
  * Structure used to hold information about the callbacks to be called for a
diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map
index df9141825c3f..949a79800cbc 100644
--- a/lib/librte_ethdev/rte_ethdev_version.map
+++ b/lib/librte_ethdev/rte_ethdev_version.map
@@ -239,6 +239,9 @@ DPDK_19.05 {
 EXPERIMENTAL {
 	global:
 
+	rte_eth_basic_stats_count;
+	rte_eth_basic_stats_get;
+	rte_eth_basic_stats_get_names;
 	rte_eth_devargs_parse;
 	rte_eth_dev_create;
 	rte_eth_dev_destroy;
-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 2/2] failsafe: implement xstats
  2019-06-26 23:33 ` [dpdk-dev] [PATCH v2 0/2] failsafe: add xstats Stephen Hemminger
  2019-06-26 23:33   ` [dpdk-dev] [PATCH v2 1/2] ethdev: expose basic xstats for driver use Stephen Hemminger
@ 2019-06-26 23:33   ` Stephen Hemminger
  2019-07-01 12:33     ` Gaëtan Rivet
  1 sibling, 1 reply; 27+ messages in thread
From: Stephen Hemminger @ 2019-06-26 23:33 UTC (permalink / raw)
  To: gaetan.rivet; +Cc: dev, Stephen Hemminger, Stephen Hemminger

Add support for extended statistics in failsafe driver.
Reports basic statistics for the failsafe driver, and detailed
statistics for each sub device.

Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
---
 drivers/net/failsafe/failsafe_ops.c | 130 ++++++++++++++++++++++++++++
 1 file changed, 130 insertions(+)

diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
index 96e05d4dc4b1..a250c0528965 100644
--- a/drivers/net/failsafe/failsafe_ops.c
+++ b/drivers/net/failsafe/failsafe_ops.c
@@ -789,6 +789,133 @@ fs_stats_reset(struct rte_eth_dev *dev)
 	fs_unlock(dev, 0);
 }
 
+static int
+fs_xstats_count(struct rte_eth_dev *dev)
+{
+	struct sub_device *sdev;
+	uint8_t i;
+	int count;
+
+	count = rte_eth_basic_stats_count(dev);
+
+	fs_lock(dev, 0);
+	FOREACH_SUBDEV(sdev, i, dev) {
+		count += rte_eth_xstats_get_names(PORT_ID(sdev), NULL, 0);
+	}
+	fs_unlock(dev, 0);
+
+	return count;
+}
+
+static int
+fs_xstats_get_names(struct rte_eth_dev *dev,
+		    struct rte_eth_xstat_name *xstats_names,
+		    unsigned int limit)
+{
+	struct sub_device *sdev;
+	unsigned int count;
+	char tmp[RTE_ETH_XSTATS_NAME_SIZE];
+	uint8_t i;
+	int r;
+
+	if (!xstats_names)
+		return fs_xstats_count(dev);
+
+	r = rte_eth_basic_stats_get_names(dev, xstats_names);
+	if (r < 0)
+		return r;
+
+	count = r;
+
+	fs_lock(dev, 0);
+	FOREACH_SUBDEV(sdev, i, dev) {
+		struct rte_eth_xstat_name *sub_names = xstats_names + count;
+
+		if (count >= limit)
+			break;
+
+		r = rte_eth_xstats_get_names(PORT_ID(sdev),
+					     xstats_names + count,
+					     limit - count);
+		if (r < 0) {
+			fs_unlock(dev, 0);
+			return r;
+		}
+
+		/* add sub_ prefix to names */
+		for (i = 0; i < r; i++) {
+			snprintf(tmp, sizeof(tmp), "sub%u_%s",
+				 i, sub_names[i].name);
+			memcpy(sub_names[i].name, tmp,
+			       RTE_ETH_XSTATS_NAME_SIZE);
+		}
+
+		count += r;
+	}
+	fs_unlock(dev, 0);
+
+	return count;
+}
+
+static int
+fs_xstats_get(struct rte_eth_dev *dev,
+	      struct rte_eth_xstat *xstats,
+	      unsigned int n)
+{
+	unsigned int nstats, j, count, scount;
+	struct sub_device *sdev;
+	uint8_t i;
+	int ret;
+
+	nstats = fs_xstats_count(dev);
+	if (n < nstats || xstats == NULL)
+		return nstats;
+
+	ret = rte_eth_basic_stats_get(dev->data->port_id, xstats);
+	if (ret < 0)
+		return ret;
+
+	count = ret;
+	for (j = 0; j < count; j++)
+		xstats[j].id = j;
+
+	fs_lock(dev, 0);
+	FOREACH_SUBDEV(sdev, i, dev) {
+		ret = rte_eth_xstats_get(PORT_ID(sdev),
+					 xstats + count,
+					 n > count ? n - count : 0);
+		if (ret < 0) {
+			fs_unlock(dev, 0);
+			return ret;
+		}
+		scount = ret;
+
+		/* add offset to id's from sub-device */
+		for (j = 0; j < scount; j++)
+			xstats[count + j].id += count;
+
+		count += scount;
+	}
+	fs_unlock(dev, 0);
+
+	return count;
+}
+
+static void
+fs_xstats_reset(struct rte_eth_dev *dev)
+{
+	struct sub_device *sdev;
+	uint8_t i;
+
+	rte_eth_stats_reset(dev->data->port_id);
+
+	fs_lock(dev, 0);
+	FOREACH_SUBDEV(sdev, i, dev) {
+		rte_eth_xstats_reset(PORT_ID(sdev));
+	}
+	fs_unlock(dev, 0);
+}
+
 static void
 fs_dev_merge_desc_lim(struct rte_eth_desc_lim *to,
 		      const struct rte_eth_desc_lim *from)
@@ -1233,6 +1360,9 @@ const struct eth_dev_ops failsafe_ops = {
 	.link_update = fs_link_update,
 	.stats_get = fs_stats_get,
 	.stats_reset = fs_stats_reset,
+	.xstats_get = fs_xstats_get,
+	.xstats_get_names = fs_xstats_get_names,
+	.xstats_reset = fs_xstats_reset,
 	.dev_infos_get = fs_dev_infos_get,
 	.dev_supported_ptypes_get = fs_dev_supported_ptypes_get,
 	.mtu_set = fs_mtu_set,
-- 
2.20.1


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

* Re: [dpdk-dev] [PATCH v2 1/2] ethdev: expose basic xstats for driver use
  2019-06-26 23:33   ` [dpdk-dev] [PATCH v2 1/2] ethdev: expose basic xstats for driver use Stephen Hemminger
@ 2019-07-01 10:54     ` Andrew Rybchenko
  2019-07-01 14:59       ` Stephen Hemminger
  0 siblings, 1 reply; 27+ messages in thread
From: Andrew Rybchenko @ 2019-07-01 10:54 UTC (permalink / raw)
  To: Stephen Hemminger, gaetan.rivet; +Cc: dev, Stephen Hemminger

On 27.06.2019 2:33, Stephen Hemminger wrote:
> Avoid duplication by having generic basic xstats available
> for use by drivers. A later patch uses this for failsafe
> driver.
>
> Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>

[...]


> diff --git a/lib/librte_ethdev/rte_ethdev_core.h b/lib/librte_ethdev/rte_ethdev_core.h
> index 2922d5b7cc95..91ce1880d1c6 100644
> --- a/lib/librte_ethdev/rte_ethdev_core.h
> +++ b/lib/librte_ethdev/rte_ethdev_core.h
> @@ -517,6 +517,20 @@ struct eth_dev_ops {
>   	/**< Test if a port supports specific mempool ops */
>   };
>   
> +/**
> + * @internal
> + * Get basic stats for ethdev
> + */
> +int __rte_experimental
> +rte_eth_basic_stats_count(struct rte_eth_dev *dev);
> +
> +int  __rte_experimental
> +rte_eth_basic_stats_get_names(struct rte_eth_dev *dev,
> +			      struct rte_eth_xstat_name *xstats_names);
> +
> +int __rte_experimental
> +rte_eth_basic_stats_get(uint16_t port_id, struct rte_eth_xstat *xstats);
> +
>   /**
>    * @internal
>    * Structure used to hold information about the callbacks to be called for a

It conflicts with __rte_experimenal placing patch which is on the 
mailing list.
Also I've expected to see these functions in rte_ethdev_driver.h to
avoid inclusion in rte_ethdev.h. As I understand these functions are for
rte_ethdev and drivers only.

> diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map
> index df9141825c3f..949a79800cbc 100644
> --- a/lib/librte_ethdev/rte_ethdev_version.map
> +++ b/lib/librte_ethdev/rte_ethdev_version.map
> @@ -239,6 +239,9 @@ DPDK_19.05 {
>   EXPERIMENTAL {
>   	global:
>   
> +	rte_eth_basic_stats_count;
> +	rte_eth_basic_stats_get;
> +	rte_eth_basic_stats_get_names;
>   	rte_eth_devargs_parse;
>   	rte_eth_dev_create;
>   	rte_eth_dev_destroy;

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

* Re: [dpdk-dev] [PATCH v2 2/2] failsafe: implement xstats
  2019-06-26 23:33   ` [dpdk-dev] [PATCH v2 2/2] failsafe: implement xstats Stephen Hemminger
@ 2019-07-01 12:33     ` Gaëtan Rivet
  0 siblings, 0 replies; 27+ messages in thread
From: Gaëtan Rivet @ 2019-07-01 12:33 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev, Stephen Hemminger

Hello Stephen,

On Wed, Jun 26, 2019 at 04:33:46PM -0700, Stephen Hemminger wrote:
> Add support for extended statistics in failsafe driver.
> Reports basic statistics for the failsafe driver, and detailed
> statistics for each sub device.
> 
> Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
> ---
>  drivers/net/failsafe/failsafe_ops.c | 130 ++++++++++++++++++++++++++++
>  1 file changed, 130 insertions(+)
> 
> diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
> index 96e05d4dc4b1..a250c0528965 100644
> --- a/drivers/net/failsafe/failsafe_ops.c
> +++ b/drivers/net/failsafe/failsafe_ops.c
> @@ -789,6 +789,133 @@ fs_stats_reset(struct rte_eth_dev *dev)
>  	fs_unlock(dev, 0);
>  }
>  
> +static int
> +fs_xstats_count(struct rte_eth_dev *dev)
> +{
> +	struct sub_device *sdev;
> +	uint8_t i;
> +	int count;
> +
> +	count = rte_eth_basic_stats_count(dev);
> +
> +	fs_lock(dev, 0);
> +	FOREACH_SUBDEV(sdev, i, dev) {
> +		count += rte_eth_xstats_get_names(PORT_ID(sdev), NULL, 0);
> +	}
> +	fs_unlock(dev, 0);
> +
> +	return count;
> +}
> +
> +static int
> +fs_xstats_get_names(struct rte_eth_dev *dev,
> +		    struct rte_eth_xstat_name *xstats_names,
> +		    unsigned int limit)
> +{
> +	struct sub_device *sdev;
> +	unsigned int count;
> +	char tmp[RTE_ETH_XSTATS_NAME_SIZE];
> +	uint8_t i;
> +	int r;
> +
> +	if (!xstats_names)
> +		return fs_xstats_count(dev);
> +
> +	r = rte_eth_basic_stats_get_names(dev, xstats_names);
> +	if (r < 0)
> +		return r;
> +
> +	count = r;
> +
> +	fs_lock(dev, 0);
> +	FOREACH_SUBDEV(sdev, i, dev) {
> +		struct rte_eth_xstat_name *sub_names = xstats_names + count;
> +
> +		if (count >= limit)
> +			break;
> +
> +		r = rte_eth_xstats_get_names(PORT_ID(sdev),
> +					     xstats_names + count,

sub_names here?

Or do you want to point our the relationship between + count on the
array and - count on the array length? If so that makes sense.

> +					     limit - count);
> +		if (r < 0) {
> +			fs_unlock(dev, 0);
> +			return r;
> +		}
> +
> +		/* add sub_ prefix to names */
> +		for (i = 0; i < r; i++) {
> +			snprintf(tmp, sizeof(tmp), "sub%u_%s",

Prefixing is a good idea, maybe it would be better with an '_' between
the sub device name and the stat name?

The rest of the implementation seems solid, thanks.

You need to update the feature matrix for fail-safe however.

Regards,
-- 
Gaëtan Rivet
6WIND

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

* Re: [dpdk-dev] [PATCH v2 1/2] ethdev: expose basic xstats for driver use
  2019-07-01 10:54     ` Andrew Rybchenko
@ 2019-07-01 14:59       ` Stephen Hemminger
  0 siblings, 0 replies; 27+ messages in thread
From: Stephen Hemminger @ 2019-07-01 14:59 UTC (permalink / raw)
  To: Andrew Rybchenko; +Cc: gaetan.rivet, dev, Stephen Hemminger

On Mon, 1 Jul 2019 13:54:52 +0300
Andrew Rybchenko <arybchenko@solarflare.com> wrote:

> On 27.06.2019 2:33, Stephen Hemminger wrote:
> > Avoid duplication by having generic basic xstats available
> > for use by drivers. A later patch uses this for failsafe
> > driver.
> >
> > Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>  
> 
> [...]
> 
> 
> > diff --git a/lib/librte_ethdev/rte_ethdev_core.h b/lib/librte_ethdev/rte_ethdev_core.h
> > index 2922d5b7cc95..91ce1880d1c6 100644
> > --- a/lib/librte_ethdev/rte_ethdev_core.h
> > +++ b/lib/librte_ethdev/rte_ethdev_core.h
> > @@ -517,6 +517,20 @@ struct eth_dev_ops {
> >   	/**< Test if a port supports specific mempool ops */
> >   };
> >   
> > +/**
> > + * @internal
> > + * Get basic stats for ethdev
> > + */
> > +int __rte_experimental
> > +rte_eth_basic_stats_count(struct rte_eth_dev *dev);
> > +
> > +int  __rte_experimental
> > +rte_eth_basic_stats_get_names(struct rte_eth_dev *dev,
> > +			      struct rte_eth_xstat_name *xstats_names);
> > +
> > +int __rte_experimental
> > +rte_eth_basic_stats_get(uint16_t port_id, struct rte_eth_xstat *xstats);
> > +
> >   /**
> >    * @internal
> >    * Structure used to hold information about the callbacks to be called for a  
> 
> It conflicts with __rte_experimenal placing patch which is on the 
> mailing list.
> Also I've expected to see these functions in rte_ethdev_driver.h to
> avoid inclusion in rte_ethdev.h. As I understand these functions are for
> rte_ethdev and drivers only.

Yes. Will change in V3

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

* [dpdk-dev] [PATCH v2 0/2] *failsafe: add xstats
  2019-06-26 22:21 [dpdk-dev] [PATCH 0/2] failsafe: add xstats Stephen Hemminger
                   ` (2 preceding siblings ...)
  2019-06-26 23:33 ` [dpdk-dev] [PATCH v2 0/2] failsafe: add xstats Stephen Hemminger
@ 2019-07-03 17:25 ` Stephen Hemminger
  2019-07-03 17:25   ` [dpdk-dev] [PATCH v2 1/2] ethdev: expose basic xstats for driver use Stephen Hemminger
                     ` (2 more replies)
  2019-08-11 16:06 ` [dpdk-dev] [PATCH v3 0/2] failsafe: " Stephen Hemminger
  4 siblings, 3 replies; 27+ messages in thread
From: Stephen Hemminger @ 2019-07-03 17:25 UTC (permalink / raw)
  To: gaetan.rivet, arybchenko; +Cc: dev, Stephen Hemminger

A useful feature of netvsc PMD is the ability to see how many packets
were processed through the VF device. This patch set adds a similar
(but more limited) capability to failsafe driver.

Since failsafe doesn't have top level xstats, this set uses the generic
xstats that exist already as a base then adds the sub-device xstats
to that.

v2 
    move generic xstats helpers to rte_ethdev_driver.h
    change prefix on subdevice stats to sub0_XXXX

Stephen Hemminger (2):
  ethdev: expose basic xstats for driver use
  failsafe: implement xstats

 drivers/net/failsafe/failsafe_ops.c      | 135 +++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev.c           |  17 ++-
 lib/librte_ethdev/rte_ethdev_driver.h    |  65 +++++++++++
 lib/librte_ethdev/rte_ethdev_version.map |   3 +
 4 files changed, 211 insertions(+), 9 deletions(-)

-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 1/2] ethdev: expose basic xstats for driver use
  2019-07-03 17:25 ` [dpdk-dev] [PATCH v2 0/2] *failsafe: add xstats Stephen Hemminger
@ 2019-07-03 17:25   ` Stephen Hemminger
  2019-07-03 17:25   ` [dpdk-dev] [PATCH v2 2/2] failsafe: implement xstats Stephen Hemminger
  2019-07-04  9:56   ` [dpdk-dev] [PATCH v2 0/2] *failsafe: add xstats Gaëtan Rivet
  2 siblings, 0 replies; 27+ messages in thread
From: Stephen Hemminger @ 2019-07-03 17:25 UTC (permalink / raw)
  To: gaetan.rivet, arybchenko; +Cc: dev, Stephen Hemminger

Avoid duplication by having generic basic xstats available
for use by drivers. A later patch uses this for failsafe
driver.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/librte_ethdev/rte_ethdev.c           | 17 +++----
 lib/librte_ethdev/rte_ethdev_driver.h    | 65 ++++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev_version.map |  3 ++
 3 files changed, 76 insertions(+), 9 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 31f02ec2ba3b..82fcac57b1a7 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -1996,8 +1996,8 @@ rte_eth_stats_reset(uint16_t port_id)
 	return 0;
 }
 
-static inline int
-get_xstats_basic_count(struct rte_eth_dev *dev)
+int
+rte_eth_basic_stats_count(struct rte_eth_dev *dev)
 {
 	uint16_t nb_rxqs, nb_txqs;
 	int count;
@@ -2034,7 +2034,7 @@ get_xstats_count(uint16_t port_id)
 		count = 0;
 
 
-	count += get_xstats_basic_count(dev);
+	count += rte_eth_basic_stats_count(dev);
 
 	return count;
 }
@@ -2084,7 +2084,7 @@ rte_eth_xstats_get_id_by_name(uint16_t port_id, const char *xstat_name,
 }
 
 /* retrieve basic stats names */
-static int
+int
 rte_eth_basic_stats_get_names(struct rte_eth_dev *dev,
 	struct rte_eth_xstat_name *xstats_names)
 {
@@ -2140,7 +2140,7 @@ rte_eth_xstats_get_names_by_id(uint16_t port_id,
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
-	basic_count = get_xstats_basic_count(dev);
+	basic_count = rte_eth_basic_stats_count(dev);
 	ret = get_xstats_count(port_id);
 	if (ret < 0)
 		return ret;
@@ -2268,8 +2268,7 @@ rte_eth_xstats_get_names(uint16_t port_id,
 	return cnt_used_entries;
 }
 
-
-static int
+int
 rte_eth_basic_stats_get(uint16_t port_id, struct rte_eth_xstat *xstats)
 {
 	struct rte_eth_dev *dev;
@@ -2341,7 +2340,7 @@ rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids,
 	expected_entries = (uint16_t)ret;
 	struct rte_eth_xstat xstats[expected_entries];
 	dev = &rte_eth_devices[port_id];
-	basic_count = get_xstats_basic_count(dev);
+	basic_count = rte_eth_basic_stats_count(dev);
 
 	/* Return max number of stats if no ids given */
 	if (!ids) {
@@ -2355,7 +2354,7 @@ rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids,
 		return -EINVAL;
 
 	if (ids && dev->dev_ops->xstats_get_by_id != NULL && size) {
-		unsigned int basic_count = get_xstats_basic_count(dev);
+		unsigned int basic_count = rte_eth_basic_stats_count(dev);
 		uint64_t ids_copy[size];
 
 		for (i = 0; i < size; i++) {
diff --git a/lib/librte_ethdev/rte_ethdev_driver.h b/lib/librte_ethdev/rte_ethdev_driver.h
index 936ff8c98651..489889a72203 100644
--- a/lib/librte_ethdev/rte_ethdev_driver.h
+++ b/lib/librte_ethdev/rte_ethdev_driver.h
@@ -208,6 +208,71 @@ rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
 #endif
 }
 
+/**
+ * @internal
+ * Get basic stats part of xstats for an ethernet device.
+ *
+ * @param dev
+ *  Pointer to struct rte_eth_dev.
+ */
+__rte_experimental
+int
+rte_eth_basic_stats_count(struct rte_eth_dev *dev);
+
+/**
+ * @internal
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Retrieve the names for the basic part of extended statistics.
+ *
+ * @param dev
+ *  Pointer to struct rte_eth_dev.
+ * @param xstats_names
+ *   An rte_eth_xstat_name array of at least *size* elements to
+ *   be filled. If set to NULL, the function returns the required number
+ *   of elements.
+ * @return
+ *   - A positive value lower or equal to size: success. The return value
+ *     is the number of entries filled in the stats table.
+ *   - A positive value higher than size: error, the given statistics table
+ *     is too small. The return value corresponds to the size that should
+ *     be given to succeed. The entries in the table are not valid and
+ *     shall not be used by the caller.
+ *   - A negative value on error (invalid port id).
+ */
+__rte_experimental
+int
+rte_eth_basic_stats_get_names(struct rte_eth_dev *dev,
+			      struct rte_eth_xstat_name *xstats_names);
+
+/**
+ * @internal
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Retrieve the basic part of the extended statistics.
+ *
+ * @param dev
+ *  Pointer to struct rte_eth_dev.
+ * @param xstats
+ *   A pointer to a table of structure of type *rte_eth_xstat*
+ *   to be filled with device statistics ids and values.
+ *   This parameter can be set to NULL if n is 0.
+ * @param n
+ *   The size of the xstats array (number of elements).
+ * @return
+ *   - A positive value lower or equal to n: success. The return value
+ *     is the number of entries filled in the stats table.
+ *   - A positive value higher than n: error, the given statistics table
+ *     is too small. The return value corresponds to the size that should
+ *     be given to succeed. The entries in the table are not valid and
+ *     shall not be used by the caller.
+ *   - A negative value on error (invalid port id).
+ */
+__rte_experimental
+int
+rte_eth_basic_stats_get(uint16_t port_id, struct rte_eth_xstat *xstats);
+
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map
index df9141825c3f..949a79800cbc 100644
--- a/lib/librte_ethdev/rte_ethdev_version.map
+++ b/lib/librte_ethdev/rte_ethdev_version.map
@@ -239,6 +239,9 @@ DPDK_19.05 {
 EXPERIMENTAL {
 	global:
 
+	rte_eth_basic_stats_count;
+	rte_eth_basic_stats_get;
+	rte_eth_basic_stats_get_names;
 	rte_eth_devargs_parse;
 	rte_eth_dev_create;
 	rte_eth_dev_destroy;
-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 2/2] failsafe: implement xstats
  2019-07-03 17:25 ` [dpdk-dev] [PATCH v2 0/2] *failsafe: add xstats Stephen Hemminger
  2019-07-03 17:25   ` [dpdk-dev] [PATCH v2 1/2] ethdev: expose basic xstats for driver use Stephen Hemminger
@ 2019-07-03 17:25   ` Stephen Hemminger
  2019-07-04  9:56   ` [dpdk-dev] [PATCH v2 0/2] *failsafe: add xstats Gaëtan Rivet
  2 siblings, 0 replies; 27+ messages in thread
From: Stephen Hemminger @ 2019-07-03 17:25 UTC (permalink / raw)
  To: gaetan.rivet, arybchenko; +Cc: dev, Stephen Hemminger

Add support for extended statistics in failsafe driver.
Reports basic statistics for the failsafe driver, and detailed
statistics for each sub device.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/failsafe/failsafe_ops.c | 135 ++++++++++++++++++++++++++++
 1 file changed, 135 insertions(+)

diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
index 96e05d4dc4b1..711fdf302f4f 100644
--- a/drivers/net/failsafe/failsafe_ops.c
+++ b/drivers/net/failsafe/failsafe_ops.c
@@ -789,6 +789,138 @@ fs_stats_reset(struct rte_eth_dev *dev)
 	fs_unlock(dev, 0);
 }
 
+/*
+ * Count how many xstats in total
+ * Include basic stats for failsafe device
+ * plus xstats for each sub-device present.
+ */
+static int
+fs_xstats_count(struct rte_eth_dev *dev)
+{
+	struct sub_device *sdev;
+	uint8_t i;
+	int count;
+
+	count = rte_eth_basic_stats_count(dev);
+
+	fs_lock(dev, 0);
+	FOREACH_SUBDEV(sdev, i, dev) {
+		count += rte_eth_xstats_get_names(PORT_ID(sdev), NULL, 0);
+	}
+	fs_unlock(dev, 0);
+
+	return count;
+}
+
+static int
+fs_xstats_get_names(struct rte_eth_dev *dev,
+		    struct rte_eth_xstat_name *xstats_names,
+		    unsigned int limit)
+{
+	struct sub_device *sdev;
+	unsigned int count;
+	char tmp[RTE_ETH_XSTATS_NAME_SIZE];
+	uint8_t i;
+	int r;
+
+	/* Caller only cares about count */
+	if (!xstats_names)
+		return fs_xstats_count(dev);
+
+	r = rte_eth_basic_stats_get_names(dev, xstats_names);
+	if (r < 0)
+		return r;
+
+	count = r;
+
+	fs_lock(dev, 0);
+	FOREACH_SUBDEV(sdev, i, dev) {
+		struct rte_eth_xstat_name *sub_names = xstats_names + count;
+
+		if (count >= limit)
+			break;
+
+		r = rte_eth_xstats_get_names(PORT_ID(sdev), sub_names,
+					     limit - count);
+		if (r < 0) {
+			fs_unlock(dev, 0);
+			return r;
+		}
+
+		/* add sub_ prefix to names */
+		for (i = 0; i < r; i++) {
+			snprintf(tmp, sizeof(tmp), "sub%u_%s",
+				 i, sub_names[i].name);
+			memcpy(sub_names[i].name, tmp,
+			       RTE_ETH_XSTATS_NAME_SIZE);
+		}
+
+		count += r;
+	}
+	fs_unlock(dev, 0);
+
+	return count;
+}
+
+static int
+fs_xstats_get(struct rte_eth_dev *dev,
+	      struct rte_eth_xstat *xstats,
+	      unsigned int n)
+{
+	unsigned int nstats, j, count, scount;
+	struct sub_device *sdev;
+	uint8_t i;
+	int ret;
+
+	nstats = fs_xstats_count(dev);
+	if (n < nstats || xstats == NULL)
+		return nstats;
+
+	ret = rte_eth_basic_stats_get(dev->data->port_id, xstats);
+	if (ret < 0)
+		return ret;
+
+	count = ret;
+	for (j = 0; j < count; j++)
+		xstats[j].id = j;
+
+	fs_lock(dev, 0);
+	FOREACH_SUBDEV(sdev, i, dev) {
+		ret = rte_eth_xstats_get(PORT_ID(sdev),
+					 xstats + count,
+					 n > count ? n - count : 0);
+		if (ret < 0) {
+			fs_unlock(dev, 0);
+			return ret;
+		}
+		scount = ret;
+
+		/* add offset to id's from sub-device */
+		for (j = 0; j < scount; j++)
+			xstats[count + j].id += count;
+
+		count += scount;
+	}
+	fs_unlock(dev, 0);
+
+	return count;
+}
+
+static void
+fs_xstats_reset(struct rte_eth_dev *dev)
+{
+	struct sub_device *sdev;
+	uint8_t i;
+
+	rte_eth_stats_reset(dev->data->port_id);
+
+	fs_lock(dev, 0);
+	FOREACH_SUBDEV(sdev, i, dev) {
+		rte_eth_xstats_reset(PORT_ID(sdev));
+	}
+	fs_unlock(dev, 0);
+}
+
 static void
 fs_dev_merge_desc_lim(struct rte_eth_desc_lim *to,
 		      const struct rte_eth_desc_lim *from)
@@ -1233,6 +1365,9 @@ const struct eth_dev_ops failsafe_ops = {
 	.link_update = fs_link_update,
 	.stats_get = fs_stats_get,
 	.stats_reset = fs_stats_reset,
+	.xstats_get = fs_xstats_get,
+	.xstats_get_names = fs_xstats_get_names,
+	.xstats_reset = fs_xstats_reset,
 	.dev_infos_get = fs_dev_infos_get,
 	.dev_supported_ptypes_get = fs_dev_supported_ptypes_get,
 	.mtu_set = fs_mtu_set,
-- 
2.20.1


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

* Re: [dpdk-dev] [PATCH v2 0/2] *failsafe: add xstats
  2019-07-03 17:25 ` [dpdk-dev] [PATCH v2 0/2] *failsafe: add xstats Stephen Hemminger
  2019-07-03 17:25   ` [dpdk-dev] [PATCH v2 1/2] ethdev: expose basic xstats for driver use Stephen Hemminger
  2019-07-03 17:25   ` [dpdk-dev] [PATCH v2 2/2] failsafe: implement xstats Stephen Hemminger
@ 2019-07-04  9:56   ` Gaëtan Rivet
  2 siblings, 0 replies; 27+ messages in thread
From: Gaëtan Rivet @ 2019-07-04  9:56 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: arybchenko, dev

On Wed, Jul 03, 2019 at 10:25:10AM -0700, Stephen Hemminger wrote:
> A useful feature of netvsc PMD is the ability to see how many packets
> were processed through the VF device. This patch set adds a similar
> (but more limited) capability to failsafe driver.
> 
> Since failsafe doesn't have top level xstats, this set uses the generic
> xstats that exist already as a base then adds the sub-device xstats
> to that.
> 
> v2 
>     move generic xstats helpers to rte_ethdev_driver.h
>     change prefix on subdevice stats to sub0_XXXX
> 

For the series:

Acked-by: Gaetan Rivet <gaetan.rivet@6wind.com>

> Stephen Hemminger (2):
>   ethdev: expose basic xstats for driver use
>   failsafe: implement xstats
> 
>  drivers/net/failsafe/failsafe_ops.c      | 135 +++++++++++++++++++++++
>  lib/librte_ethdev/rte_ethdev.c           |  17 ++-
>  lib/librte_ethdev/rte_ethdev_driver.h    |  65 +++++++++++
>  lib/librte_ethdev/rte_ethdev_version.map |   3 +
>  4 files changed, 211 insertions(+), 9 deletions(-)
> 
> -- 
> 2.20.1
> 

-- 
Gaëtan Rivet
6WIND

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

* [dpdk-dev] [PATCH v3 0/2] failsafe: add xstats
  2019-06-26 22:21 [dpdk-dev] [PATCH 0/2] failsafe: add xstats Stephen Hemminger
                   ` (3 preceding siblings ...)
  2019-07-03 17:25 ` [dpdk-dev] [PATCH v2 0/2] *failsafe: add xstats Stephen Hemminger
@ 2019-08-11 16:06 ` " Stephen Hemminger
  2019-08-11 16:06   ` [dpdk-dev] [PATCH v3 1/2] ethdev: expose basic xstats for driver use Stephen Hemminger
                     ` (3 more replies)
  4 siblings, 4 replies; 27+ messages in thread
From: Stephen Hemminger @ 2019-08-11 16:06 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

A useful feature of netvsc PMD is the ability to see how many packets
were processed through the VF device. This patch set adds a similar
(but more limited) capability to failsafe driver.

Since failsafe doesn't have top level xstats, this set uses the generic
xstats that exist already as a base then adds the sub-device xstats
to that.

v3 - rebase to 19.08

Stephen Hemminger (2):
  ethdev: expose basic xstats for driver use
  net/failsafe: implement xstats

 drivers/net/failsafe/failsafe_ops.c      | 135 +++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev.c           |  17 ++-
 lib/librte_ethdev/rte_ethdev_driver.h    |  65 +++++++++++
 lib/librte_ethdev/rte_ethdev_version.map |  24 ++++
 4 files changed, 232 insertions(+), 9 deletions(-)

-- 
2.20.1


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

* [dpdk-dev] [PATCH v3 1/2] ethdev: expose basic xstats for driver use
  2019-08-11 16:06 ` [dpdk-dev] [PATCH v3 0/2] failsafe: " Stephen Hemminger
@ 2019-08-11 16:06   ` Stephen Hemminger
  2019-08-11 16:06   ` [dpdk-dev] [PATCH v3 2/2] net/failsafe: implement xstats Stephen Hemminger
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 27+ messages in thread
From: Stephen Hemminger @ 2019-08-11 16:06 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Gaetan Rivet

Avoid duplication by having generic basic xstats available
for use by drivers. A later patch uses this for failsafe
driver.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_ethdev/rte_ethdev.c           | 17 +++----
 lib/librte_ethdev/rte_ethdev_driver.h    | 65 ++++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev_version.map | 24 +++++++++
 3 files changed, 97 insertions(+), 9 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 17d183e1f0ec..88e3065d06fd 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -1996,8 +1996,8 @@ rte_eth_stats_reset(uint16_t port_id)
 	return 0;
 }
 
-static inline int
-get_xstats_basic_count(struct rte_eth_dev *dev)
+int
+rte_eth_basic_stats_count(struct rte_eth_dev *dev)
 {
 	uint16_t nb_rxqs, nb_txqs;
 	int count;
@@ -2034,7 +2034,7 @@ get_xstats_count(uint16_t port_id)
 		count = 0;
 
 
-	count += get_xstats_basic_count(dev);
+	count += rte_eth_basic_stats_count(dev);
 
 	return count;
 }
@@ -2084,7 +2084,7 @@ rte_eth_xstats_get_id_by_name(uint16_t port_id, const char *xstat_name,
 }
 
 /* retrieve basic stats names */
-static int
+int
 rte_eth_basic_stats_get_names(struct rte_eth_dev *dev,
 	struct rte_eth_xstat_name *xstats_names)
 {
@@ -2140,7 +2140,7 @@ rte_eth_xstats_get_names_by_id(uint16_t port_id,
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
-	basic_count = get_xstats_basic_count(dev);
+	basic_count = rte_eth_basic_stats_count(dev);
 	ret = get_xstats_count(port_id);
 	if (ret < 0)
 		return ret;
@@ -2268,8 +2268,7 @@ rte_eth_xstats_get_names(uint16_t port_id,
 	return cnt_used_entries;
 }
 
-
-static int
+int
 rte_eth_basic_stats_get(uint16_t port_id, struct rte_eth_xstat *xstats)
 {
 	struct rte_eth_dev *dev;
@@ -2341,7 +2340,7 @@ rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids,
 	expected_entries = (uint16_t)ret;
 	struct rte_eth_xstat xstats[expected_entries];
 	dev = &rte_eth_devices[port_id];
-	basic_count = get_xstats_basic_count(dev);
+	basic_count = rte_eth_basic_stats_count(dev);
 
 	/* Return max number of stats if no ids given */
 	if (!ids) {
@@ -2355,7 +2354,7 @@ rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids,
 		return -EINVAL;
 
 	if (ids && dev->dev_ops->xstats_get_by_id != NULL && size) {
-		unsigned int basic_count = get_xstats_basic_count(dev);
+		unsigned int basic_count = rte_eth_basic_stats_count(dev);
 		uint64_t ids_copy[size];
 
 		for (i = 0; i < size; i++) {
diff --git a/lib/librte_ethdev/rte_ethdev_driver.h b/lib/librte_ethdev/rte_ethdev_driver.h
index 936ff8c98651..489889a72203 100644
--- a/lib/librte_ethdev/rte_ethdev_driver.h
+++ b/lib/librte_ethdev/rte_ethdev_driver.h
@@ -208,6 +208,71 @@ rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
 #endif
 }
 
+/**
+ * @internal
+ * Get basic stats part of xstats for an ethernet device.
+ *
+ * @param dev
+ *  Pointer to struct rte_eth_dev.
+ */
+__rte_experimental
+int
+rte_eth_basic_stats_count(struct rte_eth_dev *dev);
+
+/**
+ * @internal
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Retrieve the names for the basic part of extended statistics.
+ *
+ * @param dev
+ *  Pointer to struct rte_eth_dev.
+ * @param xstats_names
+ *   An rte_eth_xstat_name array of at least *size* elements to
+ *   be filled. If set to NULL, the function returns the required number
+ *   of elements.
+ * @return
+ *   - A positive value lower or equal to size: success. The return value
+ *     is the number of entries filled in the stats table.
+ *   - A positive value higher than size: error, the given statistics table
+ *     is too small. The return value corresponds to the size that should
+ *     be given to succeed. The entries in the table are not valid and
+ *     shall not be used by the caller.
+ *   - A negative value on error (invalid port id).
+ */
+__rte_experimental
+int
+rte_eth_basic_stats_get_names(struct rte_eth_dev *dev,
+			      struct rte_eth_xstat_name *xstats_names);
+
+/**
+ * @internal
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Retrieve the basic part of the extended statistics.
+ *
+ * @param dev
+ *  Pointer to struct rte_eth_dev.
+ * @param xstats
+ *   A pointer to a table of structure of type *rte_eth_xstat*
+ *   to be filled with device statistics ids and values.
+ *   This parameter can be set to NULL if n is 0.
+ * @param n
+ *   The size of the xstats array (number of elements).
+ * @return
+ *   - A positive value lower or equal to n: success. The return value
+ *     is the number of entries filled in the stats table.
+ *   - A positive value higher than n: error, the given statistics table
+ *     is too small. The return value corresponds to the size that should
+ *     be given to succeed. The entries in the table are not valid and
+ *     shall not be used by the caller.
+ *   - A negative value on error (invalid port id).
+ */
+__rte_experimental
+int
+rte_eth_basic_stats_get(uint16_t port_id, struct rte_eth_xstat *xstats);
+
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map
index 6df42a47b89d..f2198b0367d1 100644
--- a/lib/librte_ethdev/rte_ethdev_version.map
+++ b/lib/librte_ethdev/rte_ethdev_version.map
@@ -240,6 +240,25 @@ EXPERIMENTAL {
 	global:
 
 	# added in 17.11
+	rte_eth_devargs_parse;
+	rte_eth_dev_create;
+	rte_eth_dev_destroy;
+	rte_eth_dev_get_module_eeprom;
+	rte_eth_dev_get_module_info;
+	rte_eth_dev_is_removed;
+	rte_eth_dev_owner_delete;
+	rte_eth_dev_owner_get;
+	rte_eth_dev_owner_new;
+	rte_eth_dev_owner_set;
+	rte_eth_dev_owner_unset;
+	rte_eth_dev_rx_intr_ctl_q_get_fd;
+	rte_eth_find_next_of;
+	rte_eth_find_next_sibling;
+	rte_eth_read_clock;
+	rte_eth_switch_domain_alloc;
+	rte_eth_switch_domain_free;
+	rte_flow_conv;
+	rte_flow_expand_rss;
 	rte_mtr_capabilities_get;
 	rte_mtr_create;
 	rte_mtr_destroy;
@@ -283,4 +302,9 @@ EXPERIMENTAL {
 
 	# added in 19.08
 	rte_eth_read_clock;
+
+	# added in 19.11
+	rte_eth_basic_stats_count;
+	rte_eth_basic_stats_get;
+	rte_eth_basic_stats_get_names;
 };
-- 
2.20.1


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

* [dpdk-dev] [PATCH v3 2/2] net/failsafe: implement xstats
  2019-08-11 16:06 ` [dpdk-dev] [PATCH v3 0/2] failsafe: " Stephen Hemminger
  2019-08-11 16:06   ` [dpdk-dev] [PATCH v3 1/2] ethdev: expose basic xstats for driver use Stephen Hemminger
@ 2019-08-11 16:06   ` Stephen Hemminger
  2019-09-19 12:56   ` [dpdk-dev] [PATCH v4 0/2] failsafe: add xstats Stephen Hemminger
  2019-09-19 13:17   ` [dpdk-dev] [PATCH v5 0/2] failsafe: add xstats Stephen Hemminger
  3 siblings, 0 replies; 27+ messages in thread
From: Stephen Hemminger @ 2019-08-11 16:06 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Gaetan Rivet

Add support for extended statistics in failsafe driver.
Reports basic statistics for the failsafe driver, and detailed
statistics for each sub device.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/net/failsafe/failsafe_ops.c | 135 ++++++++++++++++++++++++++++
 1 file changed, 135 insertions(+)

diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
index 96e05d4dc4b1..711fdf302f4f 100644
--- a/drivers/net/failsafe/failsafe_ops.c
+++ b/drivers/net/failsafe/failsafe_ops.c
@@ -789,6 +789,138 @@ fs_stats_reset(struct rte_eth_dev *dev)
 	fs_unlock(dev, 0);
 }
 
+/*
+ * Count how many xstats in total
+ * Include basic stats for failsafe device
+ * plus xstats for each sub-device present.
+ */
+static int
+fs_xstats_count(struct rte_eth_dev *dev)
+{
+	struct sub_device *sdev;
+	uint8_t i;
+	int count;
+
+	count = rte_eth_basic_stats_count(dev);
+
+	fs_lock(dev, 0);
+	FOREACH_SUBDEV(sdev, i, dev) {
+		count += rte_eth_xstats_get_names(PORT_ID(sdev), NULL, 0);
+	}
+	fs_unlock(dev, 0);
+
+	return count;
+}
+
+static int
+fs_xstats_get_names(struct rte_eth_dev *dev,
+		    struct rte_eth_xstat_name *xstats_names,
+		    unsigned int limit)
+{
+	struct sub_device *sdev;
+	unsigned int count;
+	char tmp[RTE_ETH_XSTATS_NAME_SIZE];
+	uint8_t i;
+	int r;
+
+	/* Caller only cares about count */
+	if (!xstats_names)
+		return fs_xstats_count(dev);
+
+	r = rte_eth_basic_stats_get_names(dev, xstats_names);
+	if (r < 0)
+		return r;
+
+	count = r;
+
+	fs_lock(dev, 0);
+	FOREACH_SUBDEV(sdev, i, dev) {
+		struct rte_eth_xstat_name *sub_names = xstats_names + count;
+
+		if (count >= limit)
+			break;
+
+		r = rte_eth_xstats_get_names(PORT_ID(sdev), sub_names,
+					     limit - count);
+		if (r < 0) {
+			fs_unlock(dev, 0);
+			return r;
+		}
+
+		/* add sub_ prefix to names */
+		for (i = 0; i < r; i++) {
+			snprintf(tmp, sizeof(tmp), "sub%u_%s",
+				 i, sub_names[i].name);
+			memcpy(sub_names[i].name, tmp,
+			       RTE_ETH_XSTATS_NAME_SIZE);
+		}
+
+		count += r;
+	}
+	fs_unlock(dev, 0);
+
+	return count;
+}
+
+static int
+fs_xstats_get(struct rte_eth_dev *dev,
+	      struct rte_eth_xstat *xstats,
+	      unsigned int n)
+{
+	unsigned int nstats, j, count, scount;
+	struct sub_device *sdev;
+	uint8_t i;
+	int ret;
+
+	nstats = fs_xstats_count(dev);
+	if (n < nstats || xstats == NULL)
+		return nstats;
+
+	ret = rte_eth_basic_stats_get(dev->data->port_id, xstats);
+	if (ret < 0)
+		return ret;
+
+	count = ret;
+	for (j = 0; j < count; j++)
+		xstats[j].id = j;
+
+	fs_lock(dev, 0);
+	FOREACH_SUBDEV(sdev, i, dev) {
+		ret = rte_eth_xstats_get(PORT_ID(sdev),
+					 xstats + count,
+					 n > count ? n - count : 0);
+		if (ret < 0) {
+			fs_unlock(dev, 0);
+			return ret;
+		}
+		scount = ret;
+
+		/* add offset to id's from sub-device */
+		for (j = 0; j < scount; j++)
+			xstats[count + j].id += count;
+
+		count += scount;
+	}
+	fs_unlock(dev, 0);
+
+	return count;
+}
+
+static void
+fs_xstats_reset(struct rte_eth_dev *dev)
+{
+	struct sub_device *sdev;
+	uint8_t i;
+
+	rte_eth_stats_reset(dev->data->port_id);
+
+	fs_lock(dev, 0);
+	FOREACH_SUBDEV(sdev, i, dev) {
+		rte_eth_xstats_reset(PORT_ID(sdev));
+	}
+	fs_unlock(dev, 0);
+}
+
 static void
 fs_dev_merge_desc_lim(struct rte_eth_desc_lim *to,
 		      const struct rte_eth_desc_lim *from)
@@ -1233,6 +1365,9 @@ const struct eth_dev_ops failsafe_ops = {
 	.link_update = fs_link_update,
 	.stats_get = fs_stats_get,
 	.stats_reset = fs_stats_reset,
+	.xstats_get = fs_xstats_get,
+	.xstats_get_names = fs_xstats_get_names,
+	.xstats_reset = fs_xstats_reset,
 	.dev_infos_get = fs_dev_infos_get,
 	.dev_supported_ptypes_get = fs_dev_supported_ptypes_get,
 	.mtu_set = fs_mtu_set,
-- 
2.20.1


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

* [dpdk-dev] [PATCH v4 0/2] failsafe: add xstats
  2019-08-11 16:06 ` [dpdk-dev] [PATCH v3 0/2] failsafe: " Stephen Hemminger
  2019-08-11 16:06   ` [dpdk-dev] [PATCH v3 1/2] ethdev: expose basic xstats for driver use Stephen Hemminger
  2019-08-11 16:06   ` [dpdk-dev] [PATCH v3 2/2] net/failsafe: implement xstats Stephen Hemminger
@ 2019-09-19 12:56   ` Stephen Hemminger
  2019-09-19 12:56     ` [dpdk-dev] [PATCH 1/2] ethdev: expose basic xstats for driver use Stephen Hemminger
  2019-09-19 12:56     ` [dpdk-dev] [PATCH 2/2] net/failsafe: implement xstats Stephen Hemminger
  2019-09-19 13:17   ` [dpdk-dev] [PATCH v5 0/2] failsafe: add xstats Stephen Hemminger
  3 siblings, 2 replies; 27+ messages in thread
From: Stephen Hemminger @ 2019-09-19 12:56 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

A useful feature of netvsc PMD is the ability to see how many packets
were processed through the VF device. This patch set adds a similar
(but more limited) capability to failsafe driver.

Since failsafe doesn't have top level xstats, this set uses the generic
xstats that exist already as a base then adds the sub-device xstats
to that.

v4 - rebase to 19.11-rc
v3 - rebase to 19.08

Stephen Hemminger (2):
  ethdev: expose basic xstats for driver use
  net/failsafe: implement xstats

 drivers/net/failsafe/failsafe_ops.c      | 135 +++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev.c           |  17 ++-
 lib/librte_ethdev/rte_ethdev_driver.h    |  65 +++++++++++
 lib/librte_ethdev/rte_ethdev_version.map |  24 ++++
 4 files changed, 232 insertions(+), 9 deletions(-)

-- 
2.17.1


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

* [dpdk-dev] [PATCH 1/2] ethdev: expose basic xstats for driver use
  2019-09-19 12:56   ` [dpdk-dev] [PATCH v4 0/2] failsafe: add xstats Stephen Hemminger
@ 2019-09-19 12:56     ` Stephen Hemminger
  2019-09-19 12:56     ` [dpdk-dev] [PATCH 2/2] net/failsafe: implement xstats Stephen Hemminger
  1 sibling, 0 replies; 27+ messages in thread
From: Stephen Hemminger @ 2019-09-19 12:56 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Avoid duplication by having generic basic xstats available
for use by drivers. A later patch uses this for failsafe
driver.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_ethdev/rte_ethdev.c           | 17 +++----
 lib/librte_ethdev/rte_ethdev_driver.h    | 65 ++++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev_version.map | 24 +++++++++
 3 files changed, 97 insertions(+), 9 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 17d183e1f0ec..88e3065d06fd 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -1996,8 +1996,8 @@ rte_eth_stats_reset(uint16_t port_id)
 	return 0;
 }
 
-static inline int
-get_xstats_basic_count(struct rte_eth_dev *dev)
+int
+rte_eth_basic_stats_count(struct rte_eth_dev *dev)
 {
 	uint16_t nb_rxqs, nb_txqs;
 	int count;
@@ -2034,7 +2034,7 @@ get_xstats_count(uint16_t port_id)
 		count = 0;
 
 
-	count += get_xstats_basic_count(dev);
+	count += rte_eth_basic_stats_count(dev);
 
 	return count;
 }
@@ -2084,7 +2084,7 @@ rte_eth_xstats_get_id_by_name(uint16_t port_id, const char *xstat_name,
 }
 
 /* retrieve basic stats names */
-static int
+int
 rte_eth_basic_stats_get_names(struct rte_eth_dev *dev,
 	struct rte_eth_xstat_name *xstats_names)
 {
@@ -2140,7 +2140,7 @@ rte_eth_xstats_get_names_by_id(uint16_t port_id,
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
-	basic_count = get_xstats_basic_count(dev);
+	basic_count = rte_eth_basic_stats_count(dev);
 	ret = get_xstats_count(port_id);
 	if (ret < 0)
 		return ret;
@@ -2268,8 +2268,7 @@ rte_eth_xstats_get_names(uint16_t port_id,
 	return cnt_used_entries;
 }
 
-
-static int
+int
 rte_eth_basic_stats_get(uint16_t port_id, struct rte_eth_xstat *xstats)
 {
 	struct rte_eth_dev *dev;
@@ -2341,7 +2340,7 @@ rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids,
 	expected_entries = (uint16_t)ret;
 	struct rte_eth_xstat xstats[expected_entries];
 	dev = &rte_eth_devices[port_id];
-	basic_count = get_xstats_basic_count(dev);
+	basic_count = rte_eth_basic_stats_count(dev);
 
 	/* Return max number of stats if no ids given */
 	if (!ids) {
@@ -2355,7 +2354,7 @@ rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids,
 		return -EINVAL;
 
 	if (ids && dev->dev_ops->xstats_get_by_id != NULL && size) {
-		unsigned int basic_count = get_xstats_basic_count(dev);
+		unsigned int basic_count = rte_eth_basic_stats_count(dev);
 		uint64_t ids_copy[size];
 
 		for (i = 0; i < size; i++) {
diff --git a/lib/librte_ethdev/rte_ethdev_driver.h b/lib/librte_ethdev/rte_ethdev_driver.h
index 936ff8c98651..489889a72203 100644
--- a/lib/librte_ethdev/rte_ethdev_driver.h
+++ b/lib/librte_ethdev/rte_ethdev_driver.h
@@ -208,6 +208,71 @@ rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
 #endif
 }
 
+/**
+ * @internal
+ * Get basic stats part of xstats for an ethernet device.
+ *
+ * @param dev
+ *  Pointer to struct rte_eth_dev.
+ */
+__rte_experimental
+int
+rte_eth_basic_stats_count(struct rte_eth_dev *dev);
+
+/**
+ * @internal
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Retrieve the names for the basic part of extended statistics.
+ *
+ * @param dev
+ *  Pointer to struct rte_eth_dev.
+ * @param xstats_names
+ *   An rte_eth_xstat_name array of at least *size* elements to
+ *   be filled. If set to NULL, the function returns the required number
+ *   of elements.
+ * @return
+ *   - A positive value lower or equal to size: success. The return value
+ *     is the number of entries filled in the stats table.
+ *   - A positive value higher than size: error, the given statistics table
+ *     is too small. The return value corresponds to the size that should
+ *     be given to succeed. The entries in the table are not valid and
+ *     shall not be used by the caller.
+ *   - A negative value on error (invalid port id).
+ */
+__rte_experimental
+int
+rte_eth_basic_stats_get_names(struct rte_eth_dev *dev,
+			      struct rte_eth_xstat_name *xstats_names);
+
+/**
+ * @internal
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Retrieve the basic part of the extended statistics.
+ *
+ * @param dev
+ *  Pointer to struct rte_eth_dev.
+ * @param xstats
+ *   A pointer to a table of structure of type *rte_eth_xstat*
+ *   to be filled with device statistics ids and values.
+ *   This parameter can be set to NULL if n is 0.
+ * @param n
+ *   The size of the xstats array (number of elements).
+ * @return
+ *   - A positive value lower or equal to n: success. The return value
+ *     is the number of entries filled in the stats table.
+ *   - A positive value higher than n: error, the given statistics table
+ *     is too small. The return value corresponds to the size that should
+ *     be given to succeed. The entries in the table are not valid and
+ *     shall not be used by the caller.
+ *   - A negative value on error (invalid port id).
+ */
+__rte_experimental
+int
+rte_eth_basic_stats_get(uint16_t port_id, struct rte_eth_xstat *xstats);
+
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map
index 6df42a47b89d..f2198b0367d1 100644
--- a/lib/librte_ethdev/rte_ethdev_version.map
+++ b/lib/librte_ethdev/rte_ethdev_version.map
@@ -240,6 +240,25 @@ EXPERIMENTAL {
 	global:
 
 	# added in 17.11
+	rte_eth_devargs_parse;
+	rte_eth_dev_create;
+	rte_eth_dev_destroy;
+	rte_eth_dev_get_module_eeprom;
+	rte_eth_dev_get_module_info;
+	rte_eth_dev_is_removed;
+	rte_eth_dev_owner_delete;
+	rte_eth_dev_owner_get;
+	rte_eth_dev_owner_new;
+	rte_eth_dev_owner_set;
+	rte_eth_dev_owner_unset;
+	rte_eth_dev_rx_intr_ctl_q_get_fd;
+	rte_eth_find_next_of;
+	rte_eth_find_next_sibling;
+	rte_eth_read_clock;
+	rte_eth_switch_domain_alloc;
+	rte_eth_switch_domain_free;
+	rte_flow_conv;
+	rte_flow_expand_rss;
 	rte_mtr_capabilities_get;
 	rte_mtr_create;
 	rte_mtr_destroy;
@@ -283,4 +302,9 @@ EXPERIMENTAL {
 
 	# added in 19.08
 	rte_eth_read_clock;
+
+	# added in 19.11
+	rte_eth_basic_stats_count;
+	rte_eth_basic_stats_get;
+	rte_eth_basic_stats_get_names;
 };
-- 
2.17.1


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

* [dpdk-dev] [PATCH 2/2] net/failsafe: implement xstats
  2019-09-19 12:56   ` [dpdk-dev] [PATCH v4 0/2] failsafe: add xstats Stephen Hemminger
  2019-09-19 12:56     ` [dpdk-dev] [PATCH 1/2] ethdev: expose basic xstats for driver use Stephen Hemminger
@ 2019-09-19 12:56     ` Stephen Hemminger
  1 sibling, 0 replies; 27+ messages in thread
From: Stephen Hemminger @ 2019-09-19 12:56 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Add support for extended statistics in failsafe driver.
Reports basic statistics for the failsafe driver, and detailed
statistics for each sub device.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/net/failsafe/failsafe_ops.c | 135 ++++++++++++++++++++++++++++
 1 file changed, 135 insertions(+)

diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
index 96e05d4dc4b1..711fdf302f4f 100644
--- a/drivers/net/failsafe/failsafe_ops.c
+++ b/drivers/net/failsafe/failsafe_ops.c
@@ -789,6 +789,138 @@ fs_stats_reset(struct rte_eth_dev *dev)
 	fs_unlock(dev, 0);
 }
 
+/*
+ * Count how many xstats in total
+ * Include basic stats for failsafe device
+ * plus xstats for each sub-device present.
+ */
+static int
+fs_xstats_count(struct rte_eth_dev *dev)
+{
+	struct sub_device *sdev;
+	uint8_t i;
+	int count;
+
+	count = rte_eth_basic_stats_count(dev);
+
+	fs_lock(dev, 0);
+	FOREACH_SUBDEV(sdev, i, dev) {
+		count += rte_eth_xstats_get_names(PORT_ID(sdev), NULL, 0);
+	}
+	fs_unlock(dev, 0);
+
+	return count;
+}
+
+static int
+fs_xstats_get_names(struct rte_eth_dev *dev,
+		    struct rte_eth_xstat_name *xstats_names,
+		    unsigned int limit)
+{
+	struct sub_device *sdev;
+	unsigned int count;
+	char tmp[RTE_ETH_XSTATS_NAME_SIZE];
+	uint8_t i;
+	int r;
+
+	/* Caller only cares about count */
+	if (!xstats_names)
+		return fs_xstats_count(dev);
+
+	r = rte_eth_basic_stats_get_names(dev, xstats_names);
+	if (r < 0)
+		return r;
+
+	count = r;
+
+	fs_lock(dev, 0);
+	FOREACH_SUBDEV(sdev, i, dev) {
+		struct rte_eth_xstat_name *sub_names = xstats_names + count;
+
+		if (count >= limit)
+			break;
+
+		r = rte_eth_xstats_get_names(PORT_ID(sdev), sub_names,
+					     limit - count);
+		if (r < 0) {
+			fs_unlock(dev, 0);
+			return r;
+		}
+
+		/* add sub_ prefix to names */
+		for (i = 0; i < r; i++) {
+			snprintf(tmp, sizeof(tmp), "sub%u_%s",
+				 i, sub_names[i].name);
+			memcpy(sub_names[i].name, tmp,
+			       RTE_ETH_XSTATS_NAME_SIZE);
+		}
+
+		count += r;
+	}
+	fs_unlock(dev, 0);
+
+	return count;
+}
+
+static int
+fs_xstats_get(struct rte_eth_dev *dev,
+	      struct rte_eth_xstat *xstats,
+	      unsigned int n)
+{
+	unsigned int nstats, j, count, scount;
+	struct sub_device *sdev;
+	uint8_t i;
+	int ret;
+
+	nstats = fs_xstats_count(dev);
+	if (n < nstats || xstats == NULL)
+		return nstats;
+
+	ret = rte_eth_basic_stats_get(dev->data->port_id, xstats);
+	if (ret < 0)
+		return ret;
+
+	count = ret;
+	for (j = 0; j < count; j++)
+		xstats[j].id = j;
+
+	fs_lock(dev, 0);
+	FOREACH_SUBDEV(sdev, i, dev) {
+		ret = rte_eth_xstats_get(PORT_ID(sdev),
+					 xstats + count,
+					 n > count ? n - count : 0);
+		if (ret < 0) {
+			fs_unlock(dev, 0);
+			return ret;
+		}
+		scount = ret;
+
+		/* add offset to id's from sub-device */
+		for (j = 0; j < scount; j++)
+			xstats[count + j].id += count;
+
+		count += scount;
+	}
+	fs_unlock(dev, 0);
+
+	return count;
+}
+
+static void
+fs_xstats_reset(struct rte_eth_dev *dev)
+{
+	struct sub_device *sdev;
+	uint8_t i;
+
+	rte_eth_stats_reset(dev->data->port_id);
+
+	fs_lock(dev, 0);
+	FOREACH_SUBDEV(sdev, i, dev) {
+		rte_eth_xstats_reset(PORT_ID(sdev));
+	}
+	fs_unlock(dev, 0);
+}
+
 static void
 fs_dev_merge_desc_lim(struct rte_eth_desc_lim *to,
 		      const struct rte_eth_desc_lim *from)
@@ -1233,6 +1365,9 @@ const struct eth_dev_ops failsafe_ops = {
 	.link_update = fs_link_update,
 	.stats_get = fs_stats_get,
 	.stats_reset = fs_stats_reset,
+	.xstats_get = fs_xstats_get,
+	.xstats_get_names = fs_xstats_get_names,
+	.xstats_reset = fs_xstats_reset,
 	.dev_infos_get = fs_dev_infos_get,
 	.dev_supported_ptypes_get = fs_dev_supported_ptypes_get,
 	.mtu_set = fs_mtu_set,
-- 
2.17.1


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

* [dpdk-dev] [PATCH v5 0/2] failsafe: add xstats
  2019-08-11 16:06 ` [dpdk-dev] [PATCH v3 0/2] failsafe: " Stephen Hemminger
                     ` (2 preceding siblings ...)
  2019-09-19 12:56   ` [dpdk-dev] [PATCH v4 0/2] failsafe: add xstats Stephen Hemminger
@ 2019-09-19 13:17   ` Stephen Hemminger
  2019-09-19 13:17     ` [dpdk-dev] [PATCH v5 1/2] ethdev: expose basic xstats for driver use Stephen Hemminger
                       ` (2 more replies)
  3 siblings, 3 replies; 27+ messages in thread
From: Stephen Hemminger @ 2019-09-19 13:17 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

A useful feature of netvsc PMD is the ability to see how many
packets
were processed through the VF device. This patch set adds a similar
(but more limited) capability to failsafe driver.

Since failsafe doesn't have top level xstats, this set uses the generic
xstats that exist already as a base then adds the sub-device xstats
to that.

v5 - fix ethdev map file
v4 - rebase to 19.11
v3 - rebase to 19.08

Stephen Hemminger (2):
  ethdev: expose basic xstats for driver use
  net/failsafe: implement xstats

 drivers/net/failsafe/failsafe_ops.c      | 135 +++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev.c           |  17 ++-
 lib/librte_ethdev/rte_ethdev_driver.h    |  65 +++++++++++
 lib/librte_ethdev/rte_ethdev_version.map |   5 +
 4 files changed, 213 insertions(+), 9 deletions(-)

-- 
2.17.1


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

* [dpdk-dev] [PATCH v5 1/2] ethdev: expose basic xstats for driver use
  2019-09-19 13:17   ` [dpdk-dev] [PATCH v5 0/2] failsafe: add xstats Stephen Hemminger
@ 2019-09-19 13:17     ` Stephen Hemminger
  2019-09-26 12:46       ` Andrew Rybchenko
  2019-09-19 13:17     ` [dpdk-dev] [PATCH v5 2/2] net/failsafe: implement xstats Stephen Hemminger
  2019-10-14 17:04     ` [dpdk-dev] [PATCH v5 0/2] failsafe: add xstats Stephen Hemminger
  2 siblings, 1 reply; 27+ messages in thread
From: Stephen Hemminger @ 2019-09-19 13:17 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Avoid duplication by having generic basic xstats available
for use by drivers. A later patch uses this for failsafe
driver.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_ethdev/rte_ethdev.c           | 17 +++----
 lib/librte_ethdev/rte_ethdev_driver.h    | 65 ++++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev_version.map |  5 ++
 3 files changed, 78 insertions(+), 9 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 17d183e1f0ec..88e3065d06fd 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -1996,8 +1996,8 @@ rte_eth_stats_reset(uint16_t port_id)
 	return 0;
 }
 
-static inline int
-get_xstats_basic_count(struct rte_eth_dev *dev)
+int
+rte_eth_basic_stats_count(struct rte_eth_dev *dev)
 {
 	uint16_t nb_rxqs, nb_txqs;
 	int count;
@@ -2034,7 +2034,7 @@ get_xstats_count(uint16_t port_id)
 		count = 0;
 
 
-	count += get_xstats_basic_count(dev);
+	count += rte_eth_basic_stats_count(dev);
 
 	return count;
 }
@@ -2084,7 +2084,7 @@ rte_eth_xstats_get_id_by_name(uint16_t port_id, const char *xstat_name,
 }
 
 /* retrieve basic stats names */
-static int
+int
 rte_eth_basic_stats_get_names(struct rte_eth_dev *dev,
 	struct rte_eth_xstat_name *xstats_names)
 {
@@ -2140,7 +2140,7 @@ rte_eth_xstats_get_names_by_id(uint16_t port_id,
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
-	basic_count = get_xstats_basic_count(dev);
+	basic_count = rte_eth_basic_stats_count(dev);
 	ret = get_xstats_count(port_id);
 	if (ret < 0)
 		return ret;
@@ -2268,8 +2268,7 @@ rte_eth_xstats_get_names(uint16_t port_id,
 	return cnt_used_entries;
 }
 
-
-static int
+int
 rte_eth_basic_stats_get(uint16_t port_id, struct rte_eth_xstat *xstats)
 {
 	struct rte_eth_dev *dev;
@@ -2341,7 +2340,7 @@ rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids,
 	expected_entries = (uint16_t)ret;
 	struct rte_eth_xstat xstats[expected_entries];
 	dev = &rte_eth_devices[port_id];
-	basic_count = get_xstats_basic_count(dev);
+	basic_count = rte_eth_basic_stats_count(dev);
 
 	/* Return max number of stats if no ids given */
 	if (!ids) {
@@ -2355,7 +2354,7 @@ rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids,
 		return -EINVAL;
 
 	if (ids && dev->dev_ops->xstats_get_by_id != NULL && size) {
-		unsigned int basic_count = get_xstats_basic_count(dev);
+		unsigned int basic_count = rte_eth_basic_stats_count(dev);
 		uint64_t ids_copy[size];
 
 		for (i = 0; i < size; i++) {
diff --git a/lib/librte_ethdev/rte_ethdev_driver.h b/lib/librte_ethdev/rte_ethdev_driver.h
index 936ff8c98651..489889a72203 100644
--- a/lib/librte_ethdev/rte_ethdev_driver.h
+++ b/lib/librte_ethdev/rte_ethdev_driver.h
@@ -208,6 +208,71 @@ rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
 #endif
 }
 
+/**
+ * @internal
+ * Get basic stats part of xstats for an ethernet device.
+ *
+ * @param dev
+ *  Pointer to struct rte_eth_dev.
+ */
+__rte_experimental
+int
+rte_eth_basic_stats_count(struct rte_eth_dev *dev);
+
+/**
+ * @internal
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Retrieve the names for the basic part of extended statistics.
+ *
+ * @param dev
+ *  Pointer to struct rte_eth_dev.
+ * @param xstats_names
+ *   An rte_eth_xstat_name array of at least *size* elements to
+ *   be filled. If set to NULL, the function returns the required number
+ *   of elements.
+ * @return
+ *   - A positive value lower or equal to size: success. The return value
+ *     is the number of entries filled in the stats table.
+ *   - A positive value higher than size: error, the given statistics table
+ *     is too small. The return value corresponds to the size that should
+ *     be given to succeed. The entries in the table are not valid and
+ *     shall not be used by the caller.
+ *   - A negative value on error (invalid port id).
+ */
+__rte_experimental
+int
+rte_eth_basic_stats_get_names(struct rte_eth_dev *dev,
+			      struct rte_eth_xstat_name *xstats_names);
+
+/**
+ * @internal
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Retrieve the basic part of the extended statistics.
+ *
+ * @param dev
+ *  Pointer to struct rte_eth_dev.
+ * @param xstats
+ *   A pointer to a table of structure of type *rte_eth_xstat*
+ *   to be filled with device statistics ids and values.
+ *   This parameter can be set to NULL if n is 0.
+ * @param n
+ *   The size of the xstats array (number of elements).
+ * @return
+ *   - A positive value lower or equal to n: success. The return value
+ *     is the number of entries filled in the stats table.
+ *   - A positive value higher than n: error, the given statistics table
+ *     is too small. The return value corresponds to the size that should
+ *     be given to succeed. The entries in the table are not valid and
+ *     shall not be used by the caller.
+ *   - A negative value on error (invalid port id).
+ */
+__rte_experimental
+int
+rte_eth_basic_stats_get(uint16_t port_id, struct rte_eth_xstat *xstats);
+
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map
index 6df42a47b89d..df7e83a90603 100644
--- a/lib/librte_ethdev/rte_ethdev_version.map
+++ b/lib/librte_ethdev/rte_ethdev_version.map
@@ -283,4 +283,9 @@ EXPERIMENTAL {
 
 	# added in 19.08
 	rte_eth_read_clock;
+
+	# added in 19.11
+	rte_eth_basic_stats_count;
+	rte_eth_basic_stats_get;
+	rte_eth_basic_stats_get_names;
 };
-- 
2.17.1


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

* [dpdk-dev] [PATCH v5 2/2] net/failsafe: implement xstats
  2019-09-19 13:17   ` [dpdk-dev] [PATCH v5 0/2] failsafe: add xstats Stephen Hemminger
  2019-09-19 13:17     ` [dpdk-dev] [PATCH v5 1/2] ethdev: expose basic xstats for driver use Stephen Hemminger
@ 2019-09-19 13:17     ` Stephen Hemminger
  2019-10-17 14:54       ` Ferruh Yigit
  2019-10-14 17:04     ` [dpdk-dev] [PATCH v5 0/2] failsafe: add xstats Stephen Hemminger
  2 siblings, 1 reply; 27+ messages in thread
From: Stephen Hemminger @ 2019-09-19 13:17 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Add support for extended statistics in failsafe driver.
Reports basic statistics for the failsafe driver, and detailed
statistics for each sub device.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/net/failsafe/failsafe_ops.c | 135 ++++++++++++++++++++++++++++
 1 file changed, 135 insertions(+)

diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
index 96e05d4dc4b1..711fdf302f4f 100644
--- a/drivers/net/failsafe/failsafe_ops.c
+++ b/drivers/net/failsafe/failsafe_ops.c
@@ -789,6 +789,138 @@ fs_stats_reset(struct rte_eth_dev *dev)
 	fs_unlock(dev, 0);
 }
 
+/*
+ * Count how many xstats in total
+ * Include basic stats for failsafe device
+ * plus xstats for each sub-device present.
+ */
+static int
+fs_xstats_count(struct rte_eth_dev *dev)
+{
+	struct sub_device *sdev;
+	uint8_t i;
+	int count;
+
+	count = rte_eth_basic_stats_count(dev);
+
+	fs_lock(dev, 0);
+	FOREACH_SUBDEV(sdev, i, dev) {
+		count += rte_eth_xstats_get_names(PORT_ID(sdev), NULL, 0);
+	}
+	fs_unlock(dev, 0);
+
+	return count;
+}
+
+static int
+fs_xstats_get_names(struct rte_eth_dev *dev,
+		    struct rte_eth_xstat_name *xstats_names,
+		    unsigned int limit)
+{
+	struct sub_device *sdev;
+	unsigned int count;
+	char tmp[RTE_ETH_XSTATS_NAME_SIZE];
+	uint8_t i;
+	int r;
+
+	/* Caller only cares about count */
+	if (!xstats_names)
+		return fs_xstats_count(dev);
+
+	r = rte_eth_basic_stats_get_names(dev, xstats_names);
+	if (r < 0)
+		return r;
+
+	count = r;
+
+	fs_lock(dev, 0);
+	FOREACH_SUBDEV(sdev, i, dev) {
+		struct rte_eth_xstat_name *sub_names = xstats_names + count;
+
+		if (count >= limit)
+			break;
+
+		r = rte_eth_xstats_get_names(PORT_ID(sdev), sub_names,
+					     limit - count);
+		if (r < 0) {
+			fs_unlock(dev, 0);
+			return r;
+		}
+
+		/* add sub_ prefix to names */
+		for (i = 0; i < r; i++) {
+			snprintf(tmp, sizeof(tmp), "sub%u_%s",
+				 i, sub_names[i].name);
+			memcpy(sub_names[i].name, tmp,
+			       RTE_ETH_XSTATS_NAME_SIZE);
+		}
+
+		count += r;
+	}
+	fs_unlock(dev, 0);
+
+	return count;
+}
+
+static int
+fs_xstats_get(struct rte_eth_dev *dev,
+	      struct rte_eth_xstat *xstats,
+	      unsigned int n)
+{
+	unsigned int nstats, j, count, scount;
+	struct sub_device *sdev;
+	uint8_t i;
+	int ret;
+
+	nstats = fs_xstats_count(dev);
+	if (n < nstats || xstats == NULL)
+		return nstats;
+
+	ret = rte_eth_basic_stats_get(dev->data->port_id, xstats);
+	if (ret < 0)
+		return ret;
+
+	count = ret;
+	for (j = 0; j < count; j++)
+		xstats[j].id = j;
+
+	fs_lock(dev, 0);
+	FOREACH_SUBDEV(sdev, i, dev) {
+		ret = rte_eth_xstats_get(PORT_ID(sdev),
+					 xstats + count,
+					 n > count ? n - count : 0);
+		if (ret < 0) {
+			fs_unlock(dev, 0);
+			return ret;
+		}
+		scount = ret;
+
+		/* add offset to id's from sub-device */
+		for (j = 0; j < scount; j++)
+			xstats[count + j].id += count;
+
+		count += scount;
+	}
+	fs_unlock(dev, 0);
+
+	return count;
+}
+
+static void
+fs_xstats_reset(struct rte_eth_dev *dev)
+{
+	struct sub_device *sdev;
+	uint8_t i;
+
+	rte_eth_stats_reset(dev->data->port_id);
+
+	fs_lock(dev, 0);
+	FOREACH_SUBDEV(sdev, i, dev) {
+		rte_eth_xstats_reset(PORT_ID(sdev));
+	}
+	fs_unlock(dev, 0);
+}
+
 static void
 fs_dev_merge_desc_lim(struct rte_eth_desc_lim *to,
 		      const struct rte_eth_desc_lim *from)
@@ -1233,6 +1365,9 @@ const struct eth_dev_ops failsafe_ops = {
 	.link_update = fs_link_update,
 	.stats_get = fs_stats_get,
 	.stats_reset = fs_stats_reset,
+	.xstats_get = fs_xstats_get,
+	.xstats_get_names = fs_xstats_get_names,
+	.xstats_reset = fs_xstats_reset,
 	.dev_infos_get = fs_dev_infos_get,
 	.dev_supported_ptypes_get = fs_dev_supported_ptypes_get,
 	.mtu_set = fs_mtu_set,
-- 
2.17.1


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

* Re: [dpdk-dev] [PATCH v5 1/2] ethdev: expose basic xstats for driver use
  2019-09-19 13:17     ` [dpdk-dev] [PATCH v5 1/2] ethdev: expose basic xstats for driver use Stephen Hemminger
@ 2019-09-26 12:46       ` Andrew Rybchenko
  2019-09-26 16:09         ` Stephen Hemminger
  0 siblings, 1 reply; 27+ messages in thread
From: Andrew Rybchenko @ 2019-09-26 12:46 UTC (permalink / raw)
  To: Stephen Hemminger, dev

On 9/19/19 4:17 PM, Stephen Hemminger wrote:
> Avoid duplication by having generic basic xstats available
> for use by drivers. A later patch uses this for failsafe
> driver.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> Acked-by: Gaetan Rivet <gaetan.rivet@6wind.com>

Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>

> diff --git a/lib/librte_ethdev/rte_ethdev_driver.h b/lib/librte_ethdev/rte_ethdev_driver.h
> index 936ff8c98651..489889a72203 100644
> --- a/lib/librte_ethdev/rte_ethdev_driver.h
> +++ b/lib/librte_ethdev/rte_ethdev_driver.h
> @@ -208,6 +208,71 @@ rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
>   #endif
>   }
>   
> +/**
> + * @internal
> + * Get basic stats part of xstats for an ethernet device.
> + *
> + * @param dev
> + *  Pointer to struct rte_eth_dev.
> + */
> +__rte_experimental

Does it make sense to mark internal API as experimental?
I thought that @internal is not a part of API/ABI.

[snip]


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

* Re: [dpdk-dev] [PATCH v5 1/2] ethdev: expose basic xstats for driver use
  2019-09-26 12:46       ` Andrew Rybchenko
@ 2019-09-26 16:09         ` Stephen Hemminger
  0 siblings, 0 replies; 27+ messages in thread
From: Stephen Hemminger @ 2019-09-26 16:09 UTC (permalink / raw)
  To: Andrew Rybchenko; +Cc: dev

On Thu, 26 Sep 2019 15:46:52 +0300
Andrew Rybchenko <arybchenko@solarflare.com> wrote:

> On 9/19/19 4:17 PM, Stephen Hemminger wrote:
> > Avoid duplication by having generic basic xstats available
> > for use by drivers. A later patch uses this for failsafe
> > driver.
> >
> > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> > Acked-by: Gaetan Rivet <gaetan.rivet@6wind.com>  
> 
> Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
> 
> > diff --git a/lib/librte_ethdev/rte_ethdev_driver.h b/lib/librte_ethdev/rte_ethdev_driver.h
> > index 936ff8c98651..489889a72203 100644
> > --- a/lib/librte_ethdev/rte_ethdev_driver.h
> > +++ b/lib/librte_ethdev/rte_ethdev_driver.h
> > @@ -208,6 +208,71 @@ rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
> >   #endif
> >   }
> >   
> > +/**
> > + * @internal
> > + * Get basic stats part of xstats for an ethernet device.
> > + *
> > + * @param dev
> > + *  Pointer to struct rte_eth_dev.
> > + */
> > +__rte_experimental  
> 
> Does it make sense to mark internal API as experimental?
> I thought that @internal is not a part of API/ABI.

agree, but checkpatch doesn't understand @internal tag.

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

* Re: [dpdk-dev] [PATCH v5 0/2] failsafe: add xstats
  2019-09-19 13:17   ` [dpdk-dev] [PATCH v5 0/2] failsafe: add xstats Stephen Hemminger
  2019-09-19 13:17     ` [dpdk-dev] [PATCH v5 1/2] ethdev: expose basic xstats for driver use Stephen Hemminger
  2019-09-19 13:17     ` [dpdk-dev] [PATCH v5 2/2] net/failsafe: implement xstats Stephen Hemminger
@ 2019-10-14 17:04     ` Stephen Hemminger
  2019-10-15  9:08       ` Ferruh Yigit
  2 siblings, 1 reply; 27+ messages in thread
From: Stephen Hemminger @ 2019-10-14 17:04 UTC (permalink / raw)
  To: dev

On Thu, 19 Sep 2019 15:17:27 +0200
Stephen Hemminger <stephen@networkplumber.org> wrote:

> A useful feature of netvsc PMD is the ability to see how many
> packets
> were processed through the VF device. This patch set adds a similar
> (but more limited) capability to failsafe driver.
> 
> Since failsafe doesn't have top level xstats, this set uses the generic
> xstats that exist already as a base then adds the sub-device xstats
> to that.
> 
> v5 - fix ethdev map file
> v4 - rebase to 19.11
> v3 - rebase to 19.08
> 
> Stephen Hemminger (2):
>   ethdev: expose basic xstats for driver use
>   net/failsafe: implement xstats
> 
>  drivers/net/failsafe/failsafe_ops.c      | 135 +++++++++++++++++++++++
>  lib/librte_ethdev/rte_ethdev.c           |  17 ++-
>  lib/librte_ethdev/rte_ethdev_driver.h    |  65 +++++++++++
>  lib/librte_ethdev/rte_ethdev_version.map |   5 +
>  4 files changed, 213 insertions(+), 9 deletions(-)
> 

Why are these patches still not merged?

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

* Re: [dpdk-dev] [PATCH v5 0/2] failsafe: add xstats
  2019-10-14 17:04     ` [dpdk-dev] [PATCH v5 0/2] failsafe: add xstats Stephen Hemminger
@ 2019-10-15  9:08       ` Ferruh Yigit
  0 siblings, 0 replies; 27+ messages in thread
From: Ferruh Yigit @ 2019-10-15  9:08 UTC (permalink / raw)
  To: Stephen Hemminger, dev

On 10/14/2019 6:04 PM, Stephen Hemminger wrote:
> On Thu, 19 Sep 2019 15:17:27 +0200
> Stephen Hemminger <stephen@networkplumber.org> wrote:
> 
>> A useful feature of netvsc PMD is the ability to see how many
>> packets
>> were processed through the VF device. This patch set adds a similar
>> (but more limited) capability to failsafe driver.
>>
>> Since failsafe doesn't have top level xstats, this set uses the generic
>> xstats that exist already as a base then adds the sub-device xstats
>> to that.
>>
>> v5 - fix ethdev map file
>> v4 - rebase to 19.11
>> v3 - rebase to 19.08
>>
>> Stephen Hemminger (2):
>>   ethdev: expose basic xstats for driver use
>>   net/failsafe: implement xstats
>>
>>  drivers/net/failsafe/failsafe_ops.c      | 135 +++++++++++++++++++++++
>>  lib/librte_ethdev/rte_ethdev.c           |  17 ++-
>>  lib/librte_ethdev/rte_ethdev_driver.h    |  65 +++++++++++
>>  lib/librte_ethdev/rte_ethdev_version.map |   5 +
>>  4 files changed, 213 insertions(+), 9 deletions(-)
>>
> 
> Why are these patches still not merged?
> 

Because patches are not reviewed yet, specially ethdev one.

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

* Re: [dpdk-dev] [PATCH v5 2/2] net/failsafe: implement xstats
  2019-09-19 13:17     ` [dpdk-dev] [PATCH v5 2/2] net/failsafe: implement xstats Stephen Hemminger
@ 2019-10-17 14:54       ` Ferruh Yigit
  0 siblings, 0 replies; 27+ messages in thread
From: Ferruh Yigit @ 2019-10-17 14:54 UTC (permalink / raw)
  To: Stephen Hemminger, dev; +Cc: Andrew Rybchenko, Gaetan Rivet

On 9/19/2019 2:17 PM, Stephen Hemminger wrote:
> Add support for extended statistics in failsafe driver.
> Reports basic statistics for the failsafe driver, and detailed
> statistics for each sub device.

+1, but doesn't need to pull basic stats to the xstats in the PMD level, that
part is already done by xstats API [1],
so 'fs_xstats_get.*()' functions return only sub-device basic stats is good
enough which won't require the new 'rte_eth_basic_stats_.*()' APIs.

Current implementation cause basic stats part duplicated for failsafe device.

[1]
rte_eth_xstats_get_names
  cnt_used_entries = rte_eth_basic_stats_get_names(dev, xstats_names)
  cnt_driver_entries = (*dev->dev_ops->xstats_get_names)(...)
  cnt_used_entries += cnt_driver_entries
  return cnt_used_entries;


btw, while testing this I have observed an always reproducible seg fault by
failsafe on testpmd quit [2], but didn't checked more, @Gaetan can you please
check this when possible?


[2]
Shutting down port 1...
Closing ports...
Done
Segmentation fault (core dumped)

With command:
testpmd -w 0:0.0 --vdev net_null0 --vdev
"net_failsafe0,dev(86:00.1),dev(86:00.3)" -- -i


> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> Acked-by: Gaetan Rivet <gaetan.rivet@6wind.com>

<...>

> +static int
> +fs_xstats_get_names(struct rte_eth_dev *dev,
> +		    struct rte_eth_xstat_name *xstats_names,
> +		    unsigned int limit)
> +{
> +	struct sub_device *sdev;
> +	unsigned int count;
> +	char tmp[RTE_ETH_XSTATS_NAME_SIZE];
> +	uint8_t i;
> +	int r;
> +
> +	/* Caller only cares about count */
> +	if (!xstats_names)
> +		return fs_xstats_count(dev);
> +
> +	r = rte_eth_basic_stats_get_names(dev, xstats_names);
> +	if (r < 0)
> +		return r;
> +
> +	count = r;
> +
> +	fs_lock(dev, 0);
> +	FOREACH_SUBDEV(sdev, i, dev) {
> +		struct rte_eth_xstat_name *sub_names = xstats_names + count;
> +
> +		if (count >= limit)
> +			break;
> +
> +		r = rte_eth_xstats_get_names(PORT_ID(sdev), sub_names,
> +					     limit - count);
> +		if (r < 0) {
> +			fs_unlock(dev, 0);
> +			return r;
> +		}
> +
> +		/* add sub_ prefix to names */
> +		for (i = 0; i < r; i++) {

'i' is used in outer loop as well
thanks to 'C' to let us do these kind of things without any kind of warning.
Also it shows maintainer acked without testing :(

> +			snprintf(tmp, sizeof(tmp), "sub%u_%s",
> +				 i, sub_names[i].name);
> +			memcpy(sub_names[i].name, tmp,
> +			       RTE_ETH_XSTATS_NAME_SIZE);
> +		}
> +
> +		count += r;
> +	}
> +	fs_unlock(dev, 0);
> +
> +	return count;
> +}

<...>

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

end of thread, back to index

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-26 22:21 [dpdk-dev] [PATCH 0/2] failsafe: add xstats Stephen Hemminger
2019-06-26 22:21 ` [dpdk-dev] [PATCH 1/2] ethdev: expose basic xstats for driver use Stephen Hemminger
2019-06-26 22:21 ` [dpdk-dev] [PATCH 2/2] failsafe: implement xstats Stephen Hemminger
2019-06-26 23:33 ` [dpdk-dev] [PATCH v2 0/2] failsafe: add xstats Stephen Hemminger
2019-06-26 23:33   ` [dpdk-dev] [PATCH v2 1/2] ethdev: expose basic xstats for driver use Stephen Hemminger
2019-07-01 10:54     ` Andrew Rybchenko
2019-07-01 14:59       ` Stephen Hemminger
2019-06-26 23:33   ` [dpdk-dev] [PATCH v2 2/2] failsafe: implement xstats Stephen Hemminger
2019-07-01 12:33     ` Gaëtan Rivet
2019-07-03 17:25 ` [dpdk-dev] [PATCH v2 0/2] *failsafe: add xstats Stephen Hemminger
2019-07-03 17:25   ` [dpdk-dev] [PATCH v2 1/2] ethdev: expose basic xstats for driver use Stephen Hemminger
2019-07-03 17:25   ` [dpdk-dev] [PATCH v2 2/2] failsafe: implement xstats Stephen Hemminger
2019-07-04  9:56   ` [dpdk-dev] [PATCH v2 0/2] *failsafe: add xstats Gaëtan Rivet
2019-08-11 16:06 ` [dpdk-dev] [PATCH v3 0/2] failsafe: " Stephen Hemminger
2019-08-11 16:06   ` [dpdk-dev] [PATCH v3 1/2] ethdev: expose basic xstats for driver use Stephen Hemminger
2019-08-11 16:06   ` [dpdk-dev] [PATCH v3 2/2] net/failsafe: implement xstats Stephen Hemminger
2019-09-19 12:56   ` [dpdk-dev] [PATCH v4 0/2] failsafe: add xstats Stephen Hemminger
2019-09-19 12:56     ` [dpdk-dev] [PATCH 1/2] ethdev: expose basic xstats for driver use Stephen Hemminger
2019-09-19 12:56     ` [dpdk-dev] [PATCH 2/2] net/failsafe: implement xstats Stephen Hemminger
2019-09-19 13:17   ` [dpdk-dev] [PATCH v5 0/2] failsafe: add xstats Stephen Hemminger
2019-09-19 13:17     ` [dpdk-dev] [PATCH v5 1/2] ethdev: expose basic xstats for driver use Stephen Hemminger
2019-09-26 12:46       ` Andrew Rybchenko
2019-09-26 16:09         ` Stephen Hemminger
2019-09-19 13:17     ` [dpdk-dev] [PATCH v5 2/2] net/failsafe: implement xstats Stephen Hemminger
2019-10-17 14:54       ` Ferruh Yigit
2019-10-14 17:04     ` [dpdk-dev] [PATCH v5 0/2] failsafe: add xstats Stephen Hemminger
2019-10-15  9:08       ` Ferruh Yigit

DPDK-dev Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/dpdk-dev/0 dpdk-dev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 dpdk-dev dpdk-dev/ https://lore.kernel.org/dpdk-dev \
		dev@dpdk.org dpdk-dev@archiver.kernel.org
	public-inbox-index dpdk-dev

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.dpdk.dev


AGPL code for this site: git clone https://public-inbox.org/ public-inbox