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 v2 5/7] l3fwd-power: add interrupt-only mode Date: Thu, 18 Jun 2020 18:18:27 +0100 Message-ID: <19c87c4d73a73fc01648196315567f9f21df2f94.1592500565.git.anatoly.burakov@intel.com> (raw) In-Reply-To: <cover.1592500565.git.anatoly.burakov@intel.com> In-Reply-To: <cover.1592500565.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> --- 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-18 17:19 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 ` [dpdk-dev] [PATCH v3 5/7] l3fwd-power: add interrupt-only mode Anatoly Burakov 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 ` Anatoly Burakov [this message] 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=19c87c4d73a73fc01648196315567f9f21df2f94.1592500565.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
DPDK patches and discussions This inbox may be cloned and mirrored by anyone: git clone --mirror https://inbox.dpdk.org/dev/0 dev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 dev dev/ https://inbox.dpdk.org/dev \ dev@dpdk.org public-inbox-index dev Example config snippet for mirrors. Newsgroup available over NNTP: nntp://inbox.dpdk.org/inbox.dpdk.dev AGPL code for this site: git clone https://public-inbox.org/public-inbox.git