X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=examples%2Fl3fwd-power%2Fmain.c;h=887c6eae3fa71e78de13c00a64e871d04662e45f;hb=68629be3a622ee53cd5b40c8447ae9b083ff3f6c;hp=aa7b8db44ae878c48d50163a05d59190cfb9d89d;hpb=9a212dc06c7aaf09b146d9c3dcfd584d741634c1;p=dpdk.git diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c index aa7b8db44a..887c6eae3f 100644 --- a/examples/l3fwd-power/main.c +++ b/examples/l3fwd-power/main.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -250,22 +249,27 @@ uint16_t nb_lcore_params = RTE_DIM(lcore_params_array_default); static struct rte_eth_conf port_conf = { .rxmode = { - .mq_mode = ETH_MQ_RX_RSS, - .max_rx_pkt_len = RTE_ETHER_MAX_LEN, + .mq_mode = RTE_ETH_MQ_RX_RSS, .split_hdr_size = 0, - .offloads = DEV_RX_OFFLOAD_CHECKSUM, + .offloads = RTE_ETH_RX_OFFLOAD_CHECKSUM, }, .rx_adv_conf = { .rss_conf = { .rss_key = NULL, - .rss_hf = ETH_RSS_UDP, + .rss_hf = RTE_ETH_RSS_UDP, }, }, .txmode = { - .mq_mode = ETH_MQ_TX_NONE, + .mq_mode = RTE_ETH_MQ_TX_NONE, } }; +static uint32_t max_pkt_len; +static uint32_t max_empty_polls = 512; +static uint32_t pause_duration = 1; +static uint32_t scale_freq_min; +static uint32_t scale_freq_max; + static struct rte_mempool * pktmbuf_pool[NB_SOCKETS]; @@ -433,7 +437,7 @@ signal_exit_now(int sigtype) } -/* Freqency scale down timer callback */ +/* Frequency scale down timer callback */ static void power_timer_cb(__rte_unused struct rte_timer *tim, __rte_unused void *arg) @@ -505,7 +509,15 @@ is_valid_ipv4_pkt(struct rte_ipv4_hdr *pkt, uint32_t link_len) return -1; /* 2. The IP checksum must be correct. */ - /* this is checked in H/W */ + /* if this is not checked in H/W, check it. */ + if ((port_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_IPV4_CKSUM) == 0) { + uint16_t actual_cksum, expected_cksum; + actual_cksum = pkt->hdr_checksum; + pkt->hdr_checksum = 0; + expected_cksum = rte_ipv4_cksum(pkt); + if (actual_cksum != expected_cksum) + return -2; + } /* * 3. The IP version number must be 4. If the version number is not 4 @@ -717,7 +729,7 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint16_t portid, dst_port = portid; /* 02:00:00:00:00:xx */ - d_addr_bytes = ð_hdr->d_addr.addr_bytes[0]; + d_addr_bytes = ð_hdr->dst_addr.addr_bytes[0]; *((uint64_t *)d_addr_bytes) = 0x000000000002 + ((uint64_t)dst_port << 40); @@ -729,7 +741,7 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint16_t portid, /* src addr */ rte_ether_addr_copy(&ports_eth_addr[dst_port], - ð_hdr->s_addr); + ð_hdr->src_addr); send_single_packet(m, dst_port); } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) { @@ -749,13 +761,13 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint16_t portid, dst_port = portid; /* 02:00:00:00:00:xx */ - d_addr_bytes = ð_hdr->d_addr.addr_bytes[0]; + d_addr_bytes = ð_hdr->dst_addr.addr_bytes[0]; *((uint64_t *)d_addr_bytes) = 0x000000000002 + ((uint64_t)dst_port << 40); /* src addr */ rte_ether_addr_copy(&ports_eth_addr[dst_port], - ð_hdr->s_addr); + ð_hdr->src_addr); send_single_packet(m, dst_port); #else @@ -1601,16 +1613,15 @@ print_usage(const char *prgname) " [--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" + " [--max-pkt-len PKTLEN]\n" " -p PORTMASK: hexadecimal bitmask of ports to configure\n" - " -P : enable promiscuous mode\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" + " --max-pkt-len PKTLEN: maximum packet length in decimal (64-9600)\n" " --parse-ptype: parse packet type by software\n" " --legacy: use legacy interrupt-based scaling\n" " --empty-poll: enable empty poll detection" @@ -1619,10 +1630,32 @@ print_usage(const char *prgname) " empty polls, full polls, and core busyness to telemetry\n" " --interrupt-only: enable interrupt-only mode\n" " --pmd-mgmt MODE: enable PMD power management mode. " - "Currently supported modes: baseline, monitor, pause, scale\n", + "Currently supported modes: baseline, monitor, pause, scale\n" + " --max-empty-polls MAX_EMPTY_POLLS: number of empty polls to" + " wait before entering sleep state\n" + " --pause-duration DURATION: set the duration, in microseconds," + " of the pause callback\n" + " --scale-freq-min FREQ_MIN: set minimum frequency for scaling mode for" + " all application lcores (FREQ_MIN must be in kHz, in increments of 100MHz)\n" + " --scale-freq-max FREQ_MAX: set maximum frequency for scaling mode for" + " all application lcores (FREQ_MAX must be in kHz, in increments of 100MHz)\n", prgname); } +static int +parse_int(const char *opt) +{ + char *end = NULL; + unsigned long val; + + /* parse integer string */ + val = strtoul(opt, &end, 10); + if ((opt[0] == '\0') || (end == NULL) || (*end != '\0')) + return -1; + + return val; +} + static int parse_max_pkt_len(const char *pktlen) { char *end = NULL; @@ -1795,6 +1828,11 @@ parse_ep_config(const char *q_arg) #define CMD_LINE_OPT_INTERRUPT_ONLY "interrupt-only" #define CMD_LINE_OPT_TELEMETRY "telemetry" #define CMD_LINE_OPT_PMD_MGMT "pmd-mgmt" +#define CMD_LINE_OPT_MAX_PKT_LEN "max-pkt-len" +#define CMD_LINE_OPT_MAX_EMPTY_POLLS "max-empty-polls" +#define CMD_LINE_OPT_PAUSE_DURATION "pause-duration" +#define CMD_LINE_OPT_SCALE_FREQ_MIN "scale-freq-min" +#define CMD_LINE_OPT_SCALE_FREQ_MAX "scale-freq-max" /* Parse the argument given in the command line of the application */ static int @@ -1810,13 +1848,17 @@ parse_args(int argc, char **argv) {"perf-config", 1, 0, 0}, {"high-perf-cores", 1, 0, 0}, {"no-numa", 0, 0, 0}, - {"enable-jumbo", 0, 0, 0}, + {CMD_LINE_OPT_MAX_PKT_LEN, 1, 0, 0}, {CMD_LINE_OPT_EMPTY_POLL, 1, 0, 0}, {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}, {CMD_LINE_OPT_PMD_MGMT, 1, 0, 0}, + {CMD_LINE_OPT_MAX_EMPTY_POLLS, 1, 0, 0}, + {CMD_LINE_OPT_PAUSE_DURATION, 1, 0, 0}, + {CMD_LINE_OPT_SCALE_FREQ_MIN, 1, 0, 0}, + {CMD_LINE_OPT_SCALE_FREQ_MAX, 1, 0, 0}, {NULL, 0, 0, 0} }; @@ -1954,36 +1996,10 @@ parse_args(int argc, char **argv) } if (!strncmp(lgopts[option_index].name, - "enable-jumbo", 12)) { - struct option lenopts = - {"max-pkt-len", required_argument, \ - 0, 0}; - - printf("jumbo frame is enabled \n"); - port_conf.rxmode.offloads |= - DEV_RX_OFFLOAD_JUMBO_FRAME; - port_conf.txmode.offloads |= - DEV_TX_OFFLOAD_MULTI_SEGS; - - /** - * if no max-pkt-len set, use the default value - * RTE_ETHER_MAX_LEN - */ - if (0 == getopt_long(argc, argvopt, "", - &lenopts, &option_index)) { - ret = parse_max_pkt_len(optarg); - if ((ret < 64) || - (ret > MAX_JUMBO_PKT_LEN)){ - printf("invalid packet " - "length\n"); - print_usage(prgname); - return -1; - } - port_conf.rxmode.max_rx_pkt_len = ret; - } - printf("set jumbo frame " - "max packet length to %u\n", - (unsigned int)port_conf.rxmode.max_rx_pkt_len); + CMD_LINE_OPT_MAX_PKT_LEN, + sizeof(CMD_LINE_OPT_MAX_PKT_LEN))) { + printf("Custom frame size is configured\n"); + max_pkt_len = parse_max_pkt_len(optarg); } if (!strncmp(lgopts[option_index].name, @@ -1993,6 +2009,34 @@ parse_args(int argc, char **argv) parse_ptype = 1; } + if (!strncmp(lgopts[option_index].name, + CMD_LINE_OPT_MAX_EMPTY_POLLS, + sizeof(CMD_LINE_OPT_MAX_EMPTY_POLLS))) { + printf("Maximum empty polls configured\n"); + max_empty_polls = parse_int(optarg); + } + + if (!strncmp(lgopts[option_index].name, + CMD_LINE_OPT_PAUSE_DURATION, + sizeof(CMD_LINE_OPT_PAUSE_DURATION))) { + printf("Pause duration configured\n"); + pause_duration = parse_int(optarg); + } + + if (!strncmp(lgopts[option_index].name, + CMD_LINE_OPT_SCALE_FREQ_MIN, + sizeof(CMD_LINE_OPT_SCALE_FREQ_MIN))) { + printf("Scaling frequency minimum configured\n"); + scale_freq_min = parse_int(optarg); + } + + if (!strncmp(lgopts[option_index].name, + CMD_LINE_OPT_SCALE_FREQ_MAX, + sizeof(CMD_LINE_OPT_SCALE_FREQ_MAX))) { + printf("Scaling frequency maximum configured\n"); + scale_freq_max = parse_int(optarg); + } + break; default: @@ -2222,7 +2266,7 @@ check_all_ports_link_status(uint32_t port_mask) continue; } /* clear all_ports_up flag if any link down */ - if (link.link_status == ETH_LINK_DOWN) { + if (link.link_status == RTE_ETH_LINK_DOWN) { all_ports_up = 0; break; } @@ -2376,7 +2420,7 @@ update_telemetry(__rte_unused struct rte_timer *tim, ret = rte_metrics_update_values(RTE_METRICS_GLOBAL, telstats_index, values, RTE_DIM(values)); if (ret < 0) - RTE_LOG(WARNING, POWER, "failed to update metrcis\n"); + RTE_LOG(WARNING, POWER, "failed to update metrics\n"); } static int @@ -2505,6 +2549,41 @@ mode_to_str(enum appmode mode) } } +static uint32_t +eth_dev_get_overhead_len(uint32_t max_rx_pktlen, uint16_t max_mtu) +{ + uint32_t overhead_len; + + if (max_mtu != UINT16_MAX && max_rx_pktlen > max_mtu) + overhead_len = max_rx_pktlen - max_mtu; + else + overhead_len = RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN; + + return overhead_len; +} + +static int +config_port_max_pkt_len(struct rte_eth_conf *conf, + struct rte_eth_dev_info *dev_info) +{ + uint32_t overhead_len; + + if (max_pkt_len == 0) + return 0; + + if (max_pkt_len < RTE_ETHER_MIN_LEN || max_pkt_len > MAX_JUMBO_PKT_LEN) + return -1; + + overhead_len = eth_dev_get_overhead_len(dev_info->max_rx_pktlen, + dev_info->max_mtu); + conf->rxmode.mtu = max_pkt_len - overhead_len; + + if (conf->rxmode.mtu > RTE_ETHER_MTU) + conf->txmode.offloads |= RTE_ETH_TX_OFFLOAD_MULTI_SEGS; + + return 0; +} + /* Power library initialized in the main routine. 8< */ int main(int argc, char **argv) @@ -2523,9 +2602,6 @@ main(int argc, char **argv) uint16_t portid; const char *ptr_strings[NUM_TELSTATS]; - /* catch SIGINT and restore cpufreq governor to ondemand */ - signal(SIGINT, signal_exit_now); - /* init EAL */ ret = rte_eal_init(argc, argv); if (ret < 0) @@ -2533,6 +2609,9 @@ main(int argc, char **argv) argc -= ret; argv += ret; + /* catch SIGINT and restore cpufreq governor to ondemand */ + signal(SIGINT, signal_exit_now); + /* init RTE timer library to be used late */ rte_timer_subsystem_init(); @@ -2622,9 +2701,15 @@ main(int argc, char **argv) "Error during getting device (port %u) info: %s\n", portid, strerror(-ret)); - if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE) + ret = config_port_max_pkt_len(&local_port_conf, &dev_info); + if (ret != 0) + rte_exit(EXIT_FAILURE, + "Invalid max packet length: %u (port %u)\n", + max_pkt_len, portid); + + if (dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) local_port_conf.txmode.offloads |= - DEV_TX_OFFLOAD_MBUF_FAST_FREE; + RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE; local_port_conf.rx_adv_conf.rss_conf.rss_hf &= dev_info.flow_type_rss_offloads; @@ -2637,6 +2722,11 @@ main(int argc, char **argv) local_port_conf.rx_adv_conf.rss_conf.rss_hf); } + if (local_port_conf.rx_adv_conf.rss_conf.rss_hf == 0) + local_port_conf.rxmode.mq_mode = RTE_ETH_MQ_RX_NONE; + local_port_conf.rxmode.offloads &= dev_info.rx_offload_capa; + port_conf.rxmode.offloads = local_port_conf.rxmode.offloads; + ret = rte_eth_dev_configure(portid, nb_rx_queue, (uint16_t)n_tx_queue, &local_port_conf); if (ret < 0) @@ -2773,6 +2863,28 @@ main(int argc, char **argv) } if (app_mode == APP_MODE_PMD_MGMT && !baseline_enabled) { + /* Set power_pmd_mgmt configs passed by user */ + rte_power_pmd_mgmt_set_emptypoll_max(max_empty_polls); + ret = rte_power_pmd_mgmt_set_pause_duration(pause_duration); + if (ret < 0) + rte_exit(EXIT_FAILURE, + "Error setting pause_duration: err=%d, lcore=%d\n", + ret, lcore_id); + + ret = rte_power_pmd_mgmt_set_scaling_freq_min(lcore_id, + scale_freq_min); + if (ret < 0) + rte_exit(EXIT_FAILURE, + "Error setting scaling freq min: err=%d, lcore=%d\n", + ret, lcore_id); + + ret = rte_power_pmd_mgmt_set_scaling_freq_max(lcore_id, + scale_freq_max); + if (ret < 0) + rte_exit(EXIT_FAILURE, + "Error setting scaling freq max: err=%d, lcore %d\n", + ret, lcore_id); + ret = rte_power_ethdev_pmgmt_queue_enable( lcore_id, portid, queueid, pmgmt_type);