From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 00D9A42B9E; Thu, 25 May 2023 20:47:37 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C247440DF8; Thu, 25 May 2023 20:47:37 +0200 (CEST) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by mails.dpdk.org (Postfix) with ESMTP id D691840DDB for ; Thu, 25 May 2023 20:47:34 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1685040456; x=1716576456; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Zu6xYcaD13uzUkxz0rKYhMJ+LvnzCyQ/XuZPl0FMFSc=; b=nGz6+g5pOfQ+TFFHw0scnmOZ01ihwfej8tKVh/9+GSBu8RhC2MkWp1UL +uoTOitkp09nfUka33+x+6n7xFO9D2Ru12EsKVlHQtN3arj8F7kiGOPVz R9u10dr7ManpzC5iOirQPU+LWiAxELyD2X03uFRoqlTw4OtYb49FAYR/f /B+emMVIytc6eKxeQz9ewitiZ2zL3ujupFOpdK53QtaMxpJMUCULoF7N4 THwz/SktrFtNMJYlvFRELubZpeDSuhGirJwZgV6v4OtGVZfsPqA2tpPdn FnvJUwq1YnDFv+7wKbx4qDk7JEAbP967Em+Q8k9xffQqiBDQGuumwCvWf A==; X-IronPort-AV: E=McAfee;i="6600,9927,10721"; a="352832239" X-IronPort-AV: E=Sophos;i="6.00,191,1681196400"; d="scan'208";a="352832239" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 May 2023 11:47:34 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10721"; a="774789262" X-IronPort-AV: E=Sophos;i="6.00,191,1681196400"; d="scan'208";a="774789262" Received: from txanpdk02.an.intel.com ([10.123.117.76]) by fmsmga004.fm.intel.com with ESMTP; 25 May 2023 11:47:33 -0700 From: Abdullah Sevincer To: dev@dpdk.org Cc: jerinj@marvell.com, reshma.pattan@intel.com, stephen@networkplumber.org, Abdullah Sevincer Subject: [PATCH v17] app/procinfo: display eventdev xstats Date: Thu, 25 May 2023 13:47:31 -0500 Message-Id: <20230525184731.3056328-1-abdullah.sevincer@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230525164127.3046135-1-abdullah.sevincer@intel.com> References: <20230525164127.3046135-1-abdullah.sevincer@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 This commit extends proc-info application to display xstats for the eventdev devices. New command line arguments are introduced to display xstats for eventdev devices. The command example is like: For displaying a specific port stats (e.g. port 1): ./dpdk-proc-info -- --show-edev-port-xstats=1:0 If any xstats parameters for eventdev passed through proc-info command line, proc-info will only display requested eventdev data and exit. Users should not pass any eventdev xstats parameters if they desire to dump other proc-info data such as Rx/Tx descriptor dump. More information can be found in proc-info app doc. Signed-off-by: Abdullah Sevincer --- app/proc-info/main.c | 375 ++++++++++++++++++++++++++++++++- app/proc-info/meson.build | 2 +- doc/guides/tools/proc_info.rst | 26 ++- 3 files changed, 400 insertions(+), 3 deletions(-) diff --git a/app/proc-info/main.c b/app/proc-info/main.c index 53e852a07c..be63eace69 100644 --- a/app/proc-info/main.c +++ b/app/proc-info/main.c @@ -40,6 +40,7 @@ #include #include #include +#include /* Maximum long option length for option parsing. */ #define MAX_LONG_OPT_SZ 64 @@ -121,6 +122,25 @@ static uint32_t enable_shw_module_eeprom; static uint32_t enable_shw_rx_desc_dump; static uint32_t enable_shw_tx_desc_dump; +/* Note: Port_queue_id in xstats APIs is 8 bits, so we have a maximum of + * 256 ports and queues for event_Dev + */ +#define MAX_PORTS_QUEUES 256 + +struct eventdev_params { + uint16_t ports[MAX_PORTS_QUEUES]; + uint16_t queues[MAX_PORTS_QUEUES]; + uint16_t num_queues; + uint16_t num_ports; + uint8_t shw_all_queues:1, + shw_all_ports:1, + dump_xstats:1, + reset_xstats:1, + shw_device_xstats:1; +}; + +static struct eventdev_params eventdev_var[RTE_EVENT_MAX_DEVS]; + #define DESC_PARAM_NUM 3 struct desc_param { @@ -172,7 +192,12 @@ proc_info_usage(const char *prgname) "offset: The offset of the descriptor starting from tail. " "num: The number of the descriptors to dump.\n" " --iter-mempool=name: iterate mempool elements to display content\n" - " --dump-regs=file-prefix: dump registers to file with the file-prefix\n", + " --dump-regs=file-prefix: dump registers to file with the file-prefix\n" + " --show-edev-queue-xstats=queue_num:evdev_id or *:evdev_id to get queue xstats for specified queue or all queues;\n" + " --show-edev-port-xstats=port_num:evdev_id or *:evdev_id to get queue xstats for specified port or all ports;\n" + " --edev-dump-xstats=evdev_id to dump all event_dev xstats for specified eventdev device;\n" + " --edev-reset-xstats=evdev_id to reset event_dev xstats after reading;\n" + " --show-edev-device-xstats=evdev_id to get event_dev device xstats for specified eventdev device;\n", prgname); } @@ -236,6 +261,125 @@ parse_descriptor_param(char *list, struct desc_param *desc) return 0; } +static int +parse_eventdev_id(const char *str) +{ + unsigned long evdev_id; + char *endp; + + evdev_id = strtoul(str, &endp, 0); + + if (*str == '\0' || *endp != '\0' || evdev_id >= rte_event_dev_count()) { + fprintf(stderr, "Invalid eventdev id: %s\n", str); + return -1; + } + + return evdev_id; +} + +static int +parse_eventdev_dump_xstats_params(const char *list) +{ + int evdev_id = parse_eventdev_id(list); + + if (evdev_id < 0) + return -EINVAL; + + eventdev_var[evdev_id].dump_xstats = 1; + + return 0; +} + +static int +parse_eventdev_reset_xstats_params(const char *list) +{ + int evdev_id = parse_eventdev_id(list); + + if (evdev_id < 0) + return -EINVAL; + + eventdev_var[evdev_id].reset_xstats = 1; + + return 0; +} + +static int +parse_eventdev_device_xstats_params(const char *list) +{ + int evdev_id = parse_eventdev_id(list); + + if (evdev_id < 0) + return -EINVAL; + + eventdev_var[evdev_id].shw_device_xstats = 1; + + return 0; +} + +static int +parse_eventdev_queue_xstats_params(const char *list) +{ + uint16_t queue_id; + uint16_t evdev_id; + + if (sscanf(list, "*:%hu", &evdev_id) == 1) { + if (evdev_id >= rte_event_dev_count()) { + printf("Invalid eventdev id: %hu\n", evdev_id); + return -EINVAL; + } + eventdev_var[evdev_id].shw_all_queues = 1; + } else if (sscanf(list, "%hu:%hu", &queue_id, &evdev_id) == 2) { + if (evdev_id >= rte_event_dev_count()) { + printf("Invalid eventdev id: %hu\n", evdev_id); + return -EINVAL; + } + + if (queue_id >= MAX_PORTS_QUEUES) { + printf("Invalid queue_id: %hu\n", queue_id); + return -EINVAL; + } + + eventdev_var[evdev_id].queues[eventdev_var[evdev_id].num_queues] = queue_id; + eventdev_var[evdev_id].num_queues++; + } else { + return -EINVAL; + } + + return 0; +} + +static int +parse_eventdev_port_xstats_params(const char *list) +{ + uint16_t port_id; + uint16_t evdev_id; + + if (sscanf(list, "*:%hu", &evdev_id) == 1) { + if (evdev_id >= rte_event_dev_count()) { + printf("Invalid eventdev id: %hu\n", evdev_id); + return -EINVAL; + } + eventdev_var[evdev_id].shw_all_ports = 1; + } else if (sscanf(list, "%hu:%hu", &port_id, &evdev_id) == 2) { + if (evdev_id >= rte_event_dev_count()) { + printf("Invalid eventdev id: %hu\n", evdev_id); + return -EINVAL; + } + + if (port_id >= MAX_PORTS_QUEUES) { + printf("Invalid port_id: %hu\n", port_id); + return -EINVAL; + } + + eventdev_var[evdev_id].ports[eventdev_var[evdev_id].num_ports] = port_id; + eventdev_var[evdev_id].num_ports++; + } else { + return -EINVAL; + } + + return 0; +} + static int proc_info_preparse_args(int argc, char **argv) { @@ -302,6 +446,11 @@ proc_info_parse_args(int argc, char **argv) {"show-module-eeprom", 0, NULL, 0}, {"show-rx-descriptor", required_argument, NULL, 1}, {"show-tx-descriptor", required_argument, NULL, 1}, + {"show-edev-queue-xstats", required_argument, NULL, 0}, + {"show-edev-port-xstats", required_argument, NULL, 0}, + {"edev-dump-xstats", required_argument, NULL, 0}, + {"edev-reset-xstats", required_argument, NULL, 0}, + {"show-edev-device-xstats", required_argument, NULL, 0}, {NULL, 0, 0, 0} }; @@ -385,6 +534,47 @@ proc_info_parse_args(int argc, char **argv) else if (!strncmp(long_option[option_index].name, "show-module-eeprom", MAX_LONG_OPT_SZ)) enable_shw_module_eeprom = 1; + else if (!strncmp(long_option[option_index].name, + "edev-dump-xstats", MAX_LONG_OPT_SZ)) { + int ret = parse_eventdev_dump_xstats_params(optarg); + if (ret < 0) { + fprintf(stderr, "Error parsing eventdev dump xstats params: %s\n", + strerror(-ret)); + return -1; + } + } else if (!strncmp(long_option[option_index].name, + "edev-reset-xstats", MAX_LONG_OPT_SZ)) { + int ret = parse_eventdev_reset_xstats_params(optarg); + if (ret < 0) { + fprintf(stderr, "Error parsing eventdev reset xstats params: %s\n", + strerror(-ret)); + return -1; + } + } else if (!strncmp(long_option[option_index].name, + "show-edev-device-xstats", MAX_LONG_OPT_SZ)) { + int ret = parse_eventdev_device_xstats_params(optarg); + if (ret < 0) { + fprintf(stderr, "Error parsing eventdev reset xstats params: %s\n", + strerror(-ret)); + return -1; + } + } else if (!strncmp(long_option[option_index].name, + "show-edev-queue-xstats", MAX_LONG_OPT_SZ)) { + int ret = parse_eventdev_queue_xstats_params(optarg); + if (ret < 0) { + fprintf(stderr, "Error parsing eventdev queue xstats params: %s\n", + strerror(-ret)); + return -1; + } + } else if (!strncmp(long_option[option_index].name, + "show-edev-port-xstats", MAX_LONG_OPT_SZ)) { + int ret = parse_eventdev_port_xstats_params(optarg); + if (ret < 0) { + fprintf(stderr, "Error parsing eventdev port xstats params: %s\n", + strerror(-ret)); + return -1; + } + } break; case 1: /* Print xstat single value given by name*/ @@ -1744,6 +1934,186 @@ nic_tx_descriptor_display(uint16_t port_id, struct desc_param *desc) strerror(-ret)); } +static void +xstats_display(uint8_t dev_id, + enum rte_event_dev_xstats_mode mode, + uint8_t queue_port_id) +{ + int ret; + struct rte_event_dev_xstats_name *xstats_names; + uint64_t *ids; + uint64_t *values; + int size; + int i; + + size = rte_event_dev_xstats_names_get(dev_id, + mode, + queue_port_id, + NULL, /* names */ + NULL, /* ids */ + 0); /* num */ + + if (size < 0) + rte_panic("rte_event_dev_xstats_names_get err %d\n", size); + + if (size == 0) { + printf( + "No stats available for this item, mode=%d, queue_port_id=%d\n", + mode, queue_port_id); + return; + } + + /* Get memory to hold stat names, IDs, and values */ + xstats_names = malloc(sizeof(struct rte_event_dev_xstats_name) * (unsigned int)size); + ids = malloc(sizeof(unsigned int) * size); + + if (!xstats_names || !ids) + rte_panic("unable to alloc memory for stats retrieval\n"); + + ret = rte_event_dev_xstats_names_get(dev_id, mode, queue_port_id, + xstats_names, ids, + (unsigned int)size); + if (ret != size) + rte_panic("rte_event_dev_xstats_names_get err %d\n", ret); + + values = malloc(sizeof(uint64_t) * size); + if (!values) + rte_panic("unable to alloc memory for stats retrieval\n"); + + ret = rte_event_dev_xstats_get(dev_id, mode, queue_port_id, + ids, values, size); + + if (ret != size) + rte_panic("rte_event_dev_xstats_get err %d\n", ret); + + for (i = 0; i < size; i++) { + printf("id %"PRIu64" %s = %"PRIu64"\n", + ids[i], &xstats_names[i].name[0], values[i]); + } + + free(values); + free(xstats_names); + free(ids); + +} + +static void +xstats_reset(uint8_t dev_id, + enum rte_event_dev_xstats_mode mode, + uint8_t queue_port_id) +{ + int ret; + struct rte_event_dev_xstats_name *xstats_names; + uint64_t *ids; + int size; + + size = rte_event_dev_xstats_names_get(dev_id, + mode, + queue_port_id, + NULL, /* names */ + NULL, /* ids */ + 0); /* num */ + + if (size < 0) + rte_panic("rte_event_dev_xstats_names_get err %d\n", size); + + if (size == 0) { + printf( + "No stats available for this item, mode=%d, queue_port_id=%d\n", + mode, queue_port_id); + return; + } + + /* Get memory to hold stat names, IDs, and values */ + xstats_names = malloc(sizeof(struct rte_event_dev_xstats_name) * (unsigned int)size); + ids = malloc(sizeof(unsigned int) * size); + + if (!xstats_names || !ids) + rte_panic("unable to alloc memory for stats retrieval\n"); + + ret = rte_event_dev_xstats_names_get(dev_id, mode, queue_port_id, + xstats_names, ids, + (unsigned int)size); + if (ret != size) + rte_panic("rte_event_dev_xstats_names_get err %d\n", ret); + + rte_event_dev_xstats_reset(dev_id, mode, queue_port_id, + ids, size); + + free(xstats_names); + free(ids); + +} + +static int +process_eventdev_xstats(void) +{ + int i; + int j; + int processing_eventdev_xstats = 0; + + for (i = 0; i < RTE_EVENT_MAX_DEVS; i++) { + + if (!processing_eventdev_xstats) + processing_eventdev_xstats = 1; + + if (eventdev_var[i].dump_xstats) { + int ret = rte_event_dev_dump(i, stdout); + + if (ret) + rte_panic("dump failed with err=%d\n", ret); + } + + if (eventdev_var[i].shw_device_xstats == 1) { + xstats_display(i, RTE_EVENT_DEV_XSTATS_DEVICE, 0); + + if (eventdev_var[i].reset_xstats == 1) + xstats_reset(i, RTE_EVENT_DEV_XSTATS_DEVICE, 0); + } + + if (eventdev_var[i].shw_all_ports == 1) { + for (j = 0; j < MAX_PORTS_QUEUES; j++) { + xstats_display(i, RTE_EVENT_DEV_XSTATS_PORT, j); + + if (eventdev_var[i].reset_xstats == 1) + xstats_reset(i, RTE_EVENT_DEV_XSTATS_PORT, j); + } + } else { + for (j = 0; j < eventdev_var[i].num_ports; j++) { + xstats_display(i, RTE_EVENT_DEV_XSTATS_PORT, + eventdev_var[i].ports[j]); + + if (eventdev_var[i].reset_xstats == 1) + xstats_reset(i, RTE_EVENT_DEV_XSTATS_PORT, + eventdev_var[i].ports[j]); + } + } + + if (eventdev_var[i].shw_all_queues == 1) { + for (j = 0; j < MAX_PORTS_QUEUES; j++) { + xstats_display(i, RTE_EVENT_DEV_XSTATS_QUEUE, j); + + if (eventdev_var[i].reset_xstats == 1) + xstats_reset(i, RTE_EVENT_DEV_XSTATS_QUEUE, j); + } + } else { + for (j = 0; j < eventdev_var[i].num_queues; j++) { + xstats_display(i, RTE_EVENT_DEV_XSTATS_QUEUE, + eventdev_var[i].queues[j]); + + if (eventdev_var[i].reset_xstats == 1) + xstats_reset(i, RTE_EVENT_DEV_XSTATS_QUEUE, + eventdev_var[i].queues[j]); + } + } + } + + if (processing_eventdev_xstats) + return 1; + + return 0; +} + int main(int argc, char **argv) { @@ -1794,6 +2164,9 @@ main(int argc, char **argv) return 0; } + if (process_eventdev_xstats()) + return 0; + nb_ports = rte_eth_dev_count_avail(); if (nb_ports == 0) rte_exit(EXIT_FAILURE, "No Ethernet ports - bye\n"); diff --git a/app/proc-info/meson.build b/app/proc-info/meson.build index 1563ce656a..4f83f29a64 100644 --- a/app/proc-info/meson.build +++ b/app/proc-info/meson.build @@ -8,7 +8,7 @@ if is_windows endif sources = files('main.c') -deps += ['ethdev', 'security'] +deps += ['ethdev', 'security', 'eventdev'] if dpdk_conf.has('RTE_LIB_METRICS') deps += 'metrics' endif diff --git a/doc/guides/tools/proc_info.rst b/doc/guides/tools/proc_info.rst index cf3502a8cb..bb483afbce 100644 --- a/doc/guides/tools/proc_info.rst +++ b/doc/guides/tools/proc_info.rst @@ -22,7 +22,9 @@ The application has a number of command line options: --show-ring[=name] | --show-mempool[=name] | --iter-mempool=name | --show-port-private | --version | --firmware-version | --show-rss-reta | --show-module-eeprom | --show-rx-descriptor queue_id:offset:num | - --show-tx-descriptor queue_id:offset:num ] + --show-tx-descriptor queue_id:offset:num | --show-edev-queue-xstats=queue_num:evdev_id | + --show-edev-port-xstats=port_num :evdev_id | --edev-dump-xstats=evdev_id | + --edev-reset-xstats=evdev_id | --show-edev-device-xstats=evdev_id] Parameters ~~~~~~~~~~ @@ -101,6 +103,28 @@ queue_id: A Tx queue identifier on this port. offset: The offset of the descriptor starting from tail. num: The number of the descriptors to dump. +**--show-edev-queue-xstats queue_num:evdev_id** +The show-edev-queue-xstats parameter enables stats for specified queue or all queues. +queue_num: The queue number to get queue xstats for this specified queue or * for all queues. +evdev_id: Id of the eventdev device to display xstats. + +**--show-edev-port-xstats port_num:evdev_id** +The show-edev-port-xstats parameter enables stats for specified port or all ports. +port_num: The port number to get port xstats for this specified port or * for all ports. +evdev_id: Id of the eventdev device to display xstats. + +**--edev-dump-xstats evdev_id** +The edev-dump-xstats parameter dumps all eventdev stats. +evdev_id: Id of the eventdev device to display xstats. + +**--edev-reset-xstats evdev_id** +The edev-reset-xstats parameter resets eventdev xstats after reading. +evdev_id: Id of the eventdev device to display xstats. + +**--show-edev-device-xstats evdev_id** +The show-edev-device-xstats parameter displays eventdev device xstats. +evdev_id: Id of the eventdev device to display xstats. + Limitations ----------- -- 2.25.1