Enable direct rearm mode in l3fwd. Users can use parameters: '--direct-rearm=(rx_portid,rx_queueid,tx_portid,tx_queueid)' to enable direct rearm.
Suggested-by: Honnappa Nagarahalli <honnappa.nagaraha...@arm.com> Signed-off-by: Feifei Wang <feifei.wa...@arm.com> Reviewed-by: Ruifeng Wang <ruifeng.w...@arm.com> Reviewed-by: Honnappa Nagarahalli <honnappa.nagaraha...@arm.com> --- examples/l3fwd/l3fwd.h | 12 +++++ examples/l3fwd/l3fwd_lpm.c | 22 +++++++++ examples/l3fwd/main.c | 94 +++++++++++++++++++++++++++++++++++++- 3 files changed, 127 insertions(+), 1 deletion(-) diff --git a/examples/l3fwd/l3fwd.h b/examples/l3fwd/l3fwd.h index 40b5f32a9e..db097e344c 100644 --- a/examples/l3fwd/l3fwd.h +++ b/examples/l3fwd/l3fwd.h @@ -57,6 +57,10 @@ #endif #define HASH_ENTRY_NUMBER_DEFAULT 16 +/* MAX number of direct rearm mapping entry */ +#define MAX_DIRECT_REARM_ENTRY_NUMBER 16 +#define MAX_DIRECT_REARM_QUEUE_PER_PORT 8 + struct parm_cfg { const char *rule_ipv4_name; const char *rule_ipv6_name; @@ -114,6 +118,14 @@ extern struct parm_cfg parm_config; extern struct acl_algorithms acl_alg[]; +/* Used in direct rearm mode */ +extern bool enabled_direct_rearm; +extern uint8_t direct_rearm_entry_number; +extern bool queue_enabled_direct_rearm[RTE_MAX_ETHPORTS][MAX_DIRECT_REARM_QUEUE_PER_PORT]; +extern uint16_t direct_rearm_map_tx_port[RTE_MAX_ETHPORTS][MAX_DIRECT_REARM_QUEUE_PER_PORT]; +extern uint16_t direct_rearm_map_tx_queue[RTE_MAX_ETHPORTS][MAX_DIRECT_REARM_QUEUE_PER_PORT]; +extern uint8_t direct_rearm_entry_idx[RTE_MAX_ETHPORTS][MAX_DIRECT_REARM_QUEUE_PER_PORT]; + /* Send burst of packets on an output interface */ static inline int send_burst(struct lcore_conf *qconf, uint16_t n, uint16_t port) diff --git a/examples/l3fwd/l3fwd_lpm.c b/examples/l3fwd/l3fwd_lpm.c index 22d7f61a42..973fe70aae 100644 --- a/examples/l3fwd/l3fwd_lpm.c +++ b/examples/l3fwd/l3fwd_lpm.c @@ -150,6 +150,8 @@ lpm_main_loop(__rte_unused void *dummy) int i, nb_rx; uint16_t portid; uint8_t queueid; + uint8_t idx; + struct rte_eth_txq_data txq_data[MAX_DIRECT_REARM_ENTRY_NUMBER]; struct lcore_conf *qconf; const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * BURST_TX_DRAIN_US; @@ -175,6 +177,20 @@ lpm_main_loop(__rte_unused void *dummy) lcore_id, portid, queueid); } + if (enabled_direct_rearm) { + uint16_t tx_portid; + uint8_t tx_queueid; + + for (i = 0; i < n_rx_q; i++) { + portid = qconf->rx_queue_list[i].port_id; + queueid = qconf->rx_queue_list[i].queue_id; + tx_portid = direct_rearm_map_tx_port[portid][queueid]; + tx_queueid = direct_rearm_map_tx_queue[portid][queueid]; + idx = direct_rearm_entry_idx[portid][queueid]; + rte_eth_tx_queue_data_get(tx_portid, tx_queueid, &(txq_data[idx])); + } + } + cur_tsc = rte_rdtsc(); prev_tsc = cur_tsc; @@ -205,6 +221,12 @@ lpm_main_loop(__rte_unused void *dummy) for (i = 0; i < n_rx_q; ++i) { portid = qconf->rx_queue_list[i].port_id; queueid = qconf->rx_queue_list[i].queue_id; + + if (queue_enabled_direct_rearm[portid][queueid]) { + idx = direct_rearm_entry_idx[portid][queueid]; + rte_eth_rx_direct_rearm(portid, queueid, &(txq_data[idx])); + } + nb_rx = rte_eth_rx_burst(portid, queueid, pkts_burst, MAX_PKT_BURST); if (nb_rx == 0) diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c index e090328fcc..2e9c5c0dc4 100644 --- a/examples/l3fwd/main.c +++ b/examples/l3fwd/main.c @@ -91,6 +91,20 @@ uint32_t enabled_port_mask; int ipv6; /**< ipv6 is false by default. */ uint32_t hash_entry_number = HASH_ENTRY_NUMBER_DEFAULT; +/* Used for direct rearm mode */ +bool enabled_direct_rearm;/**< Flag to enable direct rearm mode. */ +uint8_t direct_rearm_entry_number; /**< Number of entry for direct rearm map. */ +/**< Direct rearm config parameters. */ +uint16_t direct_rearm_config[MAX_DIRECT_REARM_ENTRY_NUMBER][4]; +/**< Enable direct rearm flag for Rx queue . */ +bool queue_enabled_direct_rearm[RTE_MAX_ETHPORTS][MAX_DIRECT_REARM_QUEUE_PER_PORT]; +/**< Matrix for Rx queue mapping Tx port in direct rearm mode. */ +uint16_t direct_rearm_map_tx_port[RTE_MAX_ETHPORTS][MAX_DIRECT_REARM_QUEUE_PER_PORT]; +/**< Matrix for Rx queue mapping Tx queue in direct rearm mode. */ +uint16_t direct_rearm_map_tx_queue[RTE_MAX_ETHPORTS][MAX_DIRECT_REARM_QUEUE_PER_PORT]; +/**< Matrix for Rx queue mapping entry idx in direct rearm mode. */ +uint8_t direct_rearm_entry_idx[RTE_MAX_ETHPORTS][MAX_DIRECT_REARM_QUEUE_PER_PORT]; + struct lcore_conf lcore_conf[RTE_MAX_LCORE]; struct parm_cfg parm_config; @@ -403,6 +417,7 @@ print_usage(const char *prgname) " [--mode]" " [--eventq-sched]" " [--event-vector [--event-vector-size SIZE] [--event-vector-tmo NS]]" + " --direct-rearm (rx_port, rx_queue, tx_port, tx_queue)[,(rx_port, rx_queue, tx_port, tx_queue)]" " [-E]" " [-L]\n\n" @@ -436,6 +451,7 @@ print_usage(const char *prgname) " --event-vector: Enable event vectorization.\n" " --event-vector-size: Max vector size if event vectorization is enabled.\n" " --event-vector-tmo: Max timeout to form vector in nanoseconds if event vectorization is enabled\n" + " --direct-rearm (rx_port, rx_queue, tx_port, tx_queue): Put Tx queue sw-ring buffers into Rx queue\n" " -E : Enable exact match, legacy flag please use --lookup=em instead\n" " -L : Enable longest prefix match, legacy flag please use --lookup=lpm instead\n" " --rule_ipv4=FILE: Specify the ipv4 rules entries file.\n" @@ -670,6 +686,53 @@ parse_lookup(const char *optarg) return 0; } +static int +parse_direct_rearm(const char *q_arg) +{ + char s[256]; + const char *p, *p0 = q_arg; + char *end; + enum fieldnames { + FLD_RX_PORT = 0, + FLD_RX_QUEUE, + FLD_TX_PORT, + FLD_TX_QUEUE, + _NUM_FLD + }; + unsigned long int_fld[_NUM_FLD]; + char *str_fld[_NUM_FLD]; + int i; + unsigned int size; + + while ((p = strchr(p0, '(')) != NULL) { + ++p; + p0 = strchr(p, ')'); + if (p0 == NULL) + return -1; + + size = p0 - p; + if (size >= sizeof(s)) + return -1; + + snprintf(s, sizeof(s), "%.*s", size, p); + if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') != _NUM_FLD) + return -1; + for (i = 0; i < _NUM_FLD; i++) { + errno = 0; + int_fld[i] = strtoul(str_fld[i], &end, 0); + if (errno != 0 || end == str_fld[i] || int_fld[i] > 255) + return -1; + } + + direct_rearm_config[direct_rearm_entry_number][0] = int_fld[FLD_RX_PORT]; + direct_rearm_config[direct_rearm_entry_number][1] = int_fld[FLD_RX_QUEUE]; + direct_rearm_config[direct_rearm_entry_number][2] = int_fld[FLD_TX_PORT]; + direct_rearm_config[direct_rearm_entry_number][3] = int_fld[FLD_TX_QUEUE]; + ++direct_rearm_entry_number; + } + return 0; +} + #define MAX_JUMBO_PKT_LEN 9600 static const char short_options[] = @@ -696,6 +759,7 @@ static const char short_options[] = #define CMD_LINE_OPT_ENABLE_VECTOR "event-vector" #define CMD_LINE_OPT_VECTOR_SIZE "event-vector-size" #define CMD_LINE_OPT_VECTOR_TMO_NS "event-vector-tmo" +#define CMD_LINE_OPT_DIRECT_REARM "direct-rearm" #define CMD_LINE_OPT_RULE_IPV4 "rule_ipv4" #define CMD_LINE_OPT_RULE_IPV6 "rule_ipv6" #define CMD_LINE_OPT_ALG "alg" @@ -725,7 +789,8 @@ enum { CMD_LINE_OPT_LOOKUP_NUM, CMD_LINE_OPT_ENABLE_VECTOR_NUM, CMD_LINE_OPT_VECTOR_SIZE_NUM, - CMD_LINE_OPT_VECTOR_TMO_NS_NUM + CMD_LINE_OPT_VECTOR_TMO_NS_NUM, + CMD_LINE_OPT_DIRECT_REARM_NUM }; static const struct option lgopts[] = { @@ -747,6 +812,7 @@ static const struct option lgopts[] = { {CMD_LINE_OPT_ENABLE_VECTOR, 0, 0, CMD_LINE_OPT_ENABLE_VECTOR_NUM}, {CMD_LINE_OPT_VECTOR_SIZE, 1, 0, CMD_LINE_OPT_VECTOR_SIZE_NUM}, {CMD_LINE_OPT_VECTOR_TMO_NS, 1, 0, CMD_LINE_OPT_VECTOR_TMO_NS_NUM}, + {CMD_LINE_OPT_DIRECT_REARM, 1, 0, CMD_LINE_OPT_DIRECT_REARM_NUM}, {CMD_LINE_OPT_RULE_IPV4, 1, 0, CMD_LINE_OPT_RULE_IPV4_NUM}, {CMD_LINE_OPT_RULE_IPV6, 1, 0, CMD_LINE_OPT_RULE_IPV6_NUM}, {CMD_LINE_OPT_ALG, 1, 0, CMD_LINE_OPT_ALG_NUM}, @@ -912,6 +978,15 @@ parse_args(int argc, char **argv) case CMD_LINE_OPT_VECTOR_TMO_NS_NUM: evt_rsrc->vector_tmo_ns = strtoull(optarg, NULL, 10); break; + case CMD_LINE_OPT_DIRECT_REARM_NUM: + enabled_direct_rearm = 1; + ret = parse_direct_rearm(optarg); + if (ret) { + fprintf(stderr, "Invalid direct rearm map\n"); + print_usage(prgname); + return -1; + } + break; case CMD_LINE_OPT_RULE_IPV4_NUM: l3fwd_set_rule_ipv4_name(optarg); break; @@ -1594,6 +1669,23 @@ main(int argc, char **argv) } } + if (enabled_direct_rearm) { + uint16_t rx_port, tx_port; + uint8_t rx_queue, tx_queue; + uint8_t m = 0; + while (m < direct_rearm_entry_number) { + rx_port = direct_rearm_config[m][0]; + rx_queue = direct_rearm_config[m][1]; + tx_port = direct_rearm_config[m][2]; + tx_queue = direct_rearm_config[m][3]; + queue_enabled_direct_rearm[rx_port][rx_queue] = 1; + direct_rearm_map_tx_port[rx_port][rx_queue] = tx_port; + direct_rearm_map_tx_queue[rx_port][rx_queue] = tx_queue; + direct_rearm_entry_idx[rx_port][rx_queue] = m; + m++; + } + } + check_all_ports_link_status(enabled_port_mask); ret = 0; -- 2.25.1