From 26c44f89164d818a9edcbee6d5e208f5e43d889f Mon Sep 17 00:00:00 2001 From: Prasad Pardeshi <prasadp@xilinx.com> Date: Fri, 10 Nov 2023 15:07:34 +0530 Subject: [PATCH] QDMA DPDK reference driver for 2023.2.1 patch release --- QDMA/DPDK/RELEASE | 6 +- .../qdma/qdma_access/qdma_access_version.h | 2 +- QDMA/DPDK/drivers/net/qdma/qdma_ethdev.c | 51 ++++--- QDMA/DPDK/drivers/net/qdma/qdma_vf_ethdev.c | 37 +++++ QDMA/DPDK/drivers/net/qdma/qdma_xdebug.c | 16 ++ QDMA/DPDK/drivers/net/qdma/version.h | 2 +- QDMA/DPDK/examples/qdma_testapp/commands.c | 144 ++++++++++++++++++ 7 files changed, 234 insertions(+), 24 deletions(-) diff --git a/QDMA/DPDK/RELEASE b/QDMA/DPDK/RELEASE index d300616..806779b 100755 --- a/QDMA/DPDK/RELEASE +++ b/QDMA/DPDK/RELEASE @@ -1,4 +1,4 @@ -RELEASE: 2023.2.0 +RELEASE: 2023.2.1 ================= This release is based on DPDK v20.11, v21.11 and v22.11 and @@ -132,6 +132,10 @@ CPM5 - Added support for Tx and Rx queue statistics to enhance debugging capabilities - Added support for latency measurements in Tx and Rx data path to enhance debugging capabilities +2023.2.1 Updates +---------------- +- Added support for latency measurements in Tx and Rx data path for VF + KNOWN ISSUE: ============ - CPM4: diff --git a/QDMA/DPDK/drivers/net/qdma/qdma_access/qdma_access_version.h b/QDMA/DPDK/drivers/net/qdma/qdma_access/qdma_access_version.h index 9503e5a..652a555 100755 --- a/QDMA/DPDK/drivers/net/qdma/qdma_access/qdma_access_version.h +++ b/QDMA/DPDK/drivers/net/qdma/qdma_access/qdma_access_version.h @@ -37,7 +37,7 @@ #define QDMA_VERSION_MAJOR 2023 #define QDMA_VERSION_MINOR 2 -#define QDMA_VERSION_PATCH 0 +#define QDMA_VERSION_PATCH 1 #define QDMA_VERSION_STR \ __stringify(QDMA_VERSION_MAJOR) "." \ diff --git a/QDMA/DPDK/drivers/net/qdma/qdma_ethdev.c b/QDMA/DPDK/drivers/net/qdma/qdma_ethdev.c index 21b83a8..6bd6147 100755 --- a/QDMA/DPDK/drivers/net/qdma/qdma_ethdev.c +++ b/QDMA/DPDK/drivers/net/qdma/qdma_ethdev.c @@ -772,31 +772,40 @@ int qdma_eth_dev_init(struct rte_eth_dev *dev) } #ifdef LATENCY_MEASUREMENT - /* Create a shared memory zone for the txq latency buffer */ - txq_lat_buf_mz = rte_memzone_reserve("TXQ_LAT_BUFFER_ZONE", - LATENCY_MAX_QUEUES * LATENCY_CNT * sizeof(double), - rte_socket_id(), 0); - if (txq_lat_buf_mz == NULL) { - PMD_DRV_LOG(ERR, "Failed to allocate txq latency buffer memzone\n"); - return -1; + /* Create txq and rxq latency measurement shared memory + * if not already created by the VF + */ + if (!h2c_pidx_to_hw_cidx_lat) { + /* Create a shared memory zone for the txq latency buffer */ + txq_lat_buf_mz = rte_memzone_reserve("TXQ_LAT_BUFFER_ZONE", + LATENCY_MAX_QUEUES * LATENCY_CNT * sizeof(double), + rte_socket_id(), 0); + if (txq_lat_buf_mz == NULL) { + PMD_DRV_LOG(ERR, + "Failed to allocate txq latency buffer memzone\n"); + return -1; + } + + /* Get the virtual address of the txq latency buffer */ + h2c_pidx_to_hw_cidx_lat = + (double(*)[LATENCY_CNT])txq_lat_buf_mz->addr; } - /* Get the virtual address of the txq latency buffer */ - h2c_pidx_to_hw_cidx_lat = - (double(*)[LATENCY_CNT])txq_lat_buf_mz->addr; + if (!c2h_pidx_to_cmpt_pidx_lat) { + /* Create a shared memory zone for the rxq latency buffer */ + rxq_lat_buf_mz = rte_memzone_reserve("RXQ_LAT_BUFFER_ZONE", + LATENCY_MAX_QUEUES * LATENCY_CNT * sizeof(double), + rte_socket_id(), 0); + if (rxq_lat_buf_mz == NULL) { + PMD_DRV_LOG(ERR, + "Failed to allocate rxq latency buffer memzone\n"); + return -1; + } - /* Create a shared memory zone for the rxq latency buffer */ - rxq_lat_buf_mz = rte_memzone_reserve("RXQ_LAT_BUFFER_ZONE", - LATENCY_MAX_QUEUES * LATENCY_CNT * sizeof(double), - rte_socket_id(), 0); - if (rxq_lat_buf_mz == NULL) { - PMD_DRV_LOG(ERR, "Failed to allocate rxq latency buffer memzone\n"); - return -1; + /* Get the virtual address of the rxq latency buffer */ + c2h_pidx_to_cmpt_pidx_lat = + (double(*)[LATENCY_CNT])rxq_lat_buf_mz->addr; } - - /* Get the virtual address of the rxq latency buffer */ - c2h_pidx_to_cmpt_pidx_lat = - (double(*)[LATENCY_CNT])rxq_lat_buf_mz->addr; #endif dma_priv->reset_in_progress = 0; diff --git a/QDMA/DPDK/drivers/net/qdma/qdma_vf_ethdev.c b/QDMA/DPDK/drivers/net/qdma/qdma_vf_ethdev.c index f055e6d..219af04 100755 --- a/QDMA/DPDK/drivers/net/qdma/qdma_vf_ethdev.c +++ b/QDMA/DPDK/drivers/net/qdma/qdma_vf_ethdev.c @@ -1144,6 +1144,43 @@ static int eth_qdma_vf_dev_init(struct rte_eth_dev *dev) dma_priv->reset_state = RESET_STATE_IDLE; +#ifdef LATENCY_MEASUREMENT + /* Create txq and rxq latency measurement shared memory + * if not already created by the PF + */ + if (!h2c_pidx_to_hw_cidx_lat) { + /* Create a shared memory zone for the txq latency buffer */ + txq_lat_buf_mz = rte_memzone_reserve("TXQ_LAT_BUFFER_ZONE", + LATENCY_MAX_QUEUES * LATENCY_CNT * sizeof(double), + rte_socket_id(), 0); + if (txq_lat_buf_mz == NULL) { + PMD_DRV_LOG(ERR, + "Failed to allocate txq latency buffer memzone\n"); + return -1; + } + + /* Get the virtual address of the txq latency buffer */ + h2c_pidx_to_hw_cidx_lat = + (double(*)[LATENCY_CNT])txq_lat_buf_mz->addr; + } + + if (!c2h_pidx_to_cmpt_pidx_lat) { + /* Create a shared memory zone for the rxq latency buffer */ + rxq_lat_buf_mz = rte_memzone_reserve("RXQ_LAT_BUFFER_ZONE", + LATENCY_MAX_QUEUES * LATENCY_CNT * sizeof(double), + rte_socket_id(), 0); + if (rxq_lat_buf_mz == NULL) { + PMD_DRV_LOG(ERR, + "Failed to allocate rxq latency buffer memzone\n"); + return -1; + } + + /* Get the virtual address of the rxq latency buffer */ + c2h_pidx_to_cmpt_pidx_lat = + (double(*)[LATENCY_CNT])rxq_lat_buf_mz->addr; + } +#endif + PMD_DRV_LOG(INFO, "VF-%d(DEVFN) QDMA device driver probe:", dma_priv->func_id); diff --git a/QDMA/DPDK/drivers/net/qdma/qdma_xdebug.c b/QDMA/DPDK/drivers/net/qdma/qdma_xdebug.c index 1811f21..4cade04 100755 --- a/QDMA/DPDK/drivers/net/qdma/qdma_xdebug.c +++ b/QDMA/DPDK/drivers/net/qdma/qdma_xdebug.c @@ -1283,6 +1283,9 @@ int qdma_tx_qstats_clear(struct rte_eth_dev *dev, uint16_t queue) { struct qdma_tx_queue *txq; int ret; +#ifdef LATENCY_MEASUREMENT + int i; +#endif if (queue >= dev->data->nb_tx_queues) { xdebug_info("TX queue_id=%d not configured\n", queue); @@ -1297,6 +1300,11 @@ int qdma_tx_qstats_clear(struct rte_eth_dev *dev, uint16_t queue) memset(&txq->qstats, 0, sizeof(struct qdma_txq_stats)); +#ifdef LATENCY_MEASUREMENT + for (i = 0; i < LATENCY_CNT; i++) + h2c_pidx_to_hw_cidx_lat[queue][i] = 0; +#endif + xdebug_info("\nCleared Tx queue stats for qid: %d\n", queue); @@ -1314,6 +1322,9 @@ int qdma_rx_qstats_clear(struct rte_eth_dev *dev, uint16_t queue) { struct qdma_rx_queue *rxq; int ret; +#ifdef LATENCY_MEASUREMENT + int i; +#endif if (queue >= dev->data->nb_rx_queues) { xdebug_info("RX queue_id=%d not configured\n", queue); @@ -1328,6 +1339,11 @@ int qdma_rx_qstats_clear(struct rte_eth_dev *dev, uint16_t queue) memset(&rxq->qstats, 0, sizeof(struct qdma_rxq_stats)); +#ifdef LATENCY_MEASUREMENT + for (i = 0; i < LATENCY_CNT; i++) + c2h_pidx_to_cmpt_pidx_lat[queue][i] = 0; +#endif + xdebug_info("\nCleared Rx queue stats for qid: %d\n", queue); diff --git a/QDMA/DPDK/drivers/net/qdma/version.h b/QDMA/DPDK/drivers/net/qdma/version.h index e17690d..8e44e3a 100755 --- a/QDMA/DPDK/drivers/net/qdma/version.h +++ b/QDMA/DPDK/drivers/net/qdma/version.h @@ -39,7 +39,7 @@ #define QDMA_PMD_MAJOR 2023 #define QDMA_PMD_MINOR 2 -#define QDMA_PMD_PATCHLEVEL 0 +#define QDMA_PMD_PATCHLEVEL 1 #define QDMA_PMD_VERSION \ qdma_stringify(QDMA_PMD_MAJOR) "." \ diff --git a/QDMA/DPDK/examples/qdma_testapp/commands.c b/QDMA/DPDK/examples/qdma_testapp/commands.c index c87bb9b..20e8af7 100755 --- a/QDMA/DPDK/examples/qdma_testapp/commands.c +++ b/QDMA/DPDK/examples/qdma_testapp/commands.c @@ -170,6 +170,10 @@ static void cmd_help_parsed(__attribute__((unused)) void *parsed_result, ":Reads the field info for the specified number of registers\n" "\tqueue_dump <port-id> <queue-id> " ":To dump the queue-context of a queue-number\n" + "\tqstats <port-id> <queue-id> " + ":To dump the queue-stats of a queue-number\n" + "\tqstats_clr <port-id> <queue-id> " + ":To clear the queue-stats of a queue-number\n" "\tdesc_dump <port-id> <queue-id> " ":To dump the descriptor-fields of a " "queue-number\n" @@ -1233,6 +1237,144 @@ cmdline_parse_inst_t cmd_obj_queue_dump = { }; +/*Command queue-stats dump*/ + +struct cmd_obj_qstats_result { + cmdline_fixed_string_t action; + cmdline_fixed_string_t port_id; + cmdline_fixed_string_t queue_id; +}; + +static void cmd_obj_qstats_parsed(void *parsed_result, + struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_obj_qstats_result *res = parsed_result; + + cmdline_printf(cl, "queue-dump on Port:%s, queue-id:%s\n\n", + res->port_id, res->queue_id); + + { + int port_id = atoi(res->port_id); + int qid = atoi(res->queue_id); + int bar_id = 0x0; + + bar_id = pinfo[port_id].config_bar_idx; + if (bar_id < 0) { + cmdline_printf(cl, "Error: fetching QDMA config BAR-id " + "on port-id:%d not supported\n Please " + "enter valid port-id\n", port_id); + return; + } + if (port_id >= num_ports) { + cmdline_printf(cl, "Error: port-id:%d not supported\n " + "Please enter valid port-id\n", + port_id); + return; + } + if ((unsigned int)qid >= pinfo[port_id].num_queues) { + cmdline_printf(cl, "Error: queue-id:%d is greater than " + "the number of confgiured queues in " + "the port\n Please enter valid " + "queue-id\n", qid); + return; + } + rte_pmd_qdma_qstats(port_id, qid); + } +} + +cmdline_parse_token_string_t cmd_obj_action_qstats = + TOKEN_STRING_INITIALIZER(struct cmd_obj_qstats_result, action, + "qstats"); +cmdline_parse_token_string_t cmd_obj_qstats_port_id = + TOKEN_STRING_INITIALIZER(struct cmd_obj_qstats_result, port_id, + NULL); +cmdline_parse_token_string_t cmd_obj_qstats_queue_id = + TOKEN_STRING_INITIALIZER(struct cmd_obj_qstats_result, queue_id, + NULL); + +cmdline_parse_inst_t cmd_obj_qstats = { + .f = cmd_obj_qstats_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "qstats port-id queue_id", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_obj_action_qstats, + (void *)&cmd_obj_qstats_port_id, + (void *)&cmd_obj_qstats_queue_id, + NULL, + }, + +}; + +/*Command queue-stats-cleaar dump*/ + +struct cmd_obj_qstats_clr_result { + cmdline_fixed_string_t action; + cmdline_fixed_string_t port_id; + cmdline_fixed_string_t queue_id; +}; + +static void cmd_obj_qstats_clr_parsed(void *parsed_result, + struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_obj_qstats_clr_result *res = parsed_result; + + cmdline_printf(cl, "queue-dump on Port:%s, queue-id:%s\n\n", + res->port_id, res->queue_id); + + { + int port_id = atoi(res->port_id); + int qid = atoi(res->queue_id); + int bar_id = 0x0; + + bar_id = pinfo[port_id].config_bar_idx; + if (bar_id < 0) { + cmdline_printf(cl, "Error: fetching QDMA config BAR-id " + "on port-id:%d not supported\n Please " + "enter valid port-id\n", port_id); + return; + } + if (port_id >= num_ports) { + cmdline_printf(cl, "Error: port-id:%d not supported\n " + "Please enter valid port-id\n", + port_id); + return; + } + if ((unsigned int)qid >= pinfo[port_id].num_queues) { + cmdline_printf(cl, "Error: queue-id:%d is greater than " + "the number of confgiured queues in " + "the port\n Please enter valid " + "queue-id\n", qid); + return; + } + rte_pmd_qdma_qstats_clear(port_id, qid); + } +} + +cmdline_parse_token_string_t cmd_obj_action_qstats_clr = + TOKEN_STRING_INITIALIZER(struct cmd_obj_qstats_clr_result, action, + "qstats_clr"); +cmdline_parse_token_string_t cmd_obj_qstats_clr_port_id = + TOKEN_STRING_INITIALIZER(struct cmd_obj_qstats_clr_result, port_id, + NULL); +cmdline_parse_token_string_t cmd_obj_qstats_clr_queue_id = + TOKEN_STRING_INITIALIZER(struct cmd_obj_qstats_clr_result, queue_id, + NULL); + +cmdline_parse_inst_t cmd_obj_qstats_clr = { + .f = cmd_obj_qstats_clr_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "qstats_clr port-id queue_id", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_obj_action_qstats_clr, + (void *)&cmd_obj_qstats_clr_port_id, + (void *)&cmd_obj_qstats_clr_queue_id, + NULL, + }, + +}; + /* Command descriptor dump */ struct cmd_obj_desc_dump_result { @@ -1375,6 +1517,8 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_obj_reg_dump, (cmdline_parse_inst_t *)&cmd_obj_reg_info_read, (cmdline_parse_inst_t *)&cmd_obj_queue_dump, + (cmdline_parse_inst_t *)&cmd_obj_qstats, + (cmdline_parse_inst_t *)&cmd_obj_qstats_clr, (cmdline_parse_inst_t *)&cmd_obj_desc_dump, (cmdline_parse_inst_t *)&cmd_obj_load_cmds, (cmdline_parse_inst_t *)&cmd_help, -- GitLab