From patchwork Thu Dec 8 08:05:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "lihuisong (C)" X-Patchwork-Id: 120574 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 65244A00C2; Thu, 8 Dec 2022 09:05:51 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 05C1542D2A; Thu, 8 Dec 2022 09:05:40 +0100 (CET) Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) by mails.dpdk.org (Postfix) with ESMTP id C40FB40F17 for ; Thu, 8 Dec 2022 09:05:34 +0100 (CET) Received: from kwepemm600004.china.huawei.com (unknown [172.30.72.57]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4NSRWs4zr5zmWPL for ; Thu, 8 Dec 2022 16:04:41 +0800 (CST) Received: from localhost.localdomain (10.69.192.56) by kwepemm600004.china.huawei.com (7.193.23.242) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Thu, 8 Dec 2022 16:05:32 +0800 From: Huisong Li To: CC: , , , , Subject: [PATCH 2/8] telemetry: add u32 telemetry data type API Date: Thu, 8 Dec 2022 16:05:34 +0800 Message-ID: <20221208080540.62913-3-lihuisong@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20221208080540.62913-1-lihuisong@huawei.com> References: <20221208080540.62913-1-lihuisong@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.56] X-ClientProxiedBy: dggems705-chm.china.huawei.com (10.3.19.182) To kwepemm600004.china.huawei.com (7.193.23.242) X-CFilter-Loop: Reflected X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Currently, 32-bit integer value only is signed in telemetry. The u32 data can not be assigned to signed 32-bit integer. However, assigning to u64 is very wasteful, after all, the buffer capacity of each transfer is limited. So it is necessary for 'u32' data to add usigned 32-bit integer and a series of 'u32' APIs. Cc: stable@dpdk.org Signed-off-by: Huisong Li --- lib/telemetry/rte_telemetry.h | 35 +++++++++++++++++++++++ lib/telemetry/telemetry.c | 25 ++++++++++++++-- lib/telemetry/telemetry_data.c | 52 ++++++++++++++++++++++++++++------ lib/telemetry/telemetry_data.h | 2 ++ lib/telemetry/telemetry_json.h | 29 +++++++++++++++++++ lib/telemetry/version.map | 9 ++++++ 6 files changed, 141 insertions(+), 11 deletions(-) diff --git a/lib/telemetry/rte_telemetry.h b/lib/telemetry/rte_telemetry.h index 40e9a3bf9d..1ffa1a6632 100644 --- a/lib/telemetry/rte_telemetry.h +++ b/lib/telemetry/rte_telemetry.h @@ -10,6 +10,7 @@ extern "C" { #endif #include +#include /** Maximum length for string used in object. */ #define RTE_TEL_MAX_STRING_LEN 128 @@ -42,6 +43,7 @@ struct rte_tel_data; enum rte_tel_value_type { RTE_TEL_STRING_VAL, /** a string value */ RTE_TEL_INT_VAL, /** a signed 32-bit int value */ + RTE_TEL_U32_VAL, /** an unsigned 32-bit int value */ RTE_TEL_U64_VAL, /** an unsigned 64-bit int value */ RTE_TEL_CONTAINER, /** a container struct */ }; @@ -117,6 +119,21 @@ rte_tel_data_add_array_string(struct rte_tel_data *d, const char *str); int rte_tel_data_add_array_int(struct rte_tel_data *d, int x); +/** + * Add a uint32_t to an array. + * The array must have been started by rte_tel_data_start_array() with + * RTE_TEL_U32_VAL as the type parameter. + * + * @param d + * The data structure passed to the callback + * @param x + * The number to be returned in the array + * @return + * 0 on success, negative errno on error + */ +__rte_experimental +int rte_tel_data_add_array_u32(struct rte_tel_data *d, uint32_t x); + /** * Add a uint64_t to an array. * The array must have been started by rte_tel_data_start_array() with @@ -189,6 +206,24 @@ rte_tel_data_add_dict_string(struct rte_tel_data *d, const char *name, int rte_tel_data_add_dict_int(struct rte_tel_data *d, const char *name, int val); +/** + * Add a uint32_t value to a dictionary. + * The dict must have been started by rte_tel_data_start_dict(). + * + * @param d + * The data structure passed to the callback + * @param name + * The name the value is to be stored under in the dict + * Must contain only alphanumeric characters or the symbols: '_' or '/' + * @param val + * The number to be stored in the dict + * @return + * 0 on success, negative errno on error, E2BIG on string truncation of name. + */ +__rte_experimental +int rte_tel_data_add_dict_u32(struct rte_tel_data *d, + const char *name, uint32_t val); + /** * Add a uint64_t value to a dictionary. * The dict must have been started by rte_tel_data_start_dict(). diff --git a/lib/telemetry/telemetry.c b/lib/telemetry/telemetry.c index 8fbb4f3060..b52fcae713 100644 --- a/lib/telemetry/telemetry.c +++ b/lib/telemetry/telemetry.c @@ -167,8 +167,9 @@ container_to_json(const struct rte_tel_data *d, char *out_buf, size_t buf_len) size_t used = 0; unsigned int i; - if (d->type != RTE_TEL_DICT && d->type != RTE_TEL_ARRAY_U64 && - d->type != RTE_TEL_ARRAY_INT && d->type != RTE_TEL_ARRAY_STRING) + if (d->type != RTE_TEL_DICT && d->type != RTE_TEL_ARRAY_U32 && + d->type != RTE_TEL_ARRAY_U64 && d->type != RTE_TEL_ARRAY_INT && + d->type != RTE_TEL_ARRAY_STRING) return snprintf(out_buf, buf_len, "null"); used = rte_tel_json_empty_array(out_buf, buf_len, 0); @@ -177,6 +178,11 @@ container_to_json(const struct rte_tel_data *d, char *out_buf, size_t buf_len) used = rte_tel_json_add_array_u64(out_buf, buf_len, used, d->data.array[i].u64val); + if (d->type == RTE_TEL_ARRAY_U32) + for (i = 0; i < d->data_len; i++) + used = rte_tel_json_add_array_u32(out_buf, + buf_len, used, + d->data.array[i].u32val); if (d->type == RTE_TEL_ARRAY_INT) for (i = 0; i < d->data_len; i++) used = rte_tel_json_add_array_int(out_buf, @@ -201,6 +207,11 @@ container_to_json(const struct rte_tel_data *d, char *out_buf, size_t buf_len) buf_len, used, v->name, v->value.ival); break; + case RTE_TEL_U32_VAL: + used = rte_tel_json_add_obj_u32(out_buf, + buf_len, used, + v->name, v->value.u32val); + break; case RTE_TEL_U64_VAL: used = rte_tel_json_add_obj_u64(out_buf, buf_len, used, @@ -268,6 +279,11 @@ output_json(const char *cmd, const struct rte_tel_data *d, int s) buf_len, used, v->name, v->value.ival); break; + case RTE_TEL_U32_VAL: + used = rte_tel_json_add_obj_u32(cb_data_buf, + buf_len, used, + v->name, v->value.u32val); + break; case RTE_TEL_U64_VAL: used = rte_tel_json_add_obj_u64(cb_data_buf, buf_len, used, @@ -293,6 +309,7 @@ output_json(const char *cmd, const struct rte_tel_data *d, int s) case RTE_TEL_ARRAY_STRING: case RTE_TEL_ARRAY_INT: + case RTE_TEL_ARRAY_U32: case RTE_TEL_ARRAY_U64: case RTE_TEL_ARRAY_CONTAINER: used = rte_tel_json_empty_array(cb_data_buf, buf_len, 0); @@ -306,6 +323,10 @@ output_json(const char *cmd, const struct rte_tel_data *d, int s) used = rte_tel_json_add_array_int(cb_data_buf, buf_len, used, d->data.array[i].ival); + else if (d->type == RTE_TEL_ARRAY_U32) + used = rte_tel_json_add_array_u32(cb_data_buf, + buf_len, used, + d->data.array[i].u32val); else if (d->type == RTE_TEL_ARRAY_U64) used = rte_tel_json_add_array_u64(cb_data_buf, buf_len, used, diff --git a/lib/telemetry/telemetry_data.c b/lib/telemetry/telemetry_data.c index 34366ecee3..366cb2669a 100644 --- a/lib/telemetry/telemetry_data.c +++ b/lib/telemetry/telemetry_data.c @@ -18,8 +18,9 @@ rte_tel_data_start_array(struct rte_tel_data *d, enum rte_tel_value_type type) enum tel_container_types array_types[] = { RTE_TEL_ARRAY_STRING, /* RTE_TEL_STRING_VAL = 0 */ RTE_TEL_ARRAY_INT, /* RTE_TEL_INT_VAL = 1 */ - RTE_TEL_ARRAY_U64, /* RTE_TEL_u64_VAL = 2 */ - RTE_TEL_ARRAY_CONTAINER, /* RTE_TEL_CONTAINER = 3 */ + RTE_TEL_ARRAY_U32, /* RTE_TEL_u32_VAL = 2 */ + RTE_TEL_ARRAY_U64, /* RTE_TEL_u64_VAL = 3 */ + RTE_TEL_ARRAY_CONTAINER, /* RTE_TEL_CONTAINER = 4 */ }; d->type = array_types[type]; d->data_len = 0; @@ -69,6 +70,17 @@ rte_tel_data_add_array_int(struct rte_tel_data *d, int x) return 0; } +int +rte_tel_data_add_array_u32(struct rte_tel_data *d, uint32_t x) +{ + if (d->type != RTE_TEL_ARRAY_U32) + return -EINVAL; + if (d->data_len >= RTE_TEL_MAX_ARRAY_ENTRIES) + return -ENOSPC; + d->data.array[d->data_len++].u32val = x; + return 0; +} + int rte_tel_data_add_array_u64(struct rte_tel_data *d, uint64_t x) { @@ -85,9 +97,10 @@ rte_tel_data_add_array_container(struct rte_tel_data *d, struct rte_tel_data *val, int keep) { if (d->type != RTE_TEL_ARRAY_CONTAINER || - (val->type != RTE_TEL_ARRAY_U64 - && val->type != RTE_TEL_ARRAY_INT - && val->type != RTE_TEL_ARRAY_STRING)) + (val->type != RTE_TEL_ARRAY_U32 && + val->type != RTE_TEL_ARRAY_U64 && + val->type != RTE_TEL_ARRAY_INT && + val->type != RTE_TEL_ARRAY_STRING)) return -EINVAL; if (d->data_len >= RTE_TEL_MAX_ARRAY_ENTRIES) return -ENOSPC; @@ -159,6 +172,26 @@ rte_tel_data_add_dict_int(struct rte_tel_data *d, const char *name, int val) return bytes < RTE_TEL_MAX_STRING_LEN ? 0 : E2BIG; } +int +rte_tel_data_add_dict_u32(struct rte_tel_data *d, + const char *name, uint32_t val) +{ + struct tel_dict_entry *e = &d->data.dict[d->data_len]; + if (d->type != RTE_TEL_DICT) + return -EINVAL; + if (d->data_len >= RTE_TEL_MAX_DICT_ENTRIES) + return -ENOSPC; + + if (!valid_name(name)) + return -EINVAL; + + d->data_len++; + e->type = RTE_TEL_U32_VAL; + e->value.u32val = val; + const size_t bytes = strlcpy(e->name, name, RTE_TEL_MAX_STRING_LEN); + return bytes < RTE_TEL_MAX_STRING_LEN ? 0 : E2BIG; +} + int rte_tel_data_add_dict_u64(struct rte_tel_data *d, const char *name, uint64_t val) @@ -185,10 +218,11 @@ rte_tel_data_add_dict_container(struct rte_tel_data *d, const char *name, { struct tel_dict_entry *e = &d->data.dict[d->data_len]; - if (d->type != RTE_TEL_DICT || (val->type != RTE_TEL_ARRAY_U64 - && val->type != RTE_TEL_ARRAY_INT - && val->type != RTE_TEL_ARRAY_STRING - && val->type != RTE_TEL_DICT)) + if (d->type != RTE_TEL_DICT || (val->type != RTE_TEL_ARRAY_U32 && + val->type != RTE_TEL_ARRAY_U64 && + val->type != RTE_TEL_ARRAY_INT && + val->type != RTE_TEL_ARRAY_STRING && + val->type != RTE_TEL_DICT)) return -EINVAL; if (d->data_len >= RTE_TEL_MAX_DICT_ENTRIES) return -ENOSPC; diff --git a/lib/telemetry/telemetry_data.h b/lib/telemetry/telemetry_data.h index 26aa28e72c..ca0a895edb 100644 --- a/lib/telemetry/telemetry_data.h +++ b/lib/telemetry/telemetry_data.h @@ -13,6 +13,7 @@ enum tel_container_types { RTE_TEL_DICT, /** name-value pairs, of individual value type */ RTE_TEL_ARRAY_STRING, /** array of string values only */ RTE_TEL_ARRAY_INT, /** array of signed, 32-bit int values */ + RTE_TEL_ARRAY_U32, /** array of unsigned 32-bit int values */ RTE_TEL_ARRAY_U64, /** array of unsigned 64-bit int values */ RTE_TEL_ARRAY_CONTAINER, /** array of container structs */ }; @@ -29,6 +30,7 @@ struct container { union tel_value { char sval[RTE_TEL_MAX_STRING_LEN]; int ival; + uint32_t u32val; uint64_t u64val; struct container container; }; diff --git a/lib/telemetry/telemetry_json.h b/lib/telemetry/telemetry_json.h index e3fae7c30d..05762ec89a 100644 --- a/lib/telemetry/telemetry_json.h +++ b/lib/telemetry/telemetry_json.h @@ -146,6 +146,19 @@ rte_tel_json_add_array_int(char *buf, const int len, const int used, int val) return ret == 0 ? used : end + ret; } +/* Appends a uint32_t into the JSON array in the provided buffer. */ +static inline int +rte_tel_json_add_array_u32(char *buf, const int len, const int used, + uint32_t val) +{ + int ret, end = used - 1; /* strip off final delimiter */ + if (used <= 2) /* assume empty, since minimum is '[]' */ + return __json_snprintf(buf, len, "[%u]", val); + + ret = __json_snprintf(buf + end, len - end, ",%u]", val); + return ret == 0 ? used : end + ret; +} + /* Appends a uint64_t into the JSON array in the provided buffer. */ static inline int rte_tel_json_add_array_u64(char *buf, const int len, const int used, @@ -175,6 +188,22 @@ rte_tel_json_add_array_json(char *buf, const int len, const int used, return ret == 0 ? used : end + ret; } +/** + * Add a new element with uint32_t value to the JSON object stored in the + * provided buffer. + */ +static inline int +rte_tel_json_add_obj_u32(char *buf, const int len, const int used, + const char *name, uint32_t val) +{ + int ret, end = used - 1; + if (used <= 2) /* assume empty, since minimum is '{}' */ + return __json_snprintf(buf, len, "{\"%s\":%u}", name, val); + + ret = __json_snprintf(buf + end, len - end, ",\"%s\":%u}", name, val); + return ret == 0 ? used : end + ret; +} + /** * Add a new element with uint64_t value to the JSON object stored in the * provided buffer. diff --git a/lib/telemetry/version.map b/lib/telemetry/version.map index 9794f9ea20..3d1fb15637 100644 --- a/lib/telemetry/version.map +++ b/lib/telemetry/version.map @@ -1,3 +1,12 @@ +EXPERIMENTAL { + global: + + rte_tel_data_add_array_u32; + rte_tel_data_add_dict_u32; + + local: *; +}; + DPDK_23 { global: