examples/l3fwd-power: add ethdev power management
Add PMD power management feature support to l3fwd-power sample app. Signed-off-by: Liang Ma <liang.j.ma@intel.com> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> Acked-by: David Hunt <david.hunt@intel.com>
This commit is contained in:
parent
682a645438
commit
26fe454ec0
@ -109,6 +109,8 @@ where,
|
||||
|
||||
* --telemetry: Telemetry mode.
|
||||
|
||||
* --pmd-mgmt: PMD power management mode.
|
||||
|
||||
See :doc:`l3_forward` for details.
|
||||
The L3fwd-power example reuses the L3fwd command line options.
|
||||
|
||||
@ -456,3 +458,44 @@ reference cycles and accordingly busy rate is set to either 0% or
|
||||
|
||||
The new stats ``empty_poll`` , ``full_poll`` and ``busy_percent`` can be viewed by running the script
|
||||
``/usertools/dpdk-telemetry-client.py`` and selecting the menu option ``Send for global Metrics``.
|
||||
|
||||
PMD power management Mode
|
||||
-------------------------
|
||||
|
||||
The PMD power management mode support for ``l3fwd-power`` is a standalone mode.
|
||||
In this mode, ``l3fwd-power`` does simple l3fwding
|
||||
along with enabling the power saving scheme on specific port/queue/lcore.
|
||||
Main purpose for this mode is to demonstrate
|
||||
how to use the PMD power management API.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
./build/examples/dpdk-l3fwd-power -l 1-3 -- --pmd-mgmt -p 0x0f --config="(0,0,2),(0,1,3)"
|
||||
|
||||
PMD Power Management Mode
|
||||
-------------------------
|
||||
|
||||
There is also a traffic-aware operating mode that,
|
||||
instead of using explicit power management,
|
||||
will use automatic PMD power management.
|
||||
This mode is limited to one queue per core,
|
||||
and has three available power management schemes:
|
||||
|
||||
``monitor``
|
||||
This will use ``rte_power_monitor()`` function to enter
|
||||
a power-optimized state (subject to platform support).
|
||||
|
||||
``pause``
|
||||
This will use ``rte_power_pause()`` or ``rte_pause()``
|
||||
to avoid busy looping when there is no traffic.
|
||||
|
||||
``scale``
|
||||
This will use frequency scaling routines
|
||||
available in the ``librte_power`` library.
|
||||
|
||||
See :doc:`Power Management<../prog_guide/power_man>` chapter
|
||||
in the DPDK Programmer's Guide for more details on PMD power management.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
./<build_dir>/examples/dpdk-l3fwd-power -l 1-3 -- -p 0x0f --config="(0,0,2),(0,1,3)" --pmd-mgmt=scale
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include <rte_power_empty_poll.h>
|
||||
#include <rte_metrics.h>
|
||||
#include <rte_telemetry.h>
|
||||
#include <rte_power_pmd_mgmt.h>
|
||||
|
||||
#include "perf_core.h"
|
||||
#include "main.h"
|
||||
@ -199,11 +200,14 @@ enum appmode {
|
||||
APP_MODE_LEGACY,
|
||||
APP_MODE_EMPTY_POLL,
|
||||
APP_MODE_TELEMETRY,
|
||||
APP_MODE_INTERRUPT
|
||||
APP_MODE_INTERRUPT,
|
||||
APP_MODE_PMD_MGMT
|
||||
};
|
||||
|
||||
enum appmode app_mode;
|
||||
|
||||
static enum rte_power_pmd_mgmt_type pmgmt_type;
|
||||
|
||||
enum freq_scale_hint_t
|
||||
{
|
||||
FREQ_LOWER = -1,
|
||||
@ -1611,7 +1615,9 @@ print_usage(const char *prgname)
|
||||
" follow (training_flag, high_threshold, med_threshold)\n"
|
||||
" --telemetry: enable telemetry mode, to update"
|
||||
" empty polls, full polls, and core busyness to telemetry\n"
|
||||
" --interrupt-only: enable interrupt-only mode\n",
|
||||
" --interrupt-only: enable interrupt-only mode\n"
|
||||
" --pmd-mgmt MODE: enable PMD power management mode. "
|
||||
"Currently supported modes: monitor, pause, scale\n",
|
||||
prgname);
|
||||
}
|
||||
|
||||
@ -1701,6 +1707,32 @@ parse_config(const char *q_arg)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_pmd_mgmt_config(const char *name)
|
||||
{
|
||||
#define PMD_MGMT_MONITOR "monitor"
|
||||
#define PMD_MGMT_PAUSE "pause"
|
||||
#define PMD_MGMT_SCALE "scale"
|
||||
|
||||
if (strncmp(PMD_MGMT_MONITOR, name, sizeof(PMD_MGMT_MONITOR)) == 0) {
|
||||
pmgmt_type = RTE_POWER_MGMT_TYPE_MONITOR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strncmp(PMD_MGMT_PAUSE, name, sizeof(PMD_MGMT_PAUSE)) == 0) {
|
||||
pmgmt_type = RTE_POWER_MGMT_TYPE_PAUSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strncmp(PMD_MGMT_SCALE, name, sizeof(PMD_MGMT_SCALE)) == 0) {
|
||||
pmgmt_type = RTE_POWER_MGMT_TYPE_SCALE;
|
||||
return 0;
|
||||
}
|
||||
/* unknown PMD power management mode */
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_ep_config(const char *q_arg)
|
||||
{
|
||||
@ -1755,6 +1787,7 @@ parse_ep_config(const char *q_arg)
|
||||
#define CMD_LINE_OPT_EMPTY_POLL "empty-poll"
|
||||
#define CMD_LINE_OPT_INTERRUPT_ONLY "interrupt-only"
|
||||
#define CMD_LINE_OPT_TELEMETRY "telemetry"
|
||||
#define CMD_LINE_OPT_PMD_MGMT "pmd-mgmt"
|
||||
|
||||
/* Parse the argument given in the command line of the application */
|
||||
static int
|
||||
@ -1776,6 +1809,7 @@ parse_args(int argc, char **argv)
|
||||
{CMD_LINE_OPT_LEGACY, 0, 0, 0},
|
||||
{CMD_LINE_OPT_TELEMETRY, 0, 0, 0},
|
||||
{CMD_LINE_OPT_INTERRUPT_ONLY, 0, 0, 0},
|
||||
{CMD_LINE_OPT_PMD_MGMT, 1, 0, 0},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
@ -1886,6 +1920,21 @@ parse_args(int argc, char **argv)
|
||||
printf("telemetry mode is enabled\n");
|
||||
}
|
||||
|
||||
if (!strncmp(lgopts[option_index].name,
|
||||
CMD_LINE_OPT_PMD_MGMT,
|
||||
sizeof(CMD_LINE_OPT_PMD_MGMT))) {
|
||||
if (app_mode != APP_MODE_DEFAULT) {
|
||||
printf(" power mgmt mode is mutually exclusive with other modes\n");
|
||||
return -1;
|
||||
}
|
||||
if (parse_pmd_mgmt_config(optarg) < 0) {
|
||||
printf(" Invalid PMD power management mode: %s\n",
|
||||
optarg);
|
||||
return -1;
|
||||
}
|
||||
app_mode = APP_MODE_PMD_MGMT;
|
||||
printf("PMD power mgmt mode is enabled\n");
|
||||
}
|
||||
if (!strncmp(lgopts[option_index].name,
|
||||
CMD_LINE_OPT_INTERRUPT_ONLY,
|
||||
sizeof(CMD_LINE_OPT_INTERRUPT_ONLY))) {
|
||||
@ -2442,6 +2491,8 @@ mode_to_str(enum appmode mode)
|
||||
return "telemetry";
|
||||
case APP_MODE_INTERRUPT:
|
||||
return "interrupt-only";
|
||||
case APP_MODE_PMD_MGMT:
|
||||
return "pmd mgmt";
|
||||
default:
|
||||
return "invalid";
|
||||
}
|
||||
@ -2671,6 +2722,13 @@ main(int argc, char **argv)
|
||||
qconf = &lcore_conf[lcore_id];
|
||||
printf("\nInitializing rx queues on lcore %u ... ", lcore_id );
|
||||
fflush(stdout);
|
||||
|
||||
/* PMD power management mode can only do 1 queue per core */
|
||||
if (app_mode == APP_MODE_PMD_MGMT && qconf->n_rx_queue > 1) {
|
||||
rte_exit(EXIT_FAILURE,
|
||||
"In PMD power management mode, only one queue per lcore is allowed\n");
|
||||
}
|
||||
|
||||
/* init RX queues */
|
||||
for(queue = 0; queue < qconf->n_rx_queue; ++queue) {
|
||||
struct rte_eth_rxconf rxq_conf;
|
||||
@ -2708,6 +2766,16 @@ main(int argc, char **argv)
|
||||
rte_exit(EXIT_FAILURE,
|
||||
"Fail to add ptype cb\n");
|
||||
}
|
||||
|
||||
if (app_mode == APP_MODE_PMD_MGMT) {
|
||||
ret = rte_power_ethdev_pmgmt_queue_enable(
|
||||
lcore_id, portid, queueid,
|
||||
pmgmt_type);
|
||||
if (ret < 0)
|
||||
rte_exit(EXIT_FAILURE,
|
||||
"rte_power_ethdev_pmgmt_queue_enable: err=%d, port=%d\n",
|
||||
ret, portid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2798,6 +2866,9 @@ main(int argc, char **argv)
|
||||
SKIP_MAIN);
|
||||
} else if (app_mode == APP_MODE_INTERRUPT) {
|
||||
rte_eal_mp_remote_launch(main_intr_loop, NULL, CALL_MAIN);
|
||||
} else if (app_mode == APP_MODE_PMD_MGMT) {
|
||||
/* reuse telemetry loop for PMD power management mode */
|
||||
rte_eal_mp_remote_launch(main_telemetry_loop, NULL, CALL_MAIN);
|
||||
}
|
||||
|
||||
if (app_mode == APP_MODE_EMPTY_POLL || app_mode == APP_MODE_TELEMETRY)
|
||||
@ -2808,6 +2879,21 @@ main(int argc, char **argv)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (app_mode == APP_MODE_PMD_MGMT) {
|
||||
for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
|
||||
if (rte_lcore_is_enabled(lcore_id) == 0)
|
||||
continue;
|
||||
qconf = &lcore_conf[lcore_id];
|
||||
for (queue = 0; queue < qconf->n_rx_queue; ++queue) {
|
||||
portid = qconf->rx_queue_list[queue].port_id;
|
||||
queueid = qconf->rx_queue_list[queue].queue_id;
|
||||
|
||||
rte_power_ethdev_pmgmt_queue_disable(lcore_id,
|
||||
portid, queueid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RTE_ETH_FOREACH_DEV(portid)
|
||||
{
|
||||
if ((enabled_port_mask & (1 << portid)) == 0)
|
||||
|
Loading…
Reference in New Issue
Block a user