From: Anatoly Burakov <anatoly.burakov@intel.com>
To: dev@dpdk.org
Cc: David Hunt <david.hunt@intel.com>,
reshma.pattan@intel.com, hkalra@marvell.com,
jerinjacobk@gmail.com, yinan.wang@intel.com
Subject: [dpdk-dev] [PATCH v3 5/7] l3fwd-power: add interrupt-only mode
Date: Fri, 19 Jun 2020 11:53:53 +0100 [thread overview]
Message-ID: <8db5cf85a95de3157b53f754715cabc8c9dbdad1.1592563994.git.anatoly.burakov@intel.com> (raw)
In-Reply-To: <cover.1592563994.git.anatoly.burakov@intel.com>
In-Reply-To: <cover.1592563994.git.anatoly.burakov@intel.com>
In addition to existing modes, add a mode which is very similar to
legacy mode, but does not do frequency scaling, and thus does not
depend on the power library.
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
Tested-by: Yinan Wang <yinan.wang@intel.com>
---
examples/l3fwd-power/main.c | 188 +++++++++++++++++++++++++++++++++++-
1 file changed, 185 insertions(+), 3 deletions(-)
diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index c02b0a3574..51acbfd87d 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -198,7 +198,8 @@ enum appmode {
APP_MODE_DEFAULT = 0,
APP_MODE_LEGACY,
APP_MODE_EMPTY_POLL,
- APP_MODE_TELEMETRY
+ APP_MODE_TELEMETRY,
+ APP_MODE_INTERRUPT
};
enum appmode app_mode;
@@ -901,6 +902,170 @@ static int event_register(struct lcore_conf *qconf)
return 0;
}
+
+/* main processing loop */
+static int main_intr_loop(__rte_unused void *dummy)
+{
+ struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
+ unsigned int lcore_id;
+ uint64_t prev_tsc, diff_tsc, cur_tsc;
+ int i, j, nb_rx;
+ uint8_t queueid;
+ uint16_t portid;
+ struct lcore_conf *qconf;
+ struct lcore_rx_queue *rx_queue;
+ uint32_t lcore_rx_idle_count = 0;
+ uint32_t lcore_idle_hint = 0;
+ int intr_en = 0;
+
+ const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) /
+ US_PER_S * BURST_TX_DRAIN_US;
+
+ prev_tsc = 0;
+
+ lcore_id = rte_lcore_id();
+ qconf = &lcore_conf[lcore_id];
+
+ if (qconf->n_rx_queue == 0) {
+ RTE_LOG(INFO, L3FWD_POWER, "lcore %u has nothing to do\n",
+ lcore_id);
+ return 0;
+ }
+
+ RTE_LOG(INFO, L3FWD_POWER, "entering main interrupt loop on lcore %u\n",
+ lcore_id);
+
+ for (i = 0; i < qconf->n_rx_queue; i++) {
+ portid = qconf->rx_queue_list[i].port_id;
+ queueid = qconf->rx_queue_list[i].queue_id;
+ RTE_LOG(INFO, L3FWD_POWER,
+ " -- lcoreid=%u portid=%u rxqueueid=%hhu\n",
+ lcore_id, portid, queueid);
+ }
+
+ /* add into event wait list */
+ if (event_register(qconf) == 0)
+ intr_en = 1;
+ else
+ RTE_LOG(INFO, L3FWD_POWER, "RX interrupt won't enable.\n");
+
+ while (!is_done()) {
+ stats[lcore_id].nb_iteration_looped++;
+
+ cur_tsc = rte_rdtsc();
+
+ /*
+ * TX burst queue drain
+ */
+ diff_tsc = cur_tsc - prev_tsc;
+ if (unlikely(diff_tsc > drain_tsc)) {
+ for (i = 0; i < qconf->n_tx_port; ++i) {
+ portid = qconf->tx_port_id[i];
+ rte_eth_tx_buffer_flush(portid,
+ qconf->tx_queue_id[portid],
+ qconf->tx_buffer[portid]);
+ }
+ prev_tsc = cur_tsc;
+ }
+
+start_rx:
+ /*
+ * Read packet from RX queues
+ */
+ lcore_rx_idle_count = 0;
+ for (i = 0; i < qconf->n_rx_queue; ++i) {
+ rx_queue = &(qconf->rx_queue_list[i]);
+ rx_queue->idle_hint = 0;
+ portid = rx_queue->port_id;
+ queueid = rx_queue->queue_id;
+
+ nb_rx = rte_eth_rx_burst(portid, queueid, pkts_burst,
+ MAX_PKT_BURST);
+
+ stats[lcore_id].nb_rx_processed += nb_rx;
+ if (unlikely(nb_rx == 0)) {
+ /**
+ * no packet received from rx queue, try to
+ * sleep for a while forcing CPU enter deeper
+ * C states.
+ */
+ rx_queue->zero_rx_packet_count++;
+
+ if (rx_queue->zero_rx_packet_count <=
+ MIN_ZERO_POLL_COUNT)
+ continue;
+
+ rx_queue->idle_hint = power_idle_heuristic(
+ rx_queue->zero_rx_packet_count);
+ lcore_rx_idle_count++;
+ } else {
+ rx_queue->zero_rx_packet_count = 0;
+ }
+
+ /* Prefetch first packets */
+ for (j = 0; j < PREFETCH_OFFSET && j < nb_rx; j++) {
+ rte_prefetch0(rte_pktmbuf_mtod(
+ pkts_burst[j], void *));
+ }
+
+ /* Prefetch and forward already prefetched packets */
+ for (j = 0; j < (nb_rx - PREFETCH_OFFSET); j++) {
+ rte_prefetch0(rte_pktmbuf_mtod(
+ pkts_burst[j + PREFETCH_OFFSET],
+ void *));
+ l3fwd_simple_forward(
+ pkts_burst[j], portid, qconf);
+ }
+
+ /* Forward remaining prefetched packets */
+ for (; j < nb_rx; j++) {
+ l3fwd_simple_forward(
+ pkts_burst[j], portid, qconf);
+ }
+ }
+
+ if (unlikely(lcore_rx_idle_count == qconf->n_rx_queue)) {
+ /**
+ * All Rx queues empty in recent consecutive polls,
+ * sleep in a conservative manner, meaning sleep as
+ * less as possible.
+ */
+ for (i = 1,
+ lcore_idle_hint = qconf->rx_queue_list[0].idle_hint;
+ i < qconf->n_rx_queue; ++i) {
+ rx_queue = &(qconf->rx_queue_list[i]);
+ if (rx_queue->idle_hint < lcore_idle_hint)
+ lcore_idle_hint = rx_queue->idle_hint;
+ }
+
+ if (lcore_idle_hint < SUSPEND_THRESHOLD)
+ /**
+ * execute "pause" instruction to avoid context
+ * switch which generally take hundred of
+ * microseconds for short sleep.
+ */
+ rte_delay_us(lcore_idle_hint);
+ else {
+ /* suspend until rx interrupt triggers */
+ if (intr_en) {
+ turn_on_off_intr(qconf, 1);
+ sleep_until_rx_interrupt(
+ qconf->n_rx_queue);
+ turn_on_off_intr(qconf, 0);
+ /**
+ * start receiving packets immediately
+ */
+ if (likely(!is_done()))
+ goto start_rx;
+ }
+ }
+ stats[lcore_id].sleep_time += lcore_idle_hint;
+ }
+ }
+
+ return 0;
+}
+
/* main processing loop */
static int
main_telemetry_loop(__rte_unused void *dummy)
@@ -1440,7 +1605,8 @@ print_usage(const char *prgname)
" --empty-poll: enable empty poll detection"
" follow (training_flag, high_threshold, med_threshold)\n"
" --telemetry: enable telemetry mode, to update"
- " empty polls, full polls, and core busyness to telemetry\n",
+ " empty polls, full polls, and core busyness to telemetry\n"
+ " --interrupt-only: enable interrupt-only mode\n",
prgname);
}
@@ -1585,6 +1751,7 @@ parse_ep_config(const char *q_arg)
#define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype"
#define CMD_LINE_OPT_LEGACY "legacy"
#define CMD_LINE_OPT_EMPTY_POLL "empty-poll"
+#define CMD_LINE_OPT_INTERRUPT_ONLY "interrupt-only"
#define CMD_LINE_OPT_TELEMETRY "telemetry"
/* Parse the argument given in the command line of the application */
@@ -1606,6 +1773,7 @@ parse_args(int argc, char **argv)
{CMD_LINE_OPT_PARSE_PTYPE, 0, 0, 0},
{CMD_LINE_OPT_LEGACY, 0, 0, 0},
{CMD_LINE_OPT_TELEMETRY, 0, 0, 0},
+ {CMD_LINE_OPT_INTERRUPT_ONLY, 0, 0, 0},
{NULL, 0, 0, 0}
};
@@ -1716,6 +1884,17 @@ parse_args(int argc, char **argv)
printf("telemetry mode is enabled\n");
}
+ if (!strncmp(lgopts[option_index].name,
+ CMD_LINE_OPT_INTERRUPT_ONLY,
+ sizeof(CMD_LINE_OPT_INTERRUPT_ONLY))) {
+ if (app_mode != APP_MODE_DEFAULT) {
+ printf(" interrupt-only mode is mutually exclusive with other modes\n");
+ return -1;
+ }
+ app_mode = APP_MODE_INTERRUPT;
+ printf("interrupt-only mode is enabled\n");
+ }
+
if (!strncmp(lgopts[option_index].name,
"enable-jumbo", 12)) {
struct option lenopts =
@@ -2298,7 +2477,8 @@ main(int argc, char **argv)
RTE_ETH_FOREACH_DEV(portid) {
struct rte_eth_conf local_port_conf = port_conf;
/* not all app modes need interrupts */
- bool need_intr = app_mode == APP_MODE_LEGACY;
+ bool need_intr = app_mode == APP_MODE_LEGACY ||
+ app_mode == APP_MODE_INTERRUPT;
/* skip ports that are not enabled */
if ((enabled_port_mask & (1 << portid)) == 0) {
@@ -2576,6 +2756,8 @@ main(int argc, char **argv)
"Returns global power stats. Parameters: None");
rte_eal_mp_remote_launch(main_telemetry_loop, NULL,
SKIP_MASTER);
+ } else if (app_mode == APP_MODE_INTERRUPT) {
+ rte_eal_mp_remote_launch(main_intr_loop, NULL, CALL_MASTER);
}
if (app_mode == APP_MODE_EMPTY_POLL || app_mode == APP_MODE_TELEMETRY)
--
2.17.1
next prev parent reply other threads:[~2020-06-19 10:54 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-28 9:13 [dpdk-dev] [PATCH 0/3] Add interrupt-only mode to l3fwd-power Anatoly Burakov
2020-05-28 9:13 ` [dpdk-dev] [PATCH 1/3] l3fwd-power: disable interrupts by default Anatoly Burakov
2020-05-28 9:13 ` [dpdk-dev] [PATCH 2/3] l3fwd-power: only allow supported power library envs Anatoly Burakov
2020-05-28 9:13 ` [dpdk-dev] [PATCH 3/3] l3fwd-power: add interrupt-only mode Anatoly Burakov
2020-05-29 13:19 ` Harman Kalra
2020-05-29 14:19 ` Burakov, Anatoly
2020-05-30 10:02 ` [dpdk-dev] [EXT] " Harman Kalra
2020-06-01 12:50 ` Burakov, Anatoly
2020-06-02 10:23 ` Harman Kalra
2020-06-02 12:16 ` Harman Kalra
2020-06-15 11:31 ` Burakov, Anatoly
2020-06-15 11:43 ` Jerin Jacob
2020-06-15 15:05 ` Burakov, Anatoly
2020-06-15 15:21 ` Jerin Jacob
2020-06-15 15:45 ` Burakov, Anatoly
2020-06-15 16:29 ` Jerin Jacob
2020-06-16 9:31 ` Burakov, Anatoly
2020-06-16 17:09 ` Jerin Jacob
2020-06-08 1:24 ` [dpdk-dev] [PATCH 0/3] Add interrupt-only mode to l3fwd-power Wang, Yinan
2020-06-18 17:18 ` [dpdk-dev] [PATCH v2 0/7] " Anatoly Burakov
2020-06-19 10:53 ` [dpdk-dev] [PATCH v3 " Anatoly Burakov
2020-07-11 11:35 ` Thomas Monjalon
2020-06-19 10:53 ` [dpdk-dev] [PATCH v3 1/7] l3fwd-power: disable interrupts by default Anatoly Burakov
2020-06-19 10:53 ` [dpdk-dev] [PATCH v3 2/7] l3fwd-power: only allow supported power library envs Anatoly Burakov
2020-06-19 10:53 ` [dpdk-dev] [PATCH v3 3/7] l3fwd-power: code style and flow fixes Anatoly Burakov
2020-06-19 10:53 ` [dpdk-dev] [PATCH v3 4/7] l3fwd-power: add support for requesting legacy mode Anatoly Burakov
2020-06-19 10:53 ` Anatoly Burakov [this message]
2020-06-19 10:53 ` [dpdk-dev] [PATCH v3 6/7] power: add API to probe support for a specific env Anatoly Burakov
2020-06-19 10:53 ` [dpdk-dev] [PATCH v3 7/7] l3fwd-power: add auto-selection of default mode Anatoly Burakov
2020-07-11 10:07 ` Thomas Monjalon
2020-06-18 17:18 ` [dpdk-dev] [PATCH v2 1/7] l3fwd-power: disable interrupts by default Anatoly Burakov
2020-06-18 17:18 ` [dpdk-dev] [PATCH v2 2/7] l3fwd-power: only allow supported power library envs Anatoly Burakov
2020-06-18 17:18 ` [dpdk-dev] [PATCH v2 3/7] l3fwd-power: code style and flow fixes Anatoly Burakov
2020-06-18 17:18 ` [dpdk-dev] [PATCH v2 4/7] l3fwd-power: add support for requesting legacy mode Anatoly Burakov
2020-06-18 17:18 ` [dpdk-dev] [PATCH v2 5/7] l3fwd-power: add interrupt-only mode Anatoly Burakov
2020-06-18 17:18 ` [dpdk-dev] [PATCH v2 6/7] power: add API to probe support for a specific env Anatoly Burakov
2020-06-18 17:18 ` [dpdk-dev] [PATCH v2 7/7] l3fwd-power: add auto-selection of default mode Anatoly Burakov
2020-06-19 7:37 ` [dpdk-dev] [EXT] " Harman Kalra
2020-06-19 9:56 ` Burakov, Anatoly
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=8db5cf85a95de3157b53f754715cabc8c9dbdad1.1592563994.git.anatoly.burakov@intel.com \
--to=anatoly.burakov@intel.com \
--cc=david.hunt@intel.com \
--cc=dev@dpdk.org \
--cc=hkalra@marvell.com \
--cc=jerinjacobk@gmail.com \
--cc=reshma.pattan@intel.com \
--cc=yinan.wang@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).