[06/13] app/testpmd: add hairpin support
Checks
Commit Message
This commit introduce the hairpin queues to the testpmd.
the hairpin queue is configured using --hairpinq=<n>
the hairpin queue adds n queue objects for both the total number
of TX queues and RX queues.
The connection between the queues are 1 to 1, first Rx hairpin queue
will be connected to the first Tx hairpin queue
Signed-off-by: Ori Kam <orika@mellanox.com>
---
app/test-pmd/parameters.c | 12 ++++++++++
app/test-pmd/testpmd.c | 59 +++++++++++++++++++++++++++++++++++++++++++++--
app/test-pmd/testpmd.h | 1 +
3 files changed, 70 insertions(+), 2 deletions(-)
Comments
> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Ori Kam
> Sent: Thursday, September 26, 2019 9:29
> To: Wenzhuo Lu <wenzhuo.lu@intel.com>; Jingjing Wu
> <jingjing.wu@intel.com>; Bernard Iremonger
> <bernard.iremonger@intel.com>
> Cc: dev@dpdk.org; Ori Kam <orika@mellanox.com>;
> stephen@networkplumber.org
> Subject: [dpdk-dev] [PATCH 06/13] app/testpmd: add hairpin support
>
> This commit introduce the hairpin queues to the testpmd.
> the hairpin queue is configured using --hairpinq=<n> the hairpin queue adds n
> queue objects for both the total number of TX queues and RX queues.
> The connection between the queues are 1 to 1, first Rx hairpin queue will be
> connected to the first Tx hairpin queue
>
> Signed-off-by: Ori Kam <orika@mellanox.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
> ---
> app/test-pmd/parameters.c | 12 ++++++++++
> app/test-pmd/testpmd.c | 59
> +++++++++++++++++++++++++++++++++++++++++++++--
> app/test-pmd/testpmd.h | 1 +
> 3 files changed, 70 insertions(+), 2 deletions(-)
>
> diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c index
> 6c78dca..16bdcc8 100644
> --- a/app/test-pmd/parameters.c
> +++ b/app/test-pmd/parameters.c
> @@ -147,6 +147,8 @@
> printf(" --rxd=N: set the number of descriptors in RX rings to N.\n");
> printf(" --txq=N: set the number of TX queues per port to N.\n");
> printf(" --txd=N: set the number of descriptors in TX rings to N.\n");
> + printf(" --hairpinq=N: set the number of hairpin queues per port to "
> + "N.\n");
> printf(" --burst=N: set the number of packets per burst to N.\n");
> printf(" --mbcache=N: set the cache of mbuf memory pool to N.\n");
> printf(" --rxpt=N: set prefetch threshold register of RX rings to
> N.\n"); @@ -618,6 +620,7 @@
> { "txq", 1, 0, 0 },
> { "rxd", 1, 0, 0 },
> { "txd", 1, 0, 0 },
> + { "hairpinq", 1, 0, 0 },
> { "burst", 1, 0, 0 },
> { "mbcache", 1, 0, 0 },
> { "txpt", 1, 0, 0 },
> @@ -1036,6 +1039,15 @@
> " >= 0 && <= %u\n", n,
>
> get_allowed_max_nb_txq(&pid));
> }
> + if (!strcmp(lgopts[opt_idx].name, "hairpinq")) {
> + n = atoi(optarg);
> + if (n >= 0 && check_nb_txq((queueid_t)n) ==
> 0)
> + nb_hairpinq = (queueid_t) n;
> + else
> + rte_exit(EXIT_FAILURE, "txq %d
> invalid - must be"
> + " >= 0 && <= %u\n", n,
> +
> get_allowed_max_nb_txq(&pid));
> + }
> if (!nb_rxq && !nb_txq) {
> rte_exit(EXIT_FAILURE, "Either rx or tx
> queues should "
> "be non-zero\n");
> diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index
> de91e1b..f15a308 100644
> --- a/app/test-pmd/testpmd.c
> +++ b/app/test-pmd/testpmd.c
> @@ -235,6 +235,7 @@ struct fwd_engine * fwd_engines[] = {
> /*
> * Configurable number of RX/TX queues.
> */
> +queueid_t nb_hairpinq; /**< Number of hairpin queues per port. */
> queueid_t nb_rxq = 1; /**< Number of RX queues per port. */ queueid_t
> nb_txq = 1; /**< Number of TX queues per port. */
>
> @@ -2064,6 +2065,10 @@ struct extmem_param {
> queueid_t qi;
> struct rte_port *port;
> struct rte_ether_addr mac_addr;
> + struct rte_eth_hairpin_conf hairpin_conf = {
> + .peer_n = 1,
> + };
> + int i;
>
> if (port_id_is_invalid(pid, ENABLED_WARN))
> return 0;
> @@ -2097,8 +2102,9 @@ struct extmem_param {
> printf("Configuring Port %d (socket %u)\n", pi,
> port->socket_id);
> /* configure port */
> - diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
> - &(port->dev_conf));
> + diag = rte_eth_dev_configure(pi, nb_rxq +
> nb_hairpinq,
> + nb_txq + nb_hairpinq,
> + &(port->dev_conf));
> if (diag != 0) {
> if (rte_atomic16_cmpset(&(port-
> >port_status),
> RTE_PORT_HANDLING,
> RTE_PORT_STOPPED) == 0) @@ -2191,6 +2197,55 @@ struct
> extmem_param {
> port->need_reconfig_queues = 1;
> return -1;
> }
> + /* setup hairpin queues */
> + i = 0;
> + for (qi = nb_txq; qi < nb_hairpinq + nb_txq; qi++) {
> + hairpin_conf.peers[0].port = pi;
> + hairpin_conf.peers[0].queue = i + nb_rxq;
> + diag = rte_eth_tx_hairpin_queue_setup
> + (pi, qi, nb_txd,
> + port->socket_id, &(port-
> >tx_conf[qi]),
> + &hairpin_conf);
> + i++;
> + if (diag == 0)
> + continue;
> +
> + /* Fail to setup rx queue, return */
> + if (rte_atomic16_cmpset(&(port-
> >port_status),
> +
> RTE_PORT_HANDLING,
> +
> RTE_PORT_STOPPED) == 0)
> + printf("Port %d can not be set back "
> + "to stopped\n", pi);
> + printf("Fail to configure port %d hairpin "
> + "queues\n", pi);
> + /* try to reconfigure queues next time */
> + port->need_reconfig_queues = 1;
> + return -1;
> + }
> + i = 0;
> + for (qi = nb_rxq; qi < nb_hairpinq + nb_rxq; qi++) {
> + hairpin_conf.peers[0].port = pi;
> + hairpin_conf.peers[0].queue = i + nb_txq;
> + diag = rte_eth_rx_hairpin_queue_setup
> + (pi, qi, nb_rxd,
> + port->socket_id, &(port-
> >rx_conf[qi]),
> + &hairpin_conf);
> + i++;
> + if (diag == 0)
> + continue;
> +
> + /* Fail to setup rx queue, return */
> + if (rte_atomic16_cmpset(&(port-
> >port_status),
> +
> RTE_PORT_HANDLING,
> +
> RTE_PORT_STOPPED) == 0)
> + printf("Port %d can not be set back "
> + "to stopped\n", pi);
> + printf("Fail to configure port %d hairpin "
> + "queues\n", pi);
> + /* try to reconfigure queues next time */
> + port->need_reconfig_queues = 1;
> + return -1;
> + }
> }
> configure_rxtx_dump_callbacks(verbose_level);
> /* start port */
> diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index
> d73955d..09baa72 100644
> --- a/app/test-pmd/testpmd.h
> +++ b/app/test-pmd/testpmd.h
> @@ -383,6 +383,7 @@ struct queue_stats_mappings {
>
> extern uint64_t rss_hf;
>
> +extern queueid_t nb_hairpinq;
> extern queueid_t nb_rxq;
> extern queueid_t nb_txq;
>
> --
> 1.8.3.1
@@ -147,6 +147,8 @@
printf(" --rxd=N: set the number of descriptors in RX rings to N.\n");
printf(" --txq=N: set the number of TX queues per port to N.\n");
printf(" --txd=N: set the number of descriptors in TX rings to N.\n");
+ printf(" --hairpinq=N: set the number of hairpin queues per port to "
+ "N.\n");
printf(" --burst=N: set the number of packets per burst to N.\n");
printf(" --mbcache=N: set the cache of mbuf memory pool to N.\n");
printf(" --rxpt=N: set prefetch threshold register of RX rings to N.\n");
@@ -618,6 +620,7 @@
{ "txq", 1, 0, 0 },
{ "rxd", 1, 0, 0 },
{ "txd", 1, 0, 0 },
+ { "hairpinq", 1, 0, 0 },
{ "burst", 1, 0, 0 },
{ "mbcache", 1, 0, 0 },
{ "txpt", 1, 0, 0 },
@@ -1036,6 +1039,15 @@
" >= 0 && <= %u\n", n,
get_allowed_max_nb_txq(&pid));
}
+ if (!strcmp(lgopts[opt_idx].name, "hairpinq")) {
+ n = atoi(optarg);
+ if (n >= 0 && check_nb_txq((queueid_t)n) == 0)
+ nb_hairpinq = (queueid_t) n;
+ else
+ rte_exit(EXIT_FAILURE, "txq %d invalid - must be"
+ " >= 0 && <= %u\n", n,
+ get_allowed_max_nb_txq(&pid));
+ }
if (!nb_rxq && !nb_txq) {
rte_exit(EXIT_FAILURE, "Either rx or tx queues should "
"be non-zero\n");
@@ -235,6 +235,7 @@ struct fwd_engine * fwd_engines[] = {
/*
* Configurable number of RX/TX queues.
*/
+queueid_t nb_hairpinq; /**< Number of hairpin queues per port. */
queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
queueid_t nb_txq = 1; /**< Number of TX queues per port. */
@@ -2064,6 +2065,10 @@ struct extmem_param {
queueid_t qi;
struct rte_port *port;
struct rte_ether_addr mac_addr;
+ struct rte_eth_hairpin_conf hairpin_conf = {
+ .peer_n = 1,
+ };
+ int i;
if (port_id_is_invalid(pid, ENABLED_WARN))
return 0;
@@ -2097,8 +2102,9 @@ struct extmem_param {
printf("Configuring Port %d (socket %u)\n", pi,
port->socket_id);
/* configure port */
- diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
- &(port->dev_conf));
+ diag = rte_eth_dev_configure(pi, nb_rxq + nb_hairpinq,
+ nb_txq + nb_hairpinq,
+ &(port->dev_conf));
if (diag != 0) {
if (rte_atomic16_cmpset(&(port->port_status),
RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
@@ -2191,6 +2197,55 @@ struct extmem_param {
port->need_reconfig_queues = 1;
return -1;
}
+ /* setup hairpin queues */
+ i = 0;
+ for (qi = nb_txq; qi < nb_hairpinq + nb_txq; qi++) {
+ hairpin_conf.peers[0].port = pi;
+ hairpin_conf.peers[0].queue = i + nb_rxq;
+ diag = rte_eth_tx_hairpin_queue_setup
+ (pi, qi, nb_txd,
+ port->socket_id, &(port->tx_conf[qi]),
+ &hairpin_conf);
+ i++;
+ if (diag == 0)
+ continue;
+
+ /* Fail to setup rx queue, return */
+ if (rte_atomic16_cmpset(&(port->port_status),
+ RTE_PORT_HANDLING,
+ RTE_PORT_STOPPED) == 0)
+ printf("Port %d can not be set back "
+ "to stopped\n", pi);
+ printf("Fail to configure port %d hairpin "
+ "queues\n", pi);
+ /* try to reconfigure queues next time */
+ port->need_reconfig_queues = 1;
+ return -1;
+ }
+ i = 0;
+ for (qi = nb_rxq; qi < nb_hairpinq + nb_rxq; qi++) {
+ hairpin_conf.peers[0].port = pi;
+ hairpin_conf.peers[0].queue = i + nb_txq;
+ diag = rte_eth_rx_hairpin_queue_setup
+ (pi, qi, nb_rxd,
+ port->socket_id, &(port->rx_conf[qi]),
+ &hairpin_conf);
+ i++;
+ if (diag == 0)
+ continue;
+
+ /* Fail to setup rx queue, return */
+ if (rte_atomic16_cmpset(&(port->port_status),
+ RTE_PORT_HANDLING,
+ RTE_PORT_STOPPED) == 0)
+ printf("Port %d can not be set back "
+ "to stopped\n", pi);
+ printf("Fail to configure port %d hairpin "
+ "queues\n", pi);
+ /* try to reconfigure queues next time */
+ port->need_reconfig_queues = 1;
+ return -1;
+ }
}
configure_rxtx_dump_callbacks(verbose_level);
/* start port */
@@ -383,6 +383,7 @@ struct queue_stats_mappings {
extern uint64_t rss_hf;
+extern queueid_t nb_hairpinq;
extern queueid_t nb_rxq;
extern queueid_t nb_txq;