Add a new rte_telemetry_register_cmd_arg public function to register
a telemetry endpoint with a callback that takes an additional private
argument.

This will be used in the next commit to protect ethdev endpoints with
a lock.

Update perform_command() to take a struct callback object copied from
the list of callbacks and invoke the correct function pointer.

Signed-off-by: Robin Jarry <rja...@redhat.com>
---
 lib/telemetry/rte_telemetry.h | 46 +++++++++++++++++++++++++++++++++++
 lib/telemetry/telemetry.c     | 38 +++++++++++++++++++++++------
 lib/telemetry/version.map     |  3 +++
 3 files changed, 79 insertions(+), 8 deletions(-)

diff --git a/lib/telemetry/rte_telemetry.h b/lib/telemetry/rte_telemetry.h
index cab9daa6fed6..3fbfda138b16 100644
--- a/lib/telemetry/rte_telemetry.h
+++ b/lib/telemetry/rte_telemetry.h
@@ -336,6 +336,30 @@ rte_tel_data_add_dict_uint_hex(struct rte_tel_data *d, 
const char *name,
 typedef int (*telemetry_cb)(const char *cmd, const char *params,
                struct rte_tel_data *info);
 
+/**
+ * This telemetry callback is used when registering a telemetry command with
+ * rte_telemetry_register_cmd_arg().
+ *
+ * It handles getting and formatting information to be returned to telemetry
+ * when requested.
+ *
+ * @param cmd
+ * The cmd that was requested by the client.
+ * @param params
+ * Contains data required by the callback function.
+ * @param info
+ * The information to be returned to the caller.
+ * @param arg
+ * The opaque value that was passed to rte_telemetry_register_cmd_arg().
+ *
+ * @return
+ * Length of buffer used on success.
+ * @return
+ * Negative integer on error.
+ */
+typedef int (*telemetry_arg_cb)(const char *cmd, const char *params,
+               struct rte_tel_data *info, void *arg);
+
 /**
  * Used for handling data received over a telemetry socket.
  *
@@ -367,6 +391,28 @@ typedef void * (*handler)(void *sock_id);
 int
 rte_telemetry_register_cmd(const char *cmd, telemetry_cb fn, const char *help);
 
+/**
+ * Used when registering a command and callback function with telemetry.
+ *
+ * @param cmd
+ * The command to register with telemetry.
+ * @param fn
+ * Callback function to be called when the command is requested.
+ * @param arg
+ * An opaque value that will be passed to the callback function.
+ * @param help
+ * Help text for the command.
+ *
+ * @return
+ *  0 on success.
+ * @return
+ *  -EINVAL for invalid parameters failure.
+ *  @return
+ *  -ENOMEM for mem allocation failure.
+ */
+__rte_experimental
+int
+rte_telemetry_register_cmd_arg(const char *cmd, telemetry_arg_cb fn, void 
*arg, const char *help);
 
 /**
  * Get a pointer to a container with memory allocated. The container is to be
diff --git a/lib/telemetry/telemetry.c b/lib/telemetry/telemetry.c
index c4c5a61a5cf8..2fe48d47f886 100644
--- a/lib/telemetry/telemetry.c
+++ b/lib/telemetry/telemetry.c
@@ -37,6 +37,8 @@ client_handler(void *socket);
 struct cmd_callback {
        char cmd[MAX_CMD_LEN];
        telemetry_cb fn;
+       telemetry_arg_cb fn_arg;
+       void *arg;
        char help[RTE_TEL_MAX_STRING_LEN];
 };
 
@@ -68,14 +70,15 @@ static rte_spinlock_t callback_sl = 
RTE_SPINLOCK_INITIALIZER;
 static RTE_ATOMIC(uint16_t) v2_clients;
 #endif /* !RTE_EXEC_ENV_WINDOWS */
 
-int
-rte_telemetry_register_cmd(const char *cmd, telemetry_cb fn, const char *help)
+static int
+__rte_telemetry_register_cmd(const char *cmd, const char *help,
+                            telemetry_cb fn, telemetry_arg_cb fn_arg, void 
*arg)
 {
        struct cmd_callback *new_callbacks;
        const char *cmdp = cmd;
        int i = 0;
 
-       if (strlen(cmd) >= MAX_CMD_LEN || fn == NULL || cmd[0] != '/'
+       if (strlen(cmd) >= MAX_CMD_LEN || (fn == NULL && fn_arg == NULL) || 
cmd[0] != '/'
                        || strlen(help) >= RTE_TEL_MAX_STRING_LEN)
                return -EINVAL;
 
@@ -102,6 +105,8 @@ rte_telemetry_register_cmd(const char *cmd, telemetry_cb 
fn, const char *help)
 
        strlcpy(callbacks[i].cmd, cmd, MAX_CMD_LEN);
        callbacks[i].fn = fn;
+       callbacks[i].fn_arg = fn_arg;
+       callbacks[i].arg = arg;
        strlcpy(callbacks[i].help, help, RTE_TEL_MAX_STRING_LEN);
        num_callbacks++;
        rte_spinlock_unlock(&callback_sl);
@@ -109,6 +114,18 @@ rte_telemetry_register_cmd(const char *cmd, telemetry_cb 
fn, const char *help)
        return 0;
 }
 
+int
+rte_telemetry_register_cmd(const char *cmd, telemetry_cb fn, const char *help)
+{
+       return __rte_telemetry_register_cmd(cmd, help, fn, NULL, NULL);
+}
+
+int
+rte_telemetry_register_cmd_arg(const char *cmd, telemetry_arg_cb fn, void 
*arg, const char *help)
+{
+       return __rte_telemetry_register_cmd(cmd, help, NULL, fn, arg);
+}
+
 #ifndef RTE_EXEC_ENV_WINDOWS
 
 static int
@@ -349,11 +366,16 @@ output_json(const char *cmd, const struct rte_tel_data 
*d, int s)
 }
 
 static void
-perform_command(telemetry_cb fn, const char *cmd, const char *param, int s)
+perform_command(const struct cmd_callback *cb, const char *cmd, const char 
*param, int s)
 {
        struct rte_tel_data data = {0};
+       int ret;
+
+       if (cb->fn_arg != NULL)
+               ret = cb->fn_arg(cmd, param, &data, cb->arg);
+       else
+               ret = cb->fn(cmd, param, &data);
 
-       int ret = fn(cmd, param, &data);
        if (ret < 0) {
                char out_buf[MAX_CMD_LEN + 10];
                int used = snprintf(out_buf, sizeof(out_buf), "{\"%.*s\":null}",
@@ -392,19 +414,19 @@ client_handler(void *sock_id)
                buffer[bytes] = 0;
                const char *cmd = strtok(buffer, ",");
                const char *param = strtok(NULL, "\0");
-               telemetry_cb fn = unknown_command;
+               struct cmd_callback cb = {.fn = unknown_command};
                int i;
 
                if (cmd && strlen(cmd) < MAX_CMD_LEN) {
                        rte_spinlock_lock(&callback_sl);
                        for (i = 0; i < num_callbacks; i++)
                                if (strcmp(cmd, callbacks[i].cmd) == 0) {
-                                       fn = callbacks[i].fn;
+                                       cb = callbacks[i];
                                        break;
                                }
                        rte_spinlock_unlock(&callback_sl);
                }
-               perform_command(fn, cmd, param, s);
+               perform_command(&cb, cmd, param, s);
 
                bytes = read(s, buffer, sizeof(buffer) - 1);
        }
diff --git a/lib/telemetry/version.map b/lib/telemetry/version.map
index 2907d28aa03f..8f032bf53230 100644
--- a/lib/telemetry/version.map
+++ b/lib/telemetry/version.map
@@ -28,6 +28,9 @@ EXPERIMENTAL {
        rte_tel_data_add_array_uint_hex;
        rte_tel_data_add_dict_uint_hex;
 
+       # added in 24.11
+       rte_telemetry_register_cmd_arg;
+
        local: *;
 };
 
-- 
2.46.2

Reply via email to