dmadev: add telemetry

Telemetry commands are now registered through the dmadev library
for the gathering of DSA stats. The corresponding callback
functions for listing dmadevs and providing info and stats for a
specific dmadev are implemented in the dmadev library.

An example usage can be seen below:

Connecting to /var/run/dpdk/rte/dpdk_telemetry.v2
{"version": "DPDK 22.03.0-rc2", "pid": 2956551, "max_output_len": 16384}
Connected to application: "dpdk-dma"
--> /
{"/": ["/", "/dmadev/info", "/dmadev/list", "/dmadev/stats", ...]}
--> /dmadev/list
{"/dmadev/list": [0, 1]}
--> /dmadev/info,0
{"/dmadev/info": {"name": "0000:00:01.0", "nb_vchans": 1, "numa_node": 0,
"max_vchans": 1, "max_desc": 4096, "min_desc": 32, "max_sges": 0,
"capabilities": {"mem2mem": 1, "mem2dev": 0, "dev2mem": 0, ...}}}
--> /dmadev/stats,0,0
{"/dmadev/stats": {"submitted": 0, "completed": 0, "errors": 0}}

Signed-off-by: Sean Morrissey <sean.morrissey@intel.com>
Reviewed-by: Bruce Richardson <bruce.richardson@intel.com>
Reviewed-by: Conor Walsh <conor.walsh@intel.com>
Tested-by: Sunil Pai G <sunil.pai.g@intel.com>
Tested-by: Kevin Laatz <kevin.laatz@intel.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
This commit is contained in:
Sean Morrissey 2022-04-01 15:01:35 +00:00 committed by Thomas Monjalon
parent e345594f3c
commit 39b5ab60df
4 changed files with 161 additions and 0 deletions

View File

@ -118,3 +118,27 @@ i.e. ``rte_dma_stats_get()``. The statistics returned for each device instance a
* ``submitted``: The number of operations submitted to the device.
* ``completed``: The number of operations which have completed (successful and failed).
* ``errors``: The number of operations that completed with error.
The dmadev library has support for displaying DMA device information
through the Telemetry interface. Telemetry commands that can be used
are shown below.
#. Get the list of available DMA devices by ID::
--> /dmadev/list
{"/dmadev/list": [0, 1]}
#. Get general information from a DMA device by passing the device id as a parameter::
--> /dmadev/info,0
{"/dmadev/info": {"name": "0000:00:01.0", "nb_vchans": 1, "numa_node": 0, "max_vchans": 1, "max_desc": 4096,
"min_desc": 32, "max_sges": 0, "capabilities": {"mem2mem": 1, "mem2dev": 0, "dev2mem": 0, ...}}}
#. Get the statistics for a particular DMA device and virtual DMA channel by passing the device id and vchan id as parameters
(if a DMA device only has one virtual DMA channel you only need to pass the device id)::
--> /dmadev/stats,0,0
{"/dmadev/stats": {"submitted": 0, "completed": 0, "errors": 0}}
For more information on how to use the Telemetry interface, see
the :doc:`../howto/telemetry`.

View File

@ -164,6 +164,11 @@ New Features
* ``RTE_EVENT_QUEUE_ATTR_WEIGHT``
* ``RTE_EVENT_QUEUE_ATTR_AFFINITY``
* **Added telemetry to dmadev library.**
Added telemetry callback functions which allow for a list of DMA devices,
statistics and other DMA device information to be queried.
* **Added scalar version of the LPM library.**
Added scalar implementation of ``rte_lpm_lookupx4``.

View File

@ -5,3 +5,5 @@ sources = files('rte_dmadev.c')
headers = files('rte_dmadev.h')
indirect_headers += files('rte_dmadev_core.h')
driver_sdk_headers += files('rte_dmadev_pmd.h')
deps += ['telemetry']

View File

@ -11,6 +11,7 @@
#include <rte_malloc.h>
#include <rte_memzone.h>
#include <rte_string_fns.h>
#include <rte_telemetry.h>
#include "rte_dmadev.h"
#include "rte_dmadev_pmd.h"
@ -864,3 +865,132 @@ dma_fp_object_dummy(struct rte_dma_fp_object *obj)
obj->completed_status = dummy_completed_status;
obj->burst_capacity = dummy_burst_capacity;
}
static int
dmadev_handle_dev_list(const char *cmd __rte_unused,
const char *params __rte_unused,
struct rte_tel_data *d)
{
int dev_id;
rte_tel_data_start_array(d, RTE_TEL_INT_VAL);
for (dev_id = 0; dev_id < dma_devices_max; dev_id++)
if (rte_dma_is_valid(dev_id))
rte_tel_data_add_array_int(d, dev_id);
return 0;
}
#define ADD_CAPA(td, dc, c) rte_tel_data_add_dict_int(td, dma_capability_name(c), !!(dc & c))
static int
dmadev_handle_dev_info(const char *cmd __rte_unused,
const char *params, struct rte_tel_data *d)
{
struct rte_dma_info dma_info;
struct rte_tel_data *dma_caps;
int dev_id, ret;
uint64_t dev_capa;
char *end_param;
if (params == NULL || strlen(params) == 0 || !isdigit(*params))
return -EINVAL;
dev_id = strtoul(params, &end_param, 0);
if (*end_param != '\0')
RTE_DMA_LOG(WARNING, "Extra parameters passed to dmadev telemetry command, ignoring");
/* Function info_get validates dev_id so we don't need to. */
ret = rte_dma_info_get(dev_id, &dma_info);
if (ret < 0)
return -EINVAL;
dev_capa = dma_info.dev_capa;
rte_tel_data_start_dict(d);
rte_tel_data_add_dict_string(d, "name", dma_info.dev_name);
rte_tel_data_add_dict_int(d, "nb_vchans", dma_info.nb_vchans);
rte_tel_data_add_dict_int(d, "numa_node", dma_info.numa_node);
rte_tel_data_add_dict_int(d, "max_vchans", dma_info.max_vchans);
rte_tel_data_add_dict_int(d, "max_desc", dma_info.max_desc);
rte_tel_data_add_dict_int(d, "min_desc", dma_info.min_desc);
rte_tel_data_add_dict_int(d, "max_sges", dma_info.max_sges);
dma_caps = rte_tel_data_alloc();
if (!dma_caps)
return -ENOMEM;
rte_tel_data_start_dict(dma_caps);
ADD_CAPA(dma_caps, dev_capa, RTE_DMA_CAPA_MEM_TO_MEM);
ADD_CAPA(dma_caps, dev_capa, RTE_DMA_CAPA_MEM_TO_DEV);
ADD_CAPA(dma_caps, dev_capa, RTE_DMA_CAPA_DEV_TO_MEM);
ADD_CAPA(dma_caps, dev_capa, RTE_DMA_CAPA_DEV_TO_DEV);
ADD_CAPA(dma_caps, dev_capa, RTE_DMA_CAPA_SVA);
ADD_CAPA(dma_caps, dev_capa, RTE_DMA_CAPA_SILENT);
ADD_CAPA(dma_caps, dev_capa, RTE_DMA_CAPA_HANDLES_ERRORS);
ADD_CAPA(dma_caps, dev_capa, RTE_DMA_CAPA_OPS_COPY);
ADD_CAPA(dma_caps, dev_capa, RTE_DMA_CAPA_OPS_COPY_SG);
ADD_CAPA(dma_caps, dev_capa, RTE_DMA_CAPA_OPS_FILL);
rte_tel_data_add_dict_container(d, "capabilities", dma_caps, 0);
return 0;
}
#define ADD_DICT_STAT(s) rte_tel_data_add_dict_u64(d, #s, dma_stats.s)
static int
dmadev_handle_dev_stats(const char *cmd __rte_unused,
const char *params,
struct rte_tel_data *d)
{
struct rte_dma_info dma_info;
struct rte_dma_stats dma_stats;
int dev_id, ret, vchan_id;
char *end_param;
const char *vchan_param;
if (params == NULL || strlen(params) == 0 || !isdigit(*params))
return -EINVAL;
dev_id = strtoul(params, &end_param, 0);
/* Function info_get validates dev_id so we don't need to. */
ret = rte_dma_info_get(dev_id, &dma_info);
if (ret < 0)
return -EINVAL;
/* If the device has one vchan the user does not need to supply the
* vchan id and only the device id is needed, no extra parameters.
*/
if (dma_info.nb_vchans == 1 && *end_param == '\0')
vchan_id = 0;
else {
vchan_param = strtok(end_param, ",");
if (!vchan_param || strlen(vchan_param) == 0 || !isdigit(*vchan_param))
return -EINVAL;
vchan_id = strtoul(vchan_param, &end_param, 0);
}
if (*end_param != '\0')
RTE_DMA_LOG(WARNING, "Extra parameters passed to dmadev telemetry command, ignoring");
ret = rte_dma_stats_get(dev_id, vchan_id, &dma_stats);
if (ret < 0)
return -EINVAL;
rte_tel_data_start_dict(d);
ADD_DICT_STAT(submitted);
ADD_DICT_STAT(completed);
ADD_DICT_STAT(errors);
return 0;
}
RTE_INIT(dmadev_init_telemetry)
{
rte_telemetry_register_cmd("/dmadev/list", dmadev_handle_dev_list,
"Returns list of available dmadev devices by IDs. No parameters.");
rte_telemetry_register_cmd("/dmadev/info", dmadev_handle_dev_info,
"Returns information for a dmadev. Parameters: int dev_id");
rte_telemetry_register_cmd("/dmadev/stats", dmadev_handle_dev_stats,
"Returns the stats for a dmadev vchannel. Parameters: int dev_id, vchan_id (Optional if only one vchannel)");
}