app/testpmd: fix multicast address pool leak
[dpdk.git] / examples / l3fwd-power / main.c
index 52f56dc..887c6ea 100644 (file)
@@ -24,7 +24,6 @@
 #include <rte_memcpy.h>
 #include <rte_eal.h>
 #include <rte_launch.h>
-#include <rte_atomic.h>
 #include <rte_cycles.h>
 #include <rte_prefetch.h>
 #include <rte_lcore.h>
@@ -207,6 +206,7 @@ enum appmode {
 enum appmode app_mode;
 
 static enum rte_power_pmd_mgmt_type pmgmt_type;
+bool baseline_enabled;
 
 enum freq_scale_hint_t
 {
@@ -249,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];
 
 
@@ -432,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)
@@ -504,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
@@ -716,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 = &eth_hdr->d_addr.addr_bytes[0];
+               d_addr_bytes = &eth_hdr->dst_addr.addr_bytes[0];
                *((uint64_t *)d_addr_bytes) =
                        0x000000000002 + ((uint64_t)dst_port << 40);
 
@@ -728,7 +741,7 @@ l3fwd_simple_forward(struct rte_mbuf *m, uint16_t portid,
 
                /* src addr */
                rte_ether_addr_copy(&ports_eth_addr[dst_port],
-                               &eth_hdr->s_addr);
+                               &eth_hdr->src_addr);
 
                send_single_packet(m, dst_port);
        } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
@@ -748,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 = &eth_hdr->d_addr.addr_bytes[0];
+               d_addr_bytes = &eth_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],
-                               &eth_hdr->s_addr);
+                               &eth_hdr->src_addr);
 
                send_single_packet(m, dst_port);
 #else
@@ -910,7 +923,7 @@ static int event_register(struct lcore_conf *qconf)
        return 0;
 }
 
-/* main processing loop */
+/* Main processing loop. 8< */
 static int main_intr_loop(__rte_unused void *dummy)
 {
        struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
@@ -1073,6 +1086,7 @@ start_rx:
 
        return 0;
 }
+/* >8 End of main processing loop. */
 
 /* main processing loop */
 static int
@@ -1599,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"
@@ -1617,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: 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;
@@ -1714,6 +1749,7 @@ parse_pmd_mgmt_config(const char *name)
 #define PMD_MGMT_MONITOR "monitor"
 #define PMD_MGMT_PAUSE   "pause"
 #define PMD_MGMT_SCALE   "scale"
+#define PMD_MGMT_BASELINE  "baseline"
 
        if (strncmp(PMD_MGMT_MONITOR, name, sizeof(PMD_MGMT_MONITOR)) == 0) {
                pmgmt_type = RTE_POWER_MGMT_TYPE_MONITOR;
@@ -1729,6 +1765,10 @@ parse_pmd_mgmt_config(const char *name)
                pmgmt_type = RTE_POWER_MGMT_TYPE_SCALE;
                return 0;
        }
+       if (strncmp(PMD_MGMT_BASELINE, name, sizeof(PMD_MGMT_BASELINE)) == 0) {
+               baseline_enabled = true;
+               return 0;
+       }
        /* unknown PMD power management mode */
        return -1;
 }
@@ -1788,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
@@ -1803,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}
        };
 
@@ -1947,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,
@@ -1986,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:
@@ -2215,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;
                        }
@@ -2369,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
@@ -2498,6 +2549,42 @@ 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)
 {
@@ -2515,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)
@@ -2525,9 +2609,15 @@ 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();
 
+       /* if we're running pmd-mgmt mode, don't default to baseline mode */
+       baseline_enabled = false;
+
        /* parse application arguments (after the EAL ones) */
        ret = parse_args(argc, argv);
        if (ret < 0)
@@ -2611,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;
@@ -2626,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)
@@ -2761,7 +2862,29 @@ main(int argc, char **argv)
                                                 "Fail to add ptype cb\n");
                        }
 
-                       if (app_mode == APP_MODE_PMD_MGMT) {
+                       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);
@@ -2772,6 +2895,7 @@ main(int argc, char **argv)
                        }
                }
        }
+       /* >8 End of power library initialization. */
 
        printf("\n");