summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Hemminger <stephen@networkplumber.org>2019-11-01 13:12:56 -0700
committerFerruh Yigit <ferruh.yigit@intel.com>2019-11-11 14:23:02 +0100
commit938420ebd1ca42060e89c970bc94a38843f724f1 (patch)
treec8a8b96928f3cc187168c42e6582370345c7760f
parentbd67b6772492cdd9f7249bdff7163e9698bdcc16 (diff)
downloaddpdk-938420ebd1ca42060e89c970bc94a38843f724f1.zip
dpdk-938420ebd1ca42060e89c970bc94a38843f724f1.tar.gz
dpdk-938420ebd1ca42060e89c970bc94a38843f724f1.tar.xz
net/failsafe: support xstats
Add support for extended statistics in failsafe driver. Reports detailed statistics for each sub device. Example: testpmd> show port xstats 1 rx_good_packets: 0 tx_good_packets: 0 rx_good_bytes: 0 tx_good_bytes: 0 rx_missed_errors: 0 rx_errors: 0 tx_errors: 0 rx_mbuf_allocation_errors: 0 rx_q0packets: 0 rx_q0bytes: 0 rx_q0errors: 0 tx_q0packets: 0 tx_q0bytes: 0 rx_sub0_good_packets: 0 tx_sub0_good_packets: 0 ... rx_sub1_good_packets: 0 tx_sub1_good_packets: 0 rx_sub1_good_bytes: 0 Signed-off-by: Stephen Hemminger <stephen@networkplumber.org> Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
-rw-r--r--drivers/net/failsafe/failsafe_ops.c152
1 files changed, 152 insertions, 0 deletions
diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
index 0afae6c..a87e49b 100644
--- a/drivers/net/failsafe/failsafe_ops.c
+++ b/drivers/net/failsafe/failsafe_ops.c
@@ -14,6 +14,7 @@
#include <rte_flow.h>
#include <rte_cycles.h>
#include <rte_ethdev.h>
+#include <rte_string_fns.h>
#include "failsafe_private.h"
@@ -881,6 +882,154 @@ fs_stats_reset(struct rte_eth_dev *dev)
return 0;
}
+static int
+__fs_xstats_count(struct rte_eth_dev *dev)
+{
+ struct sub_device *sdev;
+ int count = 0;
+ uint8_t i;
+ int ret;
+
+ FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
+ ret = rte_eth_xstats_get_names(PORT_ID(sdev), NULL, 0);
+ if (ret < 0)
+ return ret;
+ count += ret;
+ }
+
+ 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 = 0;
+ uint8_t i;
+
+ /* Caller only cares about count */
+ if (!xstats_names)
+ return __fs_xstats_count(dev);
+
+ FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
+ struct rte_eth_xstat_name *sub_names = xstats_names + count;
+ int j, r;
+
+ if (count >= limit)
+ break;
+
+ r = rte_eth_xstats_get_names(PORT_ID(sdev),
+ sub_names, limit - count);
+ if (r < 0)
+ return r;
+
+ /* add subN_ prefix to names */
+ for (j = 0; j < r; j++) {
+ char *xname = sub_names[j].name;
+ char tmp[RTE_ETH_XSTATS_NAME_SIZE];
+
+ if ((xname[0] == 't' || xname[0] == 'r') &&
+ xname[1] == 'x' && xname[2] == '_')
+ snprintf(tmp, sizeof(tmp), "%.3ssub%u_%s",
+ xname, i, xname + 3);
+ else
+ snprintf(tmp, sizeof(tmp), "sub%u_%s",
+ i, xname);
+
+ strlcpy(xname, tmp, RTE_ETH_XSTATS_NAME_SIZE);
+ }
+ count += r;
+ }
+ return count;
+}
+
+static int
+fs_xstats_get_names(struct rte_eth_dev *dev,
+ struct rte_eth_xstat_name *xstats_names,
+ unsigned int limit)
+{
+ int ret;
+
+ fs_lock(dev, 0);
+ ret = __fs_xstats_get_names(dev, xstats_names, limit);
+ fs_unlock(dev, 0);
+ return ret;
+}
+
+static int
+__fs_xstats_get(struct rte_eth_dev *dev,
+ struct rte_eth_xstat *xstats,
+ unsigned int n)
+{
+ unsigned int count = 0;
+ struct sub_device *sdev;
+ uint8_t i;
+ int j, ret;
+
+ ret = __fs_xstats_count(dev);
+ /*
+ * if error
+ * or caller did not give enough space
+ * or just querying
+ */
+ if (ret < 0 || ret > (int)n || xstats == NULL)
+ return ret;
+
+ FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
+ ret = rte_eth_xstats_get(PORT_ID(sdev), xstats, n);
+ if (ret < 0)
+ return ret;
+
+ if (ret > (int)n)
+ return n + count;
+
+ /* add offset to id's from sub-device */
+ for (j = 0; j < ret; j++)
+ xstats[j].id += count;
+
+ xstats += ret;
+ n -= ret;
+ count += ret;
+ }
+
+ return count;
+}
+
+static int
+fs_xstats_get(struct rte_eth_dev *dev,
+ struct rte_eth_xstat *xstats,
+ unsigned int n)
+{
+ int ret;
+
+ fs_lock(dev, 0);
+ ret = __fs_xstats_get(dev, xstats, n);
+ fs_unlock(dev, 0);
+
+ return ret;
+}
+
+
+static int
+fs_xstats_reset(struct rte_eth_dev *dev)
+{
+ struct sub_device *sdev;
+ uint8_t i;
+ int r = 0;
+
+ fs_lock(dev, 0);
+ FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
+ r = rte_eth_xstats_reset(PORT_ID(sdev));
+ if (r < 0)
+ break;
+ }
+ fs_unlock(dev, 0);
+
+ return r;
+}
+
static void
fs_dev_merge_desc_lim(struct rte_eth_desc_lim *to,
const struct rte_eth_desc_lim *from)
@@ -1331,6 +1480,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,