telemetry: update metrics before sending stats
authorCiara Power <ciara.power@intel.com>
Sat, 27 Oct 2018 09:17:45 +0000 (10:17 +0100)
committerThomas Monjalon <thomas@monjalon.net>
Sat, 27 Oct 2018 13:18:23 +0000 (15:18 +0200)
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
lib/librte_telemetry/rte_telemetry_internal.h
lib/librte_telemetry/rte_telemetry_parser.c

index 03766e7..053c8b8 100644 (file)
@@ -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)
 {
index 86a5ba1..0082cb2 100644 (file)
@@ -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
index 556abbe..03a58a2 100644 (file)
@@ -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;
 }