DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Stephen Hemminger <stephen@networkplumber.org>
To: dev@dpdk.org
Cc: Stephen Hemminger <stephen@networkplumber.org>,
	Aman Singh <aman.deep.singh@intel.com>
Subject: [RFC 1/2] app/testpmd: add option to set flow control mode
Date: Sat, 17 Oct 2026 12:48:54 -0700	[thread overview]
Message-ID: <20261017194856.2950241-1-stephen@networkplumber.org> (raw)

When doing benchmarking it is important to disable NIC
flow control. Testpmd can do this only from the interactive
command line, there was no option to do this from a script.

Add --flow-ctrl=none|rx|tx|full, applied each time a port
is started. Devices without flow control support are skipped.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 app/test-pmd/parameters.c             | 18 +++++++++++++++++
 app/test-pmd/testpmd.c                | 28 +++++++++++++++++++++++++++
 app/test-pmd/testpmd.h                |  1 +
 doc/guides/testpmd_app_ug/run_app.rst |  5 +++++
 4 files changed, 52 insertions(+)

diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c
index 833b14eda4..f031dd7445 100644
--- a/app/test-pmd/parameters.c
+++ b/app/test-pmd/parameters.c
@@ -207,6 +207,8 @@ enum {
 	TESTPMD_OPT_NO_LSC_INTERRUPT_NUM,
 #define TESTPMD_OPT_NO_RMV_INTERRUPT "no-rmv-interrupt"
 	TESTPMD_OPT_NO_RMV_INTERRUPT_NUM,
+#define TESTPMD_OPT_FLOW_CTRL "flow-ctrl"
+	TESTPMD_OPT_FLOW_CTRL_NUM,
 #define TESTPMD_OPT_PRINT_EVENT "print-event"
 	TESTPMD_OPT_PRINT_EVENT_NUM,
 #define TESTPMD_OPT_MASK_EVENT "mask-event"
@@ -357,6 +359,7 @@ static const struct option long_options[] = {
 	NO_ARG(TESTPMD_OPT_DISABLE_DEVICE_START),
 	NO_ARG(TESTPMD_OPT_NO_LSC_INTERRUPT),
 	NO_ARG(TESTPMD_OPT_NO_RMV_INTERRUPT),
+	REQUIRED_ARG(TESTPMD_OPT_FLOW_CTRL),
 	REQUIRED_ARG(TESTPMD_OPT_PRINT_EVENT),
 	REQUIRED_ARG(TESTPMD_OPT_MASK_EVENT),
 	REQUIRED_ARG(TESTPMD_OPT_TX_OFFLOADS),
@@ -515,6 +518,8 @@ usage(char* progname)
 	printf("  --disable-device-start: do not automatically start port\n");
 	printf("  --no-lsc-interrupt: disable link status change interrupt.\n");
 	printf("  --no-rmv-interrupt: disable device removal interrupt.\n");
+	printf("  --flow-ctrl=none|rx|tx|full: set Ethernet flow control"
+	       " mode when ports are started.\n");
 #ifdef RTE_LIB_BITRATESTATS
 	printf("  --bitrate-stats=N: set the logical core N to perform "
 		"bit-rate calculation.\n");
@@ -1635,6 +1640,19 @@ launch_args_parse(int argc, char** argv)
 		case TESTPMD_OPT_NO_RMV_INTERRUPT_NUM:
 			rmv_interrupt = 0;
 			break;
+		case TESTPMD_OPT_FLOW_CTRL_NUM:
+			if (!strcmp(optarg, "none"))
+				flow_ctrl_mode = RTE_ETH_FC_NONE;
+			else if (!strcmp(optarg, "rx"))
+				flow_ctrl_mode = RTE_ETH_FC_RX_PAUSE;
+			else if (!strcmp(optarg, "tx"))
+				flow_ctrl_mode = RTE_ETH_FC_TX_PAUSE;
+			else if (!strcmp(optarg, "full"))
+				flow_ctrl_mode = RTE_ETH_FC_FULL;
+			else
+				rte_exit(EXIT_FAILURE,
+					 "flow-ctrl must be none, rx, tx or full\n");
+			break;
 		case TESTPMD_OPT_FLOW_ISOLATE_ALL_NUM:
 			flow_isolate_all = 1;
 			break;
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index d6211a9a8a..e1766eec72 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -446,6 +446,12 @@ uint8_t lsc_interrupt = 1; /* enabled by default */
  */
 uint8_t rmv_interrupt = 1; /* enabled by default */
 
+/*
+ * Ethernet flow control mode applied on port start.
+ * Negative means leave the device default.
+ */
+int flow_ctrl_mode = -1;
+
 uint8_t hot_plug = 0; /**< hotplug disabled by default. */
 
 /* After attach, port setup is called on event or by iterator */
@@ -2973,6 +2979,26 @@ update_bonding_port_dev_conf(portid_t bond_pid)
 #endif
 }
 
+static void
+port_flow_ctrl_apply(portid_t pi)
+{
+	struct rte_eth_fc_conf fc_conf;
+	int ret;
+
+	if (flow_ctrl_mode < 0 || !is_proc_primary())
+		return;
+
+	memset(&fc_conf, 0, sizeof(fc_conf));
+	ret = rte_eth_dev_flow_ctrl_get(pi, &fc_conf);
+	if (ret == 0) {
+		fc_conf.mode = flow_ctrl_mode;
+		ret = rte_eth_dev_flow_ctrl_set(pi, &fc_conf);
+	}
+	if (ret != 0 && ret != -ENOTSUP)
+		fprintf(stderr, "Port %u: failed to set flow control: %s\n",
+			pi, rte_strerror(-ret));
+}
+
 int
 start_port(portid_t pid)
 {
@@ -3229,6 +3255,8 @@ start_port(portid_t pid)
 			fprintf(stderr, "Port %d can not be set into started\n",
 				pi);
 
+		port_flow_ctrl_apply(pi);
+
 		if (eth_macaddr_get_print_err(pi, &port->eth_addr) == 0)
 			printf("Port %d: " RTE_ETHER_ADDR_PRT_FMT "\n", pi,
 					RTE_ETHER_ADDR_BYTES(&port->eth_addr));
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 2ca4aaf086..6d4c3e8f84 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -541,6 +541,7 @@ extern uint8_t no_device_start; /**<set by "--disable-device-start" parameter */
 extern volatile int test_done; /* stop packet forwarding when set to 1. */
 extern uint8_t lsc_interrupt; /**< disabled by "--no-lsc-interrupt" parameter */
 extern uint8_t rmv_interrupt; /**< disabled by "--no-rmv-interrupt" parameter */
+extern int flow_ctrl_mode; /**< set by "--flow-ctrl" parameter */
 extern uint32_t event_print_mask;
 /**< set by "--print-event xxxx" and "--mask-event xxxx parameters */
 extern bool setup_on_probe_event; /**< disabled by port setup-on iterator */
diff --git a/doc/guides/testpmd_app_ug/run_app.rst b/doc/guides/testpmd_app_ug/run_app.rst
index bcfbf33f92..e678058b97 100644
--- a/doc/guides/testpmd_app_ug/run_app.rst
+++ b/doc/guides/testpmd_app_ug/run_app.rst
@@ -224,6 +224,11 @@ The command line options are:
 
     Disable RSS (Receive Side Scaling).
 
+*   ``--flow-ctrl=mode``
+
+    Set the Ethernet flow control mode of all ports each time they are started.
+    The possible values are ``none``, ``rx``, ``tx`` and ``full``.
+
 *   ``--port-topology=mode``
 
     Set port topology, where mode is ``paired`` (the default), ``chained`` or ``loop``.
-- 
2.53.0


             reply	other threads:[~2026-10-17 19:49 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-17 19:48 Stephen Hemminger [this message]
2026-10-17 19:48 ` [RFC 2/2] app/testpmd: add option to limit run time Stephen Hemminger

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=20261017194856.2950241-1-stephen@networkplumber.org \
    --to=stephen@networkplumber.org \
    --cc=aman.deep.singh@intel.com \
    --cc=dev@dpdk.org \
    /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