From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <kevin.laatz@intel.com>
Received: from mga04.intel.com (mga04.intel.com [192.55.52.120])
 by dpdk.org (Postfix) with ESMTP id 7ED5C58C4
 for <dev@dpdk.org>; Mon, 22 Oct 2018 13:00:19 +0200 (CEST)
X-Amp-Result: SKIPPED(no attachment in message)
X-Amp-File-Uploaded: False
Received: from orsmga005.jf.intel.com ([10.7.209.41])
 by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;
 22 Oct 2018 04:00:19 -0700
X-ExtLoop1: 1
X-IronPort-AV: E=Sophos;i="5.54,412,1534834800"; d="scan'208";a="267735487"
Received: from silpixa00397517.ir.intel.com (HELO
 silpixa00397517.ger.corp.intel.com) ([10.237.222.54])
 by orsmga005.jf.intel.com with ESMTP; 22 Oct 2018 04:00:16 -0700
From: Kevin Laatz <kevin.laatz@intel.com>
To: dev@dpdk.org
Cc: harry.van.haaren@intel.com, stephen@networkplumber.org,
 gaetan.rivet@6wind.com, shreyansh.jain@nxp.com, thomas@monjalon.net,
 mattias.ronnblom@ericsson.com, bruce.richardson@intel.com,
 Ciara Power <ciara.power@intel.com>,
 Brian Archbold <brian.archbold@intel.com>,
 Kevin Laatz <kevin.laatz@intel.com>
Date: Mon, 22 Oct 2018 12:00:08 +0100
Message-Id: <20181022110014.82153-8-kevin.laatz@intel.com>
X-Mailer: git-send-email 2.9.5
In-Reply-To: <20181022110014.82153-1-kevin.laatz@intel.com>
References: <20181016155802.2067-1-kevin.laatz@intel.com>
 <20181022110014.82153-1-kevin.laatz@intel.com>
Subject: [dpdk-dev] [PATCH v6 07/13] telemetry: update metrics before
	sending stats
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
X-List-Received-Date: Mon, 22 Oct 2018 11:00:20 -0000

From: Ciara Power <ciara.power@intel.com>

This patch adds functionality to update the statistics in
the metrics library with values from the ethdev stats.

Values need to be updated before they are encoded into a JSON
message and sent to the client that requested them. The JSON encoding
will be added in a subsequent patch.

Signed-off-by: Ciara Power <ciara.power@intel.com>
Signed-off-by: Brian Archbold <brian.archbold@intel.com>
Signed-off-by: Kevin Laatz <kevin.laatz@intel.com>
Acked-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 lib/librte_telemetry/rte_telemetry.c          | 134 ++++++++++++++++++++++++++
 lib/librte_telemetry/rte_telemetry_internal.h |   4 +
 lib/librte_telemetry/rte_telemetry_parser.c   |  17 ++++
 3 files changed, 155 insertions(+)

diff --git a/lib/librte_telemetry/rte_telemetry.c b/lib/librte_telemetry/rte_telemetry.c
index 76d92e9..cd97a6e 100644
--- a/lib/librte_telemetry/rte_telemetry.c
+++ b/lib/librte_telemetry/rte_telemetry.c
@@ -46,6 +46,78 @@ rte_telemetry_is_port_active(int port_id)
 	return 0;
 }
 
+static int32_t
+rte_telemetry_update_metrics_ethdev(struct telemetry_impl *telemetry,
+	uint16_t port_id, int reg_start_index)
+{
+	int ret, num_xstats, i;
+	struct rte_eth_xstat *eth_xstats;
+
+	if (!rte_eth_dev_is_valid_port(port_id)) {
+		TELEMETRY_LOG_ERR("port_id: %d is invalid", port_id);
+		ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
+		if (ret < 0)
+			TELEMETRY_LOG_ERR("Could not send error");
+		return -1;
+	}
+
+	ret = rte_telemetry_is_port_active(port_id);
+	if (ret < 1) {
+		ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
+		if (ret < 0)
+			TELEMETRY_LOG_ERR("Could not send error");
+		return -1;
+	}
+
+	num_xstats = rte_eth_xstats_get(port_id, NULL, 0);
+	if (num_xstats < 0) {
+		TELEMETRY_LOG_ERR("rte_eth_xstats_get(%u) failed: %d", port_id,
+				num_xstats);
+		ret = rte_telemetry_send_error_response(telemetry, -EPERM);
+		if (ret < 0)
+			TELEMETRY_LOG_ERR("Could not send error");
+		return -1;
+	}
+
+	eth_xstats = malloc(sizeof(struct rte_eth_xstat) * num_xstats);
+	if (eth_xstats == NULL) {
+		TELEMETRY_LOG_ERR("Failed to malloc memory for xstats");
+		ret = rte_telemetry_send_error_response(telemetry, -ENOMEM);
+		if (ret < 0)
+			TELEMETRY_LOG_ERR("Could not send error");
+		return -1;
+	}
+
+	ret = rte_eth_xstats_get(port_id, eth_xstats, num_xstats);
+	if (ret < 0 || ret > num_xstats) {
+		free(eth_xstats);
+		TELEMETRY_LOG_ERR("rte_eth_xstats_get(%u) len%i failed: %d",
+				port_id, num_xstats, ret);
+		ret = rte_telemetry_send_error_response(telemetry, -EPERM);
+		if (ret < 0)
+			TELEMETRY_LOG_ERR("Could not send error");
+		return -1;
+	}
+
+	uint64_t xstats_values[num_xstats];
+	for (i = 0; i < num_xstats; i++)
+		xstats_values[i] = eth_xstats[i].value;
+
+	ret = rte_metrics_update_values(port_id, reg_start_index, xstats_values,
+			num_xstats);
+	if (ret < 0) {
+		TELEMETRY_LOG_ERR("Could not update metrics values");
+		ret = rte_telemetry_send_error_response(telemetry, -EPERM);
+		if (ret < 0)
+			TELEMETRY_LOG_ERR("Could not send error");
+		free(eth_xstats);
+		return -1;
+	}
+
+	free(eth_xstats);
+	return 0;
+}
+
 int32_t
 rte_telemetry_write_to_socket(struct telemetry_impl *telemetry,
 	const char *json_string)
@@ -130,6 +202,68 @@ rte_telemetry_send_error_response(struct telemetry_impl *telemetry,
 	return 0;
 }
 
+int32_t
+rte_telemetry_send_ports_stats_values(uint32_t *metric_ids, int num_metric_ids,
+	uint32_t *port_ids, int num_port_ids, struct telemetry_impl *telemetry)
+{
+	int ret, i;
+	char *json_buffer = NULL;
+
+	if (telemetry == NULL) {
+		TELEMETRY_LOG_ERR("Invalid telemetry argument");
+		return -1;
+	}
+
+	if (metric_ids == NULL) {
+		TELEMETRY_LOG_ERR("Invalid metric_ids array");
+		goto einval_fail;
+	}
+
+	if (num_metric_ids < 0) {
+		TELEMETRY_LOG_ERR("Invalid num_metric_ids, must be positive");
+		goto einval_fail;
+	}
+
+	if (port_ids == NULL) {
+		TELEMETRY_LOG_ERR("Invalid port_ids array");
+		goto einval_fail;
+	}
+
+	if (num_port_ids < 0) {
+		TELEMETRY_LOG_ERR("Invalid num_port_ids, must be positive");
+		goto einval_fail;
+	}
+
+	for (i = 0; i < num_port_ids; i++) {
+		if (!rte_eth_dev_is_valid_port(port_ids[i])) {
+			TELEMETRY_LOG_ERR("Port: %d invalid", port_ids[i]);
+			goto einval_fail;
+		}
+
+		ret = rte_telemetry_update_metrics_ethdev(telemetry,
+			port_ids[i], telemetry->reg_index);
+		if (ret < 0) {
+			TELEMETRY_LOG_ERR("Failed to update ethdev metrics");
+			return -1;
+		}
+	}
+
+	ret = rte_telemetry_write_to_socket(telemetry, json_buffer);
+	if (ret < 0) {
+		TELEMETRY_LOG_ERR("Could not write to socket");
+		return -1;
+	}
+
+	return 0;
+
+einval_fail:
+	ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
+	if (ret < 0)
+		TELEMETRY_LOG_ERR("Could not send error");
+	return -1;
+}
+
+
 static int32_t
 rte_telemetry_reg_ethdev_to_metrics(uint16_t port_id)
 {
diff --git a/lib/librte_telemetry/rte_telemetry_internal.h b/lib/librte_telemetry/rte_telemetry_internal.h
index 86a5ba1..0082cb2 100644
--- a/lib/librte_telemetry/rte_telemetry_internal.h
+++ b/lib/librte_telemetry/rte_telemetry_internal.h
@@ -71,4 +71,8 @@ rte_telemetry_unregister_client(struct telemetry_impl *telemetry,
 int32_t
 rte_telemetry_is_port_active(int port_id);
 
+int32_t
+rte_telemetry_send_ports_stats_values(uint32_t *metric_ids, int num_metric_ids,
+	uint32_t *port_ids, int num_port_ids, struct telemetry_impl *telemetry);
+
 #endif
diff --git a/lib/librte_telemetry/rte_telemetry_parser.c b/lib/librte_telemetry/rte_telemetry_parser.c
index 6bc4c6d..084c160 100644
--- a/lib/librte_telemetry/rte_telemetry_parser.c
+++ b/lib/librte_telemetry/rte_telemetry_parser.c
@@ -258,6 +258,7 @@ rte_telemetry_command_ports_all_stat_values(struct telemetry_impl *telemetry,
 	int ret, num_metrics, i, p;
 	struct rte_metric_name *names;
 	uint64_t num_port_ids = 0;
+	uint32_t port_ids[RTE_MAX_ETHPORTS];
 
 	if (telemetry == NULL) {
 		TELEMETRY_LOG_ERR("Invalid telemetry argument");
@@ -313,6 +314,7 @@ rte_telemetry_command_ports_all_stat_values(struct telemetry_impl *telemetry,
 	uint32_t stat_ids[num_metrics];
 
 	RTE_ETH_FOREACH_DEV(p) {
+		port_ids[num_port_ids] = p;
 		num_port_ids++;
 	}
 
@@ -337,6 +339,13 @@ rte_telemetry_command_ports_all_stat_values(struct telemetry_impl *telemetry,
 		goto fail;
 	}
 
+	ret = rte_telemetry_send_ports_stats_values(stat_ids, num_metrics,
+		port_ids, num_port_ids, telemetry);
+	if (ret < 0) {
+		TELEMETRY_LOG_ERR("Sending ports stats values failed");
+		goto fail;
+	}
+
 	return 0;
 
 fail:
@@ -428,6 +437,14 @@ rte_telemetry_command_ports_stats_values_by_name(struct telemetry_impl
 		TELEMETRY_LOG_ERR("Could not convert stat names to IDs");
 		return -1;
 	}
+
+	ret = rte_telemetry_send_ports_stats_values(stat_ids, num_stat_names,
+		port_ids, num_port_ids, telemetry);
+	if (ret < 0) {
+		TELEMETRY_LOG_ERR("Sending ports stats values failed");
+		return -1;
+	}
+
 	return 0;
 }
 
-- 
2.9.5