[06/13] app/testpmd: add hairpin support

Message ID 1569479349-36962-7-git-send-email-orika@mellanox.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers
Series add hairpin feature |

Checks

Context Check Description
ci/Intel-compilation success Compilation OK
ci/checkpatch success coding style OK

Commit Message

Ori Kam Sept. 26, 2019, 6:29 a.m. UTC
  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

Slava Ovsiienko Sept. 26, 2019, 9:32 a.m. UTC | #1
> -----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
  

Patch

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;