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
next 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