[05/11] telemetry: update metrics before sending stats

Message ID 1535026093-101872-6-git-send-email-ciara.power@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series introduce telemetry library |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation fail Compilation issues

Commit Message

Power, Ciara Aug. 23, 2018, 12:08 p.m. UTC
  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>
---
 lib/librte_telemetry/rte_telemetry.c          | 128 ++++++++++++++++++++++++++
 lib/librte_telemetry/rte_telemetry_internal.h |   4 +
 lib/librte_telemetry/rte_telemetry_parser.c   |  19 ++++
 3 files changed, 151 insertions(+)
  

Patch

diff --git a/lib/librte_telemetry/rte_telemetry.c b/lib/librte_telemetry/rte_telemetry.c
index c6c6612..bd09374 100644
--- a/lib/librte_telemetry/rte_telemetry.c
+++ b/lib/librte_telemetry/rte_telemetry.c
@@ -40,6 +40,74 @@  rte_telemetry_check_port_activity(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("Error - port_id: %d is invalid\n", port_id);
+		ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
+		if (ret < 0)
+			TELEMETRY_LOG_ERR("Error - Could not send error\n");
+		return -1;
+	}
+	ret = rte_telemetry_check_port_activity(port_id);
+	if (ret < 1) {
+		ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
+		if (ret < 0)
+			TELEMETRY_LOG_ERR("Error - Could not send error\n");
+		return -1;
+	}
+	num_xstats = rte_eth_xstats_get(port_id, NULL, 0);
+	if (num_xstats < 0) {
+		TELEMETRY_LOG_ERR("Error - rte_eth_xstats_get(%u) failed:"
+			" %d\n", port_id, num_xstats);
+		ret = rte_telemetry_send_error_response(telemetry, -EPERM);
+		if (ret < 0)
+			TELEMETRY_LOG_ERR("Error - Could not send error\n");
+		return -1;
+	}
+	eth_xstats = malloc(sizeof(struct rte_eth_xstat) * num_xstats);
+	if (eth_xstats == NULL) {
+		TELEMETRY_LOG_ERR("Error - Failed to malloc memory for "
+			"xstats\n");
+		ret = rte_telemetry_send_error_response(telemetry, -ENOMEM);
+		if (ret < 0)
+			TELEMETRY_LOG_ERR("Error - Could not send error\n");
+		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("Error - rte_eth_xstats_get(%u) len%i"
+			" failed: %d\n", port_id, num_xstats, ret);
+		ret = rte_telemetry_send_error_response(telemetry, -EPERM);
+		if (ret < 0)
+			TELEMETRY_LOG_ERR("Error - Could not send error\n");
+		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("Error - Could not update metrics values\n");
+		ret = rte_telemetry_send_error_response(telemetry, -EPERM);
+		if (ret < 0)
+			TELEMETRY_LOG_ERR("Error - Could not send error\n");
+		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)
@@ -122,6 +190,66 @@  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;
+	if (!telemetry) {
+		TELEMETRY_LOG_ERR("Error - Invalid telemetry argument\n");
+		return -1;
+	}
+	if (metric_ids == NULL) {
+		TELEMETRY_LOG_ERR("Error - Invalid metric_ids array\n");
+		goto einval_fail;
+	}
+	if (num_metric_ids < 0) {
+		TELEMETRY_LOG_ERR("Error - Invalid num_metric_ids, must be "
+			"positive\n");
+		goto einval_fail;
+	}
+	if (port_ids == NULL) {
+		TELEMETRY_LOG_ERR("Error - Invalid port_ids array\n");
+		goto einval_fail;
+	}
+	if (num_port_ids < 0) {
+		TELEMETRY_LOG_ERR("Error - Invalid num_port_ids, must be "
+			"positive\n");
+		goto einval_fail;
+	}
+
+	int i;
+	for (i = 0; i < num_port_ids; i++) {
+		if (!rte_eth_dev_is_valid_port(port_ids[i])) {
+			TELEMETRY_LOG_ERR("Error - Port: %d invalid\n",
+				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("Error - failed to update ethdev "
+				"metrics\n");
+			return -1;
+		}
+	}
+
+	char *json_buffer = NULL;
+	ret = rte_telemetry_write_to_socket(telemetry, json_buffer);
+	if (ret < 0) {
+		TELEMETRY_LOG_ERR("Error - Could not write to socket\n");
+		return -1;
+	}
+	return 0;
+
+einval_fail:
+	ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
+	if (ret < 0)
+		TELEMETRY_LOG_ERR("Error - Could not send error\n");
+	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 b057794..ef417f2 100644
--- a/lib/librte_telemetry/rte_telemetry_internal.h
+++ b/lib/librte_telemetry/rte_telemetry_internal.h
@@ -61,4 +61,8 @@  rte_telemetry_unregister_client(struct telemetry_impl *telemetry,
 int32_t
 rte_telemetry_check_port_activity(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 571c991..4c50e41 100644
--- a/lib/librte_telemetry/rte_telemetry_parser.c
+++ b/lib/librte_telemetry/rte_telemetry_parser.c
@@ -327,8 +327,10 @@  rte_telemetry_command_ports_all_stat_values(struct telemetry_impl *telemetry,
 	const char *stat_names[num_metrics];
 	uint32_t stat_ids[num_metrics];
 	int p;
+	uint32_t port_ids[RTE_MAX_ETHPORTS];
 
 	RTE_ETH_FOREACH_DEV(p) {
+		port_ids[num_port_ids] = p;
 		num_port_ids++;
 	}
 	if (!num_port_ids) {
@@ -351,6 +353,14 @@  rte_telemetry_command_ports_all_stat_values(struct telemetry_impl *telemetry,
 		TELEMETRY_LOG_ERR("Error - Could not convert stat names to IDs\n");
 		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("Error - Sending ports stats values failed\n");
+		goto fail;
+	}
+
 	return 0;
 
 fail:
@@ -451,6 +461,15 @@  rte_telemetry_command_ports_stats_values_by_name(struct telemetry_impl
 			"IDs\n");
 		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("Error - Sending ports stats values "
+			"failed\n");
+		return -1;
+	}
+
 	return 0;
 }