DPDK patches and discussions
 help / color / mirror / Atom feed
From: Bing Zhao <bingz@nvidia.com>
To: thomas@monjalon.net, orika@nvidia.com, ferruh.yigit@intel.com,
	arybchenko@solarflare.com, mdr@ashroe.eu, nhorman@tuxdriver.com,
	bernard.iremonger@intel.com, beilei.xing@intel.com,
	wenzhuo.lu@intel.com
Cc: dev@dpdk.org
Subject: [dpdk-dev] [PATCH v2 5/6] app/testpmd: change hairpin queues setup
Date: Thu,  8 Oct 2020 16:51:37 +0800	[thread overview]
Message-ID: <1602147098-9768-6-git-send-email-bingz@nvidia.com> (raw)
In-Reply-To: <1602147098-9768-1-git-send-email-bingz@nvidia.com>

A new parameter `hairpin-mode` is introduced to the testpmd command
line. Bitmask value is used to provide more flexible configuration.
This parameter should be used when `hairpinq` is specified in the
command line.

Bit 0 in the LSB indicates the hairpin will use the loop mode. The
previous port RX queue will be connected to the current port TX
queue.
Bit 1 in the LSB indicates the hairpin will use pair port mode. The
even index port will be paired with the next odd index port. If the
total number of probed port is odd, then the last one will be paired
to itself.
If this byte is zero, then each port will be paired to itself.
Bit 0 takes a higher priority in the checking.

Bit 4 in the second bytes indicate if the hairpin will use explicit
TX flow mode.

e.g. in the command line, "--hairpinq=2 --hairpin-mode=0x11"

If not set, default value zero will be used and the behavior will
try to get align with the previous single port mode. If the ports
belong to different vendors' NICs, it is suggested to use the `self`
hairpin mode only.

Since hairpin configures the hardware resources, the port mask of
packets forwarding engine will not be used here.

Signed-off-by: Bing Zhao <bingz@nvidia.com>
---
v2: move the hairpin bind/unbind into start/stop to support hot-plug
    and hot-unplug
---
 app/test-pmd/parameters.c |  15 ++++++
 app/test-pmd/testpmd.c    | 125 ++++++++++++++++++++++++++++++++++++++++++++--
 app/test-pmd/testpmd.h    |   2 +
 3 files changed, 138 insertions(+), 4 deletions(-)

diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c
index 1ead595..991029d 100644
--- a/app/test-pmd/parameters.c
+++ b/app/test-pmd/parameters.c
@@ -221,6 +221,9 @@
 	       "enabled\n");
 	printf("  --record-core-cycles: enable measurement of CPU cycles.\n");
 	printf("  --record-burst-stats: enable display of RX and TX bursts.\n");
+	printf("  --hairpin-mode=0xXX: bitmask set the hairpin port mode.\n "
+	       "    0x10 - explicit tx rule, 0x02 - hairpin ports paired\n"
+	       "    0x01 - hairpin ports loop, 0x00 - hairpin port self\n");
 }
 
 #ifdef RTE_LIBRTE_CMDLINE
@@ -644,6 +647,7 @@
 		{ "rxd",			1, 0, 0 },
 		{ "txd",			1, 0, 0 },
 		{ "hairpinq",			1, 0, 0 },
+		{ "hairpin-mode",		1, 0, 0 },
 		{ "burst",			1, 0, 0 },
 		{ "mbcache",			1, 0, 0 },
 		{ "txpt",			1, 0, 0 },
@@ -1111,6 +1115,17 @@
 				rte_exit(EXIT_FAILURE, "Either rx or tx queues should "
 						"be non-zero\n");
 			}
+			if (!strcmp(lgopts[opt_idx].name, "hairpin-mode")) {
+				char *end = NULL;
+				unsigned int n;
+
+				errno = 0;
+				n = strtoul(optarg, &end, 0);
+				if (errno != 0 || end == optarg)
+					rte_exit(EXIT_FAILURE, "hairpin mode invalid\n");
+				else
+					hairpin_mode = (uint16_t)n;
+			}
 			if (!strcmp(lgopts[opt_idx].name, "burst")) {
 				n = atoi(optarg);
 				if (n == 0) {
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index ccba71c..344de83 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -367,6 +367,9 @@ struct fwd_engine * fwd_engines[] = {
 /* Clear ptypes on port initialization. */
 uint8_t clear_ptypes = true;
 
+/* Hairpin ports configuration mode. */
+uint16_t hairpin_mode;
+
 /* Pretty printing of ethdev events */
 static const char * const eth_event_desc[] = {
 	[RTE_ETH_EVENT_UNKNOWN] = "unknown",
@@ -2345,7 +2348,7 @@ struct extmem_param {
 
 /* Configure the Rx and Tx hairpin queues for the selected port. */
 static int
-setup_hairpin_queues(portid_t pi)
+setup_hairpin_queues(portid_t pi, portid_t p_pi, uint16_t cnt_pi)
 {
 	queueid_t qi;
 	struct rte_eth_hairpin_conf hairpin_conf = {
@@ -2354,10 +2357,49 @@ struct extmem_param {
 	int i;
 	int diag;
 	struct rte_port *port = &ports[pi];
+	uint16_t peer_rx_port = pi;
+	uint16_t peer_tx_port = pi;
+	uint32_t manual = 1;
+	uint32_t tx_exp = hairpin_mode & 0x10;
+
+	if (!(hairpin_mode & 0xf)) {
+		peer_rx_port = pi;
+		peer_tx_port = pi;
+		manual = 0;
+	} else if (hairpin_mode & 0x1) {
+		peer_tx_port = rte_eth_find_next_owned_by(pi + 1,
+						       RTE_ETH_DEV_NO_OWNER);
+		if (peer_tx_port >= RTE_MAX_ETHPORTS)
+			peer_tx_port = rte_eth_find_next_owned_by(0,
+						RTE_ETH_DEV_NO_OWNER);
+		if (p_pi != RTE_MAX_ETHPORTS) {
+			peer_rx_port = p_pi;
+		} else {
+			uint16_t next_pi;
+
+			/* Last port will be the peer RX port of the first. */
+			RTE_ETH_FOREACH_DEV(next_pi)
+				peer_rx_port = next_pi;
+		}
+		manual = 1;
+	} else if (hairpin_mode & 0x2) {
+		if (cnt_pi & 0x1) {
+			peer_rx_port = p_pi;
+		} else {
+			peer_rx_port = rte_eth_find_next_owned_by(pi + 1,
+						RTE_ETH_DEV_NO_OWNER);
+			if (peer_rx_port >= RTE_MAX_ETHPORTS)
+				peer_rx_port = pi;
+		}
+		peer_tx_port = peer_rx_port;
+		manual = 1;
+	}
 
 	for (qi = nb_txq, i = 0; qi < nb_hairpinq + nb_txq; qi++) {
-		hairpin_conf.peers[0].port = pi;
+		hairpin_conf.peers[0].port = peer_rx_port;
 		hairpin_conf.peers[0].queue = i + nb_rxq;
+		hairpin_conf.manual_bind = !!manual;
+		hairpin_conf.tx_explicit = !!tx_exp;
 		diag = rte_eth_tx_hairpin_queue_setup
 			(pi, qi, nb_txd, &hairpin_conf);
 		i++;
@@ -2377,8 +2419,10 @@ struct extmem_param {
 		return -1;
 	}
 	for (qi = nb_rxq, i = 0; qi < nb_hairpinq + nb_rxq; qi++) {
-		hairpin_conf.peers[0].port = pi;
+		hairpin_conf.peers[0].port = peer_tx_port;
 		hairpin_conf.peers[0].queue = i + nb_txq;
+		hairpin_conf.manual_bind = !!manual;
+		hairpin_conf.tx_explicit = !!tx_exp;
 		diag = rte_eth_rx_hairpin_queue_setup
 			(pi, qi, nb_rxd, &hairpin_conf);
 		i++;
@@ -2405,6 +2449,12 @@ struct extmem_param {
 {
 	int diag, need_check_link_status = -1;
 	portid_t pi;
+	portid_t p_pi = RTE_MAX_ETHPORTS;
+	portid_t pl[RTE_MAX_ETHPORTS];
+	portid_t peer_pl[RTE_MAX_ETHPORTS];
+	uint16_t cnt_pi = 0;
+	uint16_t cfg_pi = 0;
+	int peer_pi;
 	queueid_t qi;
 	struct rte_port *port;
 	struct rte_ether_addr mac_addr;
@@ -2544,7 +2594,7 @@ struct extmem_param {
 				return -1;
 			}
 			/* setup hairpin queues */
-			if (setup_hairpin_queues(pi) != 0)
+			if (setup_hairpin_queues(pi, p_pi, cnt_pi) != 0)
 				return -1;
 		}
 		configure_rxtx_dump_callbacks(verbose_level);
@@ -2557,6 +2607,9 @@ struct extmem_param {
 				pi);
 		}
 
+		p_pi = pi;
+		cnt_pi++;
+
 		/* start port */
 		if (rte_eth_dev_start(pi) < 0) {
 			printf("Fail to start port %d\n", pi);
@@ -2581,6 +2634,8 @@ struct extmem_param {
 
 		/* at least one port started, need checking link status */
 		need_check_link_status = 1;
+
+		pl[cfg_pi++] = pi;
 	}
 
 	if (need_check_link_status == 1 && !no_link_check)
@@ -2588,6 +2643,50 @@ struct extmem_param {
 	else if (need_check_link_status == 0)
 		printf("Please stop the ports first\n");
 
+	if (hairpin_mode & 0xf) {
+		uint16_t i;
+		int j;
+
+		/* bind all started hairpin ports */
+		for (i = 0; i < cfg_pi; i++) {
+			pi = pl[i];
+			/* bind current TX to all peer RX */
+			peer_pi = rte_eth_hairpin_get_peer_ports(pi,
+								 peer_pl, 1);
+			if (peer_pi < 0)
+				return peer_pi;
+			for (j = 0; j < peer_pi; j++) {
+				if (!port_is_started(peer_pl[j]))
+					continue;
+				diag = rte_eth_hairpin_bind(pi, peer_pl[j]);
+				if (diag < 0) {
+					printf("Error during binding "
+					       "hairpin tx port %u to %u: %s",
+					       pi, peer_pl[j],
+					       rte_strerror(-diag));
+					return -1;
+				}
+			}
+			/* bind all peer TX to current RX */
+			peer_pi = rte_eth_hairpin_get_peer_ports(pi,
+								 peer_pl, 0);
+			if (peer_pi < 0)
+				return peer_pi;
+			for (j = 0; j < peer_pi; j++) {
+				if (!port_is_started(peer_pl[j]))
+					continue;
+				diag = rte_eth_hairpin_bind(peer_pl[j], pi);
+				if (diag < 0) {
+					printf("Error during binding "
+					       "hairpin tx port %u to %u: %s",
+					       peer_pl[j], pi,
+					       rte_strerror(-diag));
+					return -1;
+				}
+			}
+		}
+	}
+
 	printf("Done\n");
 	return 0;
 }
@@ -2598,6 +2697,8 @@ struct extmem_param {
 	portid_t pi;
 	struct rte_port *port;
 	int need_check_link_status = 0;
+	portid_t peer_pl[RTE_MAX_ETHPORTS];
+	int peer_pi;
 
 	if (dcb_test) {
 		dcb_test = 0;
@@ -2628,6 +2729,22 @@ struct extmem_param {
 						RTE_PORT_HANDLING) == 0)
 			continue;
 
+		if (hairpin_mode & 0xf) {
+			int j;
+
+			rte_eth_hairpin_unbind(pi, RTE_MAX_ETHPORTS);
+			/* unbind all peer TX from current RX */
+			peer_pi = rte_eth_hairpin_get_peer_ports(pi,
+								 peer_pl, 0);
+			if (peer_pi < 0)
+				continue;
+			for (j = 0; j < peer_pi; j++) {
+				if (!port_is_started(peer_pl[j]))
+					continue;
+				rte_eth_hairpin_unbind(peer_pl[j], pi);
+			}
+		}
+
 		rte_eth_dev_stop(pi);
 
 		if (rte_atomic16_cmpset(&(port->port_status),
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index c7e7e41..29ede20 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -398,6 +398,8 @@ struct queue_stats_mappings {
 
 extern uint16_t stats_period;
 
+extern uint16_t hairpin_mode;
+
 #ifdef RTE_LIBRTE_LATENCY_STATS
 extern uint8_t latencystats_enabled;
 extern lcoreid_t latencystats_lcore_id;
-- 
1.8.3.1


  parent reply	other threads:[~2020-10-08  8:53 UTC|newest]

Thread overview: 81+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-11  4:51 [dpdk-dev] [RFC] introduce support for hairpin between two ports Bing Zhao
2020-09-13 15:48 ` [dpdk-dev] [RFC PATCH v2 0/4] " Bing Zhao
2020-09-13 15:48   ` [dpdk-dev] [RFC PATCH v2 1/4] ethdev: add support for flow item transmit queue Bing Zhao
2020-09-13 15:48   ` [dpdk-dev] [RFC PATCH v2 2/4] testpmd: add item transmit queue in flow CLI Bing Zhao
2020-09-13 15:48   ` [dpdk-dev] [RFC PATCH v2 3/4] ethdev: add hairpin bind APIs Bing Zhao
2020-09-13 15:49   ` [dpdk-dev] [RFC PATCH v2 4/4] ethdev: add new attributes to hairpin queues config Bing Zhao
2020-10-01  0:25   ` [dpdk-dev] [PATCH 0/4] introduce support for hairpin between two ports Bing Zhao
2020-10-01  0:25     ` [dpdk-dev] [PATCH 1/4] ethdev: add hairpin bind and unbind APIs Bing Zhao
2020-10-04  9:20       ` Ori Kam
2020-10-07 11:21         ` Bing Zhao
2020-10-07 11:42           ` Ori Kam
2020-10-01  0:26     ` [dpdk-dev] [PATCH 2/4] ethdev: add new attributes to hairpin config Bing Zhao
2020-10-04  9:22       ` Ori Kam
2020-10-07 11:32         ` Bing Zhao
2020-10-01  0:26     ` [dpdk-dev] [PATCH 3/4] ethdev: add APIs for hairpin queue operation Bing Zhao
2020-10-04  9:34       ` Ori Kam
2020-10-07 11:34         ` Bing Zhao
2020-10-01  0:26     ` [dpdk-dev] [PATCH 4/4] app/testpmd: change hairpin queues setup Bing Zhao
2020-10-04  9:39       ` Ori Kam
2020-10-07 11:36         ` Bing Zhao
2020-10-04  9:45     ` [dpdk-dev] [PATCH 0/4] introduce support for hairpin between two ports Ori Kam
2020-10-08  8:51     ` [dpdk-dev] [PATCH v2 0/6] " Bing Zhao
2020-10-08  8:51       ` [dpdk-dev] [PATCH v2 1/6] ethdev: add hairpin bind and unbind APIs Bing Zhao
2020-10-08  9:07         ` Ori Kam
2020-10-08  8:51       ` [dpdk-dev] [PATCH v2 2/6] ethdev: add new attributes to hairpin config Bing Zhao
2020-10-08  9:23         ` Ori Kam
2020-10-08  8:51       ` [dpdk-dev] [PATCH v2 3/6] ethdev: add API to get hairpin peer ports list Bing Zhao
2020-10-08  9:40         ` Ori Kam
2020-10-08  8:51       ` [dpdk-dev] [PATCH v2 4/6] ethdev: add APIs for hairpin queue operation Bing Zhao
2020-10-08  9:44         ` Ori Kam
2020-10-08  8:51       ` Bing Zhao [this message]
2020-10-08  9:45         ` [dpdk-dev] [PATCH v2 5/6] app/testpmd: change hairpin queues setup Ori Kam
2020-10-08  8:51       ` [dpdk-dev] [PATCH v2 6/6] doc: update for two ports hairpin mode Bing Zhao
2020-10-08  9:47         ` Ori Kam
2020-10-08 12:05       ` [dpdk-dev] [PATCH v3 0/6] introduce support for hairpin between two ports Bing Zhao
2020-10-08 12:05         ` [dpdk-dev] [PATCH v3 1/6] ethdev: add hairpin bind and unbind APIs Bing Zhao
2020-10-14 14:35           ` Thomas Monjalon
2020-10-15  2:56             ` Bing Zhao
2020-10-15  7:31               ` Thomas Monjalon
2020-10-08 12:05         ` [dpdk-dev] [PATCH v3 2/6] ethdev: add new attributes to hairpin config Bing Zhao
2020-10-12 21:37           ` Thomas Monjalon
2020-10-13 12:29             ` Bing Zhao
2020-10-13 12:41               ` Thomas Monjalon
2020-10-13 13:21                 ` Bing Zhao
2020-10-08 12:05         ` [dpdk-dev] [PATCH v3 3/6] ethdev: add API to get hairpin peer ports list Bing Zhao
2020-10-08 12:31           ` Ori Kam
2020-10-08 12:05         ` [dpdk-dev] [PATCH v3 4/6] ethdev: add APIs for hairpin queue operation Bing Zhao
2020-10-08 12:05         ` [dpdk-dev] [PATCH v3 5/6] app/testpmd: change hairpin queues setup Bing Zhao
2020-10-08 12:05         ` [dpdk-dev] [PATCH v3 6/6] doc: update for two ports hairpin mode Bing Zhao
2020-10-12 21:30           ` Thomas Monjalon
2020-10-13  1:13             ` Bing Zhao
2020-10-13  6:37               ` Thomas Monjalon
2020-10-13  6:40                 ` Bing Zhao
2020-10-13 16:19         ` [dpdk-dev] [PATCH v4 0/5] introduce support for hairpin between two ports Bing Zhao
2020-10-13 16:19           ` [dpdk-dev] [PATCH v4 1/5] ethdev: add hairpin bind and unbind APIs Bing Zhao
2020-10-14 14:43             ` Thomas Monjalon
2020-10-15  2:59               ` Bing Zhao
2020-10-13 16:19           ` [dpdk-dev] [PATCH v4 2/5] ethdev: add new attributes to hairpin config Bing Zhao
2020-10-13 16:19           ` [dpdk-dev] [PATCH v4 3/5] ethdev: add API to get hairpin peer ports list Bing Zhao
2020-10-14 15:02             ` Thomas Monjalon
2020-10-15  4:03               ` Bing Zhao
2020-10-13 16:19           ` [dpdk-dev] [PATCH v4 4/5] ethdev: add APIs for hairpin queue operation Bing Zhao
2020-10-13 16:19           ` [dpdk-dev] [PATCH v4 5/5] app/testpmd: change hairpin queues setup Bing Zhao
2020-10-15  5:35     ` [dpdk-dev] [PATCH v5 0/5] introduce support for hairpin between two ports Bing Zhao
2020-10-15  5:35       ` [dpdk-dev] [PATCH v5 1/5] ethdev: add hairpin bind and unbind APIs Bing Zhao
2020-10-15 10:34         ` Thomas Monjalon
2020-10-15 11:39           ` Bing Zhao
2020-10-15  5:35       ` [dpdk-dev] [PATCH v5 2/5] ethdev: add new attributes to hairpin config Bing Zhao
2020-10-15 10:46         ` Thomas Monjalon
2020-10-15 13:45           ` Bing Zhao
2020-10-15  5:35       ` [dpdk-dev] [PATCH v5 3/5] ethdev: add API to get hairpin peer ports list Bing Zhao
2020-10-15  5:35       ` [dpdk-dev] [PATCH v5 4/5] ethdev: add APIs for hairpin queue operation Bing Zhao
2020-10-15  5:35       ` [dpdk-dev] [PATCH v5 5/5] app/testpmd: change hairpin queues setup Bing Zhao
2020-10-15 13:08     ` [dpdk-dev] [PATCH v6 0/5] introduce support for hairpin between two ports Bing Zhao
2020-10-15 13:08       ` [dpdk-dev] [PATCH v6 1/5] ethdev: add hairpin bind and unbind APIs Bing Zhao
2020-10-15 13:08       ` [dpdk-dev] [PATCH v6 2/5] ethdev: add new attributes to hairpin config Bing Zhao
2020-10-15 13:08       ` [dpdk-dev] [PATCH v6 3/5] ethdev: add API to get hairpin peer ports list Bing Zhao
2020-10-15 13:08       ` [dpdk-dev] [PATCH v6 4/5] ethdev: add APIs for hairpin queue operation Bing Zhao
2020-10-15 13:08       ` [dpdk-dev] [PATCH v6 5/5] app/testpmd: change hairpin queues setup Bing Zhao
2020-10-15 23:03       ` [dpdk-dev] [PATCH v6 0/5] introduce support for hairpin between two ports Ferruh Yigit
2020-10-16  1:34         ` Bing Zhao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1602147098-9768-6-git-send-email-bingz@nvidia.com \
    --to=bingz@nvidia.com \
    --cc=arybchenko@solarflare.com \
    --cc=beilei.xing@intel.com \
    --cc=bernard.iremonger@intel.com \
    --cc=dev@dpdk.org \
    --cc=ferruh.yigit@intel.com \
    --cc=mdr@ashroe.eu \
    --cc=nhorman@tuxdriver.com \
    --cc=orika@nvidia.com \
    --cc=thomas@monjalon.net \
    --cc=wenzhuo.lu@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).