Allow applications to register a callback that will be invoked in
rte_lcore_dump() and when requesting lcore info in the telemetry API.

The callback is expected to return a number between 0 and 100
representing the percentage of busy cycles spent over a fixed period of
time. The period of time is configured when registering the callback.

Cc: Bruce Richardson <bruce.richard...@intel.com>
Cc: Jerin Jacob <jer...@marvell.com>
Cc: Kevin Laatz <kevin.la...@intel.com>
Cc: Konstantin Ananyev <konstantin.v.anan...@yandex.ru>
Cc: Mattias Rönnblom <hof...@lysator.liu.se>
Cc: Morten Brørup <m...@smartsharesystems.com>
Signed-off-by: Robin Jarry <rja...@redhat.com>
---
 lib/eal/common/eal_common_lcore.c | 37 ++++++++++++++++++++++++++++---
 lib/eal/include/rte_lcore.h       | 30 +++++++++++++++++++++++++
 lib/eal/version.map               |  1 +
 3 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/lib/eal/common/eal_common_lcore.c 
b/lib/eal/common/eal_common_lcore.c
index 31e3965dc5ad..9a85fd8854df 100644
--- a/lib/eal/common/eal_common_lcore.c
+++ b/lib/eal/common/eal_common_lcore.c
@@ -420,14 +420,36 @@ rte_lcore_iterate(rte_lcore_iterate_cb cb, void *arg)
        return ret;
 }
 
+static rte_lcore_busy_percent_cb lcore_busy_cb;
+static unsigned int lcore_busy_period;
+
+void
+rte_lcore_register_busy_percent_cb(rte_lcore_busy_percent_cb cb, unsigned int 
period)
+{
+       lcore_busy_cb = cb;
+       lcore_busy_period = period;
+}
+
+static int
+lcore_busy_percent(unsigned int lcore_id)
+{
+       int percent = -1;
+       if (lcore_busy_cb)
+               percent = lcore_busy_cb(lcore_id);
+       if (percent > 100)
+               percent = 100;
+       return percent;
+}
+
 static int
 lcore_dump_cb(unsigned int lcore_id, void *arg)
 {
        struct rte_config *cfg = rte_eal_get_configuration();
        char cpuset[RTE_CPU_AFFINITY_STR_LEN];
+       char busy_str[16];
        const char *role;
        FILE *f = arg;
-       int ret;
+       int ret, busy;
 
        switch (cfg->lcore_role[lcore_id]) {
        case ROLE_RTE:
@@ -446,9 +468,16 @@ lcore_dump_cb(unsigned int lcore_id, void *arg)
 
        ret = eal_thread_dump_affinity(&lcore_config[lcore_id].cpuset, cpuset,
                sizeof(cpuset));
-       fprintf(f, "lcore %u, socket %u, role %s, cpuset %s%s\n", lcore_id,
+       busy = lcore_busy_percent(lcore_id);
+       if (busy < 0) {
+               snprintf(busy_str, sizeof(busy_str), "%s", "N/A");
+       } else {
+               snprintf(busy_str, sizeof(busy_str), "%d%% last %d sec",
+                       busy, lcore_busy_period);
+       }
+       fprintf(f, "lcore %u, socket %u, role %s, cpuset %s%s, busy %s\n", 
lcore_id,
                rte_lcore_to_socket_id(lcore_id), role, cpuset,
-               ret == 0 ? "" : "...");
+               ret == 0 ? "" : "...", busy_str);
        return 0;
 }
 
@@ -517,6 +546,8 @@ lcore_telemetry_info_cb(unsigned int lcore_id, void *arg)
        rte_tel_data_add_dict_int(info->d, "socket", 
rte_lcore_to_socket_id(lcore_id));
        rte_tel_data_add_dict_string(info->d, "role", role);
        rte_tel_data_add_dict_string(info->d, "cpuset", cpuset);
+       rte_tel_data_add_dict_int(info->d, "busy_percent", 
lcore_busy_percent(lcore_id));
+       rte_tel_data_add_dict_int(info->d, "busy_period", lcore_busy_period);
 
        return 0;
 }
diff --git a/lib/eal/include/rte_lcore.h b/lib/eal/include/rte_lcore.h
index 6938c3fd7b81..b1223eaa12bf 100644
--- a/lib/eal/include/rte_lcore.h
+++ b/lib/eal/include/rte_lcore.h
@@ -328,6 +328,36 @@ typedef int (*rte_lcore_iterate_cb)(unsigned int lcore_id, 
void *arg);
 int
 rte_lcore_iterate(rte_lcore_iterate_cb cb, void *arg);
 
+/**
+ * Callback to allow applications to report CPU utilization.
+ *
+ * @param lcore_id
+ *   The lcore to consider.
+ * @return
+ *   - A number between 0 and 100 representing the percentage of busy cycles
+ *     over the last period for the given lcore_id.
+ *   - -1 if the information is not available or if any error occurred.
+ */
+typedef int (*rte_lcore_busy_percent_cb)(unsigned int lcore_id);
+
+/**
+ * Register a callback from an application to be called in rte_lcore_dump()
+ * and the /eal/lcore/info telemetry endpoint handler.
+ *
+ * Applications are expected to return a number between 0 and 100 representing
+ * the percentage of busy cycles over the last period for the provided 
lcore_id.
+ * The implementation details for computing such a ratio is specific to each
+ * application.
+ *
+ * @param cb
+ *   The callback function.
+ * @param period
+ *   The period in seconds over which the percentage of busy cycles will be
+ *   reported by the application.
+ */
+__rte_experimental
+void rte_lcore_register_busy_percent_cb(rte_lcore_busy_percent_cb cb, unsigned 
int period);
+
 /**
  * List all lcores.
  *
diff --git a/lib/eal/version.map b/lib/eal/version.map
index 7ad12a7dc985..138537ee5835 100644
--- a/lib/eal/version.map
+++ b/lib/eal/version.map
@@ -440,6 +440,7 @@ EXPERIMENTAL {
        rte_thread_detach;
        rte_thread_equal;
        rte_thread_join;
+       rte_lcore_register_busy_percent_cb;
 };
 
 INTERNAL {
-- 
2.38.1

Reply via email to