diff options
Diffstat (limited to 'examples/l3fwd-power')
-rw-r--r-- | examples/l3fwd-power/Makefile | 6 | ||||
-rw-r--r-- | examples/l3fwd-power/main.c | 111 | ||||
-rw-r--r-- | examples/l3fwd-power/main.h | 20 | ||||
-rw-r--r-- | examples/l3fwd-power/meson.build | 7 | ||||
-rw-r--r-- | examples/l3fwd-power/perf_core.c | 230 | ||||
-rw-r--r-- | examples/l3fwd-power/perf_core.h | 12 |
6 files changed, 350 insertions, 36 deletions
diff --git a/examples/l3fwd-power/Makefile b/examples/l3fwd-power/Makefile index 390b7d6b..d7e39a34 100644 --- a/examples/l3fwd-power/Makefile +++ b/examples/l3fwd-power/Makefile @@ -1,11 +1,11 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright(c) 2010-2014 Intel Corporation +# Copyright(c) 2010-2018 Intel Corporation # binary name APP = l3fwd-power # all source are stored in SRCS-y -SRCS-y := main.c +SRCS-y := main.c perf_core.c # Build using pkg-config variables if possible $(shell pkg-config --exists libdpdk) @@ -48,7 +48,7 @@ RTE_TARGET ?= x86_64-native-linuxapp-gcc include $(RTE_SDK)/mk/rte.vars.mk -ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp") +ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y) $(info This application can only operate in a linuxapp environment, \ please change the definition of the RTE_TARGET environment variable) all: diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c index b2a7c79e..d15cd520 100644 --- a/examples/l3fwd-power/main.c +++ b/examples/l3fwd-power/main.c @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2016 Intel Corporation + * Copyright(c) 2010-2018 Intel Corporation */ #include <stdio.h> @@ -44,6 +44,9 @@ #include <rte_power.h> #include <rte_spinlock.h> +#include "perf_core.h" +#include "main.h" + #define RTE_LOGTYPE_L3FWD_POWER RTE_LOGTYPE_USER1 #define MAX_PKT_BURST 32 @@ -155,14 +158,7 @@ struct lcore_rx_queue { #define MAX_RX_QUEUE_INTERRUPT_PER_PORT 16 -#define MAX_LCORE_PARAMS 1024 -struct lcore_params { - uint16_t port_id; - uint8_t queue_id; - uint8_t lcore_id; -} __rte_cache_aligned; - -static struct lcore_params lcore_params_array[MAX_LCORE_PARAMS]; +struct lcore_params lcore_params_array[MAX_LCORE_PARAMS]; static struct lcore_params lcore_params_array_default[] = { {0, 0, 2}, {0, 1, 2}, @@ -175,8 +171,8 @@ static struct lcore_params lcore_params_array_default[] = { {3, 1, 3}, }; -static struct lcore_params * lcore_params = lcore_params_array_default; -static uint16_t nb_lcore_params = sizeof(lcore_params_array_default) / +struct lcore_params *lcore_params = lcore_params_array_default; +uint16_t nb_lcore_params = sizeof(lcore_params_array_default) / sizeof(lcore_params_array_default[0]); static struct rte_eth_conf port_conf = { @@ -184,7 +180,6 @@ static struct rte_eth_conf port_conf = { .mq_mode = ETH_MQ_RX_RSS, .max_rx_pkt_len = ETHER_MAX_LEN, .split_hdr_size = 0, - .ignore_offload_bitfield = 1, .offloads = (DEV_RX_OFFLOAD_CRC_STRIP | DEV_RX_OFFLOAD_CHECKSUM), }, @@ -341,7 +336,7 @@ static void signal_exit_now(int sigtype) { unsigned lcore_id; - unsigned int portid, nb_ports; + unsigned int portid; int ret; if (sigtype == SIGINT) { @@ -357,8 +352,7 @@ signal_exit_now(int sigtype) "core%u\n", lcore_id); } - nb_ports = rte_eth_dev_count(); - for (portid = 0; portid < nb_ports; portid++) { + RTE_ETH_FOREACH_DEV(portid) { if ((enabled_port_mask & (1 << portid)) == 0) continue; @@ -1057,7 +1051,7 @@ check_lcore_params(void) } static int -check_port_config(const unsigned nb_ports) +check_port_config(void) { unsigned portid; uint16_t i; @@ -1069,7 +1063,7 @@ check_port_config(const unsigned nb_ports) portid); return -1; } - if (portid >= nb_ports) { + if (!rte_eth_dev_is_valid_port(portid)) { printf("port %u is not present on the board\n", portid); return -1; @@ -1122,10 +1116,15 @@ print_usage(const char *prgname) { printf ("%s [EAL options] -- -p PORTMASK -P" " [--config (port,queue,lcore)[,(port,queue,lcore]]" + " [--high-perf-cores CORELIST" + " [--perf-config (port,queue,hi_perf,lcore_index)[,(port,queue,hi_perf,lcore_index]]" " [--enable-jumbo [--max-pkt-len PKTLEN]]\n" " -p PORTMASK: hexadecimal bitmask of ports to configure\n" " -P : enable promiscuous mode\n" " --config (port,queue,lcore): rx queues configuration\n" + " --high-perf-cores CORELIST: list of high performance cores\n" + " --perf-config: similar as config, cores specified as indices" + " for bins containing high or regular performance cores\n" " --no-numa: optional, disable numa awareness\n" " --enable-jumbo: enable jumbo frame" " which max packet len is PKTLEN in decimal (64-9600)\n" @@ -1235,6 +1234,8 @@ parse_args(int argc, char **argv) char *prgname = argv[0]; static struct option lgopts[] = { {"config", 1, 0, 0}, + {"perf-config", 1, 0, 0}, + {"high-perf-cores", 1, 0, 0}, {"no-numa", 0, 0, 0}, {"enable-jumbo", 0, 0, 0}, {CMD_LINE_OPT_PARSE_PTYPE, 0, 0, 0}, @@ -1273,6 +1274,26 @@ parse_args(int argc, char **argv) } if (!strncmp(lgopts[option_index].name, + "perf-config", 11)) { + ret = parse_perf_config(optarg); + if (ret) { + printf("invalid perf-config\n"); + print_usage(prgname); + return -1; + } + } + + if (!strncmp(lgopts[option_index].name, + "high-perf-cores", 15)) { + ret = parse_perf_core_list(optarg); + if (ret) { + printf("invalid high-perf-cores\n"); + print_usage(prgname); + return -1; + } + } + + if (!strncmp(lgopts[option_index].name, "no-numa", 7)) { printf("numa is disabled \n"); numa_on = 0; @@ -1512,7 +1533,7 @@ init_mem(unsigned nb_mbuf) /* Check the link status of all ports in up to 9s, and print them finally */ static void -check_all_ports_link_status(uint16_t port_num, uint32_t port_mask) +check_all_ports_link_status(uint32_t port_mask) { #define CHECK_INTERVAL 100 /* 100ms */ #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */ @@ -1524,7 +1545,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask) fflush(stdout); for (count = 0; count <= MAX_CHECK_TIME; count++) { all_ports_up = 1; - for (portid = 0; portid < port_num; portid++) { + RTE_ETH_FOREACH_DEV(portid) { if ((port_mask & (1 << portid)) == 0) continue; memset(&link, 0, sizeof(link)); @@ -1610,6 +1631,23 @@ static int check_ptype(uint16_t portid) } +static int +init_power_library(void) +{ + int ret = 0, lcore_id; + for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { + if (rte_lcore_is_enabled(lcore_id)) { + /* init power management library */ + ret = rte_power_init(lcore_id); + if (ret) + RTE_LOG(ERR, POWER, + "Library initialization failed on core %u\n", + lcore_id); + } + } + return ret; +} + int main(int argc, char **argv) { @@ -1644,6 +1682,12 @@ main(int argc, char **argv) if (ret < 0) rte_exit(EXIT_FAILURE, "Invalid L3FWD parameters\n"); + if (init_power_library()) + rte_exit(EXIT_FAILURE, "init_power_library failed\n"); + + if (update_lcore_params() < 0) + rte_exit(EXIT_FAILURE, "update_lcore_params failed\n"); + if (check_lcore_params() < 0) rte_exit(EXIT_FAILURE, "check_lcore_params failed\n"); @@ -1651,15 +1695,15 @@ main(int argc, char **argv) if (ret < 0) rte_exit(EXIT_FAILURE, "init_lcore_rx_queues failed\n"); - nb_ports = rte_eth_dev_count(); + nb_ports = rte_eth_dev_count_avail(); - if (check_port_config(nb_ports) < 0) + if (check_port_config() < 0) rte_exit(EXIT_FAILURE, "check_port_config failed\n"); nb_lcores = rte_lcore_count(); /* initialize all ports */ - for (portid = 0; portid < nb_ports; portid++) { + RTE_ETH_FOREACH_DEV(portid) { struct rte_eth_conf local_port_conf = port_conf; /* skip ports that are not enabled */ @@ -1694,6 +1738,18 @@ main(int argc, char **argv) if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE) local_port_conf.txmode.offloads |= DEV_TX_OFFLOAD_MBUF_FAST_FREE; + + local_port_conf.rx_adv_conf.rss_conf.rss_hf &= + dev_info.flow_type_rss_offloads; + if (local_port_conf.rx_adv_conf.rss_conf.rss_hf != + port_conf.rx_adv_conf.rss_conf.rss_hf) { + printf("Port %u modified RSS hash function based on hardware support," + "requested:%#"PRIx64" configured:%#"PRIx64"\n", + portid, + port_conf.rx_adv_conf.rss_conf.rss_hf, + local_port_conf.rx_adv_conf.rss_conf.rss_hf); + } + ret = rte_eth_dev_configure(portid, nb_rx_queue, (uint16_t)n_tx_queue, &local_port_conf); if (ret < 0) @@ -1751,7 +1807,6 @@ main(int argc, char **argv) fflush(stdout); txconf = &dev_info.default_txconf; - txconf->txq_flags = ETH_TXQ_FLAGS_IGNORE; txconf->offloads = local_port_conf.txmode.offloads; ret = rte_eth_tx_queue_setup(portid, queueid, nb_txd, socketid, txconf); @@ -1774,12 +1829,6 @@ main(int argc, char **argv) if (rte_lcore_is_enabled(lcore_id) == 0) continue; - /* init power management library */ - ret = rte_power_init(lcore_id); - if (ret) - RTE_LOG(ERR, POWER, - "Library initialization failed on core %u\n", lcore_id); - /* init timer structures for each enabled lcore */ rte_timer_init(&power_timers[lcore_id]); hz = rte_get_timer_hz(); @@ -1834,7 +1883,7 @@ main(int argc, char **argv) printf("\n"); /* start ports */ - for (portid = 0; portid < nb_ports; portid++) { + RTE_ETH_FOREACH_DEV(portid) { if ((enabled_port_mask & (1 << portid)) == 0) { continue; } @@ -1855,7 +1904,7 @@ main(int argc, char **argv) rte_spinlock_init(&(locks[portid])); } - check_all_ports_link_status(nb_ports, enabled_port_mask); + check_all_ports_link_status(enabled_port_mask); /* launch per-lcore init on every lcore */ rte_eal_mp_remote_launch(main_loop, NULL, CALL_MASTER); diff --git a/examples/l3fwd-power/main.h b/examples/l3fwd-power/main.h new file mode 100644 index 00000000..258de98f --- /dev/null +++ b/examples/l3fwd-power/main.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2018 Intel Corporation + */ + +#ifndef _MAIN_H_ +#define _MAIN_H_ + + +#define MAX_LCORE_PARAMS 1024 +struct lcore_params { + uint16_t port_id; + uint8_t queue_id; + uint8_t lcore_id; +} __rte_cache_aligned; + +extern struct lcore_params *lcore_params; +extern uint16_t nb_lcore_params; +extern struct lcore_params lcore_params_array[]; + +#endif /* _MAIN_H_ */ diff --git a/examples/l3fwd-power/meson.build b/examples/l3fwd-power/meson.build index 61e8daa9..20c80543 100644 --- a/examples/l3fwd-power/meson.build +++ b/examples/l3fwd-power/meson.build @@ -1,12 +1,15 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright(c) 2017 Intel Corporation +# Copyright(c) 2018 Intel Corporation # meson file, for building this example as part of a main DPDK build. # # To build this example as a standalone application with an already-installed # DPDK instance, use 'make' +if host_machine.system() != 'linux' + build = false +endif deps += ['power', 'timer', 'lpm', 'hash'] sources = files( - 'main.c' + 'main.c', 'perf_core.c' ) diff --git a/examples/l3fwd-power/perf_core.c b/examples/l3fwd-power/perf_core.c new file mode 100644 index 00000000..83948ea2 --- /dev/null +++ b/examples/l3fwd-power/perf_core.c @@ -0,0 +1,230 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2018 Intel Corporation + */ + +#include <stdio.h> +#include <string.h> + +#include <rte_common.h> +#include <rte_memory.h> +#include <rte_lcore.h> +#include <rte_power.h> +#include <rte_string_fns.h> + +#include "perf_core.h" +#include "main.h" + + +static uint16_t hp_lcores[RTE_MAX_LCORE]; +static uint16_t nb_hp_lcores; + +struct perf_lcore_params { + uint16_t port_id; + uint8_t queue_id; + uint8_t high_perf; + uint8_t lcore_idx; +} __rte_cache_aligned; + +static struct perf_lcore_params prf_lc_prms[MAX_LCORE_PARAMS]; +static uint16_t nb_prf_lc_prms; + +int +update_lcore_params(void) +{ + uint8_t non_perf_lcores[RTE_MAX_LCORE]; + uint16_t nb_non_perf_lcores = 0; + int i, j, ret; + + /* if perf-config option was not used do nothing */ + if (nb_prf_lc_prms == 0) + return 0; + + /* if high-perf-cores option was not used query every available core */ + if (nb_hp_lcores == 0) { + for (i = 0; i < RTE_MAX_LCORE; i++) { + if (rte_lcore_is_enabled(i)) { + struct rte_power_core_capabilities caps; + ret = rte_power_get_capabilities(i, &caps); + if (ret == 0 && caps.turbo) { + hp_lcores[nb_hp_lcores] = i; + nb_hp_lcores++; + } + } + } + } + + /* create a list on non high performance cores*/ + for (i = 0; i < RTE_MAX_LCORE; i++) { + if (rte_lcore_is_enabled(i)) { + int hp = 0; + for (j = 0; j < nb_hp_lcores; j++) { + if (hp_lcores[j] == i) { + hp = 1; + break; + } + } + if (!hp) + non_perf_lcores[nb_non_perf_lcores++] = i; + } + } + + /* update the lcore config */ + for (i = 0; i < nb_prf_lc_prms; i++) { + int lcore = -1; + if (prf_lc_prms[i].high_perf) { + if (prf_lc_prms[i].lcore_idx < nb_hp_lcores) + lcore = hp_lcores[prf_lc_prms[i].lcore_idx]; + } else { + if (prf_lc_prms[i].lcore_idx < nb_non_perf_lcores) + lcore = + non_perf_lcores[prf_lc_prms[i].lcore_idx]; + } + + if (lcore < 0) { + printf("Performance cores configuration error\n"); + return -1; + } + + lcore_params_array[i].lcore_id = lcore; + lcore_params_array[i].queue_id = prf_lc_prms[i].queue_id; + lcore_params_array[i].port_id = prf_lc_prms[i].port_id; + } + + lcore_params = lcore_params_array; + nb_lcore_params = nb_prf_lc_prms; + + printf("Updated performance core configuration\n"); + for (i = 0; i < nb_prf_lc_prms; i++) + printf("\t(%d,%d,%d)\n", lcore_params[i].port_id, + lcore_params[i].queue_id, + lcore_params[i].lcore_id); + + return 0; +} + +int +parse_perf_config(const char *q_arg) +{ + char s[256]; + const char *p, *p0 = q_arg; + char *end; + enum fieldnames { + FLD_PORT = 0, + FLD_QUEUE, + FLD_LCORE_HP, + FLD_LCORE_IDX, + _NUM_FLD + }; + unsigned long int_fld[_NUM_FLD]; + char *str_fld[_NUM_FLD]; + int i; + unsigned int size; + + nb_prf_lc_prms = 0; + + while ((p = strchr(p0, '(')) != NULL) { + ++p; + p0 = strchr(p, ')'); + if (p0 == NULL) + return -1; + + size = p0 - p; + if (size >= sizeof(s)) + return -1; + + snprintf(s, sizeof(s), "%.*s", size, p); + if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') != + _NUM_FLD) + return -1; + for (i = 0; i < _NUM_FLD; i++) { + errno = 0; + int_fld[i] = strtoul(str_fld[i], &end, 0); + if (errno != 0 || end == str_fld[i] || int_fld[i] > 255) + return -1; + } + if (nb_prf_lc_prms >= MAX_LCORE_PARAMS) { + printf("exceeded max number of lcore params: %hu\n", + nb_prf_lc_prms); + return -1; + } + prf_lc_prms[nb_prf_lc_prms].port_id = + (uint8_t)int_fld[FLD_PORT]; + prf_lc_prms[nb_prf_lc_prms].queue_id = + (uint8_t)int_fld[FLD_QUEUE]; + prf_lc_prms[nb_prf_lc_prms].high_perf = + !!(uint8_t)int_fld[FLD_LCORE_HP]; + prf_lc_prms[nb_prf_lc_prms].lcore_idx = + (uint8_t)int_fld[FLD_LCORE_IDX]; + ++nb_prf_lc_prms; + } + + return 0; +} + +int +parse_perf_core_list(const char *corelist) +{ + int i, idx = 0; + unsigned int count = 0; + char *end = NULL; + int min, max; + + if (corelist == NULL) { + printf("invalid core list\n"); + return -1; + } + + + /* Remove all blank characters ahead and after */ + while (isblank(*corelist)) + corelist++; + i = strlen(corelist); + while ((i > 0) && isblank(corelist[i - 1])) + i--; + + /* Get list of cores */ + min = RTE_MAX_LCORE; + do { + while (isblank(*corelist)) + corelist++; + if (*corelist == '\0') + return -1; + errno = 0; + idx = strtoul(corelist, &end, 10); + if (errno || end == NULL) + return -1; + while (isblank(*end)) + end++; + if (*end == '-') { + min = idx; + } else if ((*end == ',') || (*end == '\0')) { + max = idx; + if (min == RTE_MAX_LCORE) + min = idx; + for (idx = min; idx <= max; idx++) { + hp_lcores[count] = idx; + count++; + } + min = RTE_MAX_LCORE; + } else { + printf("invalid core list\n"); + return -1; + } + corelist = end + 1; + } while (*end != '\0'); + + if (count == 0) { + printf("invalid core list\n"); + return -1; + } + + nb_hp_lcores = count; + + printf("Configured %d high performance cores\n", nb_hp_lcores); + for (i = 0; i < nb_hp_lcores; i++) + printf("\tHigh performance core %d %d\n", + i, hp_lcores[i]); + + return 0; +} + diff --git a/examples/l3fwd-power/perf_core.h b/examples/l3fwd-power/perf_core.h new file mode 100644 index 00000000..7b7b747b --- /dev/null +++ b/examples/l3fwd-power/perf_core.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2018 Intel Corporation + */ + +#ifndef _PERF_CORE_H_ +#define _PERF_CORE_H_ + +int parse_perf_config(const char *q_arg); +int parse_perf_core_list(const char *corelist); +int update_lcore_params(void); + +#endif /* _PERF_CORE_H_ */ |