Merge "PROX generator: performance optimization (2/4)"
[samplevnf.git] / VNFs / DPPD-PROX / prox_port_cfg.c
index a71d0cc..a538be4 100644 (file)
@@ -224,16 +224,6 @@ void init_rte_dev(int use_dummy_devices)
                port_cfg->max_rx_pkt_len = dev_info.max_rx_pktlen;
                port_cfg->min_rx_bufsize = dev_info.min_rx_bufsize;
 
-#if RTE_VERSION < RTE_VERSION_NUM(18,5,0,0)
-               pci_dev = dev_info.pci_dev;
-#else
-               pci_dev = RTE_DEV_TO_PCI(dev_info.device);
-#endif
-               if (!pci_dev)
-                       continue;
-
-               snprintf(port_cfg->pci_addr, sizeof(port_cfg->pci_addr),
-                        "%04x:%02x:%02x.%1x", pci_dev->addr.domain, pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function);
                strncpy(port_cfg->driver_name, dev_info.driver_name, sizeof(port_cfg->driver_name));
                plog_info("\tPort %u : driver='%s' tx_queues=%d rx_queues=%d\n", port_id, !strcmp(port_cfg->driver_name, "")? "null" : port_cfg->driver_name, port_cfg->max_txq, port_cfg->max_rxq);
 
@@ -249,6 +239,18 @@ void init_rte_dev(int use_dummy_devices)
                        *ptr = '\x0';
                }
 
+#if RTE_VERSION < RTE_VERSION_NUM(18,5,0,0)
+               pci_dev = dev_info.pci_dev;
+#else
+               if (!dev_info.device)
+                       continue;
+               pci_dev = RTE_DEV_TO_PCI(dev_info.device);
+#endif
+               if (!pci_dev)
+                       continue;
+
+               snprintf(port_cfg->pci_addr, sizeof(port_cfg->pci_addr),
+                        "%04x:%02x:%02x.%1x", pci_dev->addr.domain, pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function);
                /* Try to find the device's numa node */
                char buf[1024];
                snprintf(buf, sizeof(buf), "/sys/bus/pci/devices/%s/numa_node", port_cfg->pci_addr);
@@ -307,12 +309,9 @@ uint8_t init_rte_ring_dev(void)
        return nb_ring_dev;
 }
 
-static void init_port(struct prox_port_cfg *port_cfg)
+static void print_port_capa(struct prox_port_cfg *port_cfg)
 {
-       static char dummy_pool_name[] = "0_dummy";
-       struct rte_eth_link link;
        uint8_t port_id;
-       int ret;
 
        port_id = port_cfg - prox_port_cfg;
        plog_info("\t*** Initializing port %u ***\n", port_id);
@@ -322,54 +321,8 @@ static void init_port(struct prox_port_cfg *port_cfg)
 #if RTE_VERSION >= RTE_VERSION_NUM(16,4,0,0)
        plog_info("\t\tSupported speed mask = 0x%x\n", port_cfg->dev_info.speed_capa);
 #endif
-
-       PROX_PANIC(port_cfg->n_rxq == 0 && port_cfg->n_txq == 0,
-                  "\t\t port %u is enabled but no RX or TX queues have been configured", port_id);
-
-       if (port_cfg->n_rxq == 0) {
-               /* not receiving on this port */
-               plog_info("\t\tPort %u had no RX queues, setting to 1\n", port_id);
-               port_cfg->n_rxq = 1;
-               uint32_t mbuf_size = TX_MBUF_SIZE;
-               plog_info("\t\tAllocating dummy memory pool on socket %u with %u elements of size %u\n",
-                         port_cfg->socket, port_cfg->n_rxd, mbuf_size);
-               port_cfg->pool[0] = rte_mempool_create(dummy_pool_name, port_cfg->n_rxd, mbuf_size,
-                                                      0,
-                                                      sizeof(struct rte_pktmbuf_pool_private),
-                                                      rte_pktmbuf_pool_init, NULL,
-                                                      prox_pktmbuf_init, 0,
-                                                      port_cfg->socket, 0);
-               PROX_PANIC(port_cfg->pool[0] == NULL, "Failed to allocate dummy memory pool on socket %u with %u elements\n",
-                          port_cfg->socket, port_cfg->n_rxd);
-               dummy_pool_name[0]++;
-       } else {
-               // Most pmd should now support setting mtu
-               if (port_cfg->mtu + ETHER_HDR_LEN + ETHER_CRC_LEN > port_cfg->max_rx_pkt_len) {
-                       plog_info("\t\tMTU is too big for the port, reducing MTU from %d to %d\n", port_cfg->mtu, port_cfg->max_rx_pkt_len);
-                       port_cfg->mtu = port_cfg->max_rx_pkt_len;
-               }
-               plog_info("\t\tSetting MTU size to %u for port %u ...\n", port_cfg->mtu, port_id);
-               ret = rte_eth_dev_set_mtu(port_id, port_cfg->mtu);
-               if (ret)
-                       plog_err("\t\t\trte_eth_dev_set_mtu() failed on port %u: error %d\n", port_id, ret);
-
-               if (port_cfg->n_txq == 0) {
-                       /* not sending on this port */
-                       plog_info("\t\tPort %u had no TX queues, setting to 1\n", port_id);
-                       port_cfg->n_txq = 1;
-               }
-       }
-
-       if (port_cfg->n_rxq > 1)  {
-               // Enable RSS if multiple receive queues
-               port_cfg->port_conf.rxmode.mq_mode                      |= ETH_MQ_RX_RSS;
-               port_cfg->port_conf.rx_adv_conf.rss_conf.rss_key        = toeplitz_init_key;
-               port_cfg->port_conf.rx_adv_conf.rss_conf.rss_key_len    = TOEPLITZ_KEY_LEN;
-#if RTE_VERSION >= RTE_VERSION_NUM(2,0,0,0)
-               port_cfg->port_conf.rx_adv_conf.rss_conf.rss_hf         = ETH_RSS_IPV4|ETH_RSS_NONFRAG_IPV4_UDP;
-#else
-               port_cfg->port_conf.rx_adv_conf.rss_conf.rss_hf         = ETH_RSS_IPV4|ETH_RSS_NONF_IPV4_UDP;
-#endif
+       if (port_cfg->max_link_speed != UINT32_MAX) {
+               plog_info("\t\tHighest link speed capa = %d Mbps\n", port_cfg->max_link_speed);
        }
 
 #if RTE_VERSION >= RTE_VERSION_NUM(18,8,0,1)
@@ -455,11 +408,120 @@ static void init_port(struct prox_port_cfg *port_cfg)
        plog_info("\t\tdefault RX port conf: burst_size = %d, ring_size = %d, nb_queues = %d\n", port_cfg->dev_info.default_rxportconf.burst_size, port_cfg->dev_info.default_rxportconf.ring_size, port_cfg->dev_info.default_rxportconf.nb_queues);
        plog_info("\t\tdefault TX port conf: burst_size = %d, ring_size = %d, nb_queues = %d\n", port_cfg->dev_info.default_txportconf.burst_size, port_cfg->dev_info.default_txportconf.ring_size, port_cfg->dev_info.default_txportconf.nb_queues);
 #endif
+}
+
+static void get_max_link_speed(struct prox_port_cfg *port_cfg)
+{
+       port_cfg->max_link_speed = UINT32_MAX;
+
+#if RTE_VERSION >= RTE_VERSION_NUM(16,4,0,0)
+       // virtio and vmxnet3 reports fake max_link_speed
+       if (strcmp(port_cfg->short_name, "vmxnet3") && strcmp(port_cfg->short_name, "virtio")) {
+               // Get link_speed from highest capability from the port
+               // This will be used by gen and lat for extrapolation purposes
+               // The negotiated link_speed (as reported by rte_eth_link_get
+               // or rte_eth_link_get_nowait) might be reported too late
+               // and might result in wrong exrapolation, and hence should not be used
+               // for extrapolation purposes
+               if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_100G)
+                       port_cfg->max_link_speed = ETH_SPEED_NUM_100G;
+               else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_56G)
+                       port_cfg->max_link_speed = ETH_SPEED_NUM_56G;
+               else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_50G)
+                       port_cfg->max_link_speed = ETH_SPEED_NUM_50G;
+               else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_40G)
+                       port_cfg->max_link_speed = ETH_SPEED_NUM_40G;
+               else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_25G)
+                       port_cfg->max_link_speed = ETH_SPEED_NUM_25G;
+               else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_20G)
+                       port_cfg->max_link_speed = ETH_SPEED_NUM_20G;
+               else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_10G)
+                       port_cfg->max_link_speed = ETH_SPEED_NUM_10G;
+               else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_5G)
+                       port_cfg->max_link_speed = ETH_SPEED_NUM_5G;
+               else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_2_5G)
+                       port_cfg->max_link_speed = ETH_SPEED_NUM_2_5G;
+               else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_1G)
+                       port_cfg->max_link_speed = ETH_SPEED_NUM_1G;
+               else if (port_cfg->dev_info.speed_capa & (ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M))
+                       port_cfg->max_link_speed = ETH_SPEED_NUM_100M;
+               else if (port_cfg->dev_info.speed_capa & (ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M))
+                       port_cfg->max_link_speed = ETH_SPEED_NUM_10M;
+
+       }
+#endif
+}
+
+static void init_port(struct prox_port_cfg *port_cfg)
+{
+       static char dummy_pool_name[] = "0_dummy";
+       struct rte_eth_link link;
+       uint8_t port_id;
+       int ret;
+
+       get_max_link_speed(port_cfg);
+       print_port_capa(port_cfg);
+       port_id = port_cfg - prox_port_cfg;
+       PROX_PANIC(port_cfg->n_rxq == 0 && port_cfg->n_txq == 0,
+                  "\t\t port %u is enabled but no RX or TX queues have been configured", port_id);
+
+       if (port_cfg->n_rxq == 0) {
+               /* not receiving on this port */
+               plog_info("\t\tPort %u had no RX queues, setting to 1\n", port_id);
+               port_cfg->n_rxq = 1;
+               uint32_t mbuf_size = TX_MBUF_SIZE;
+               plog_info("\t\tAllocating dummy memory pool on socket %u with %u elements of size %u\n",
+                         port_cfg->socket, port_cfg->n_rxd, mbuf_size);
+               port_cfg->pool[0] = rte_mempool_create(dummy_pool_name, port_cfg->n_rxd, mbuf_size,
+                                                      0,
+                                                      sizeof(struct rte_pktmbuf_pool_private),
+                                                      rte_pktmbuf_pool_init, NULL,
+                                                      prox_pktmbuf_init, 0,
+                                                      port_cfg->socket, 0);
+               PROX_PANIC(port_cfg->pool[0] == NULL, "Failed to allocate dummy memory pool on socket %u with %u elements\n",
+                          port_cfg->socket, port_cfg->n_rxd);
+               dummy_pool_name[0]++;
+       } else {
+               // Most pmd should now support setting mtu
+               if (port_cfg->mtu + ETHER_HDR_LEN + ETHER_CRC_LEN > port_cfg->max_rx_pkt_len) {
+                       plog_info("\t\tMTU is too big for the port, reducing MTU from %d to %d\n", port_cfg->mtu, port_cfg->max_rx_pkt_len);
+                       port_cfg->mtu = port_cfg->max_rx_pkt_len;
+               }
+               plog_info("\t\tSetting MTU size to %u for port %u ...\n", port_cfg->mtu, port_id);
+               ret = rte_eth_dev_set_mtu(port_id, port_cfg->mtu);
+               if (ret)
+                       plog_err("\t\t\trte_eth_dev_set_mtu() failed on port %u: error %d\n", port_id, ret);
+
+               if (port_cfg->n_txq == 0) {
+                       /* not sending on this port */
+                       plog_info("\t\tPort %u had no TX queues, setting to 1\n", port_id);
+                       port_cfg->n_txq = 1;
+               }
+       }
+
+       if (port_cfg->n_rxq > 1)  {
+               // Enable RSS if multiple receive queues
+               port_cfg->port_conf.rxmode.mq_mode                      |= ETH_MQ_RX_RSS;
+               port_cfg->port_conf.rx_adv_conf.rss_conf.rss_key        = toeplitz_init_key;
+               port_cfg->port_conf.rx_adv_conf.rss_conf.rss_key_len    = TOEPLITZ_KEY_LEN;
+#if RTE_VERSION >= RTE_VERSION_NUM(2,0,0,0)
+               port_cfg->port_conf.rx_adv_conf.rss_conf.rss_hf         = ETH_RSS_IP|ETH_RSS_UDP;
+#else
+               port_cfg->port_conf.rx_adv_conf.rss_conf.rss_hf         = ETH_RSS_IPV4|ETH_RSS_NONF_IPV4_UDP;
+#endif
+       }
+
+       // Make sure that the requested RSS offload is supported by the PMD
+#if RTE_VERSION >= RTE_VERSION_NUM(2,0,0,0)
+       port_cfg->port_conf.rx_adv_conf.rss_conf.rss_hf &= port_cfg->dev_info.flow_type_rss_offloads;
+#endif
+       plog_info("\t\t Enabling RSS rss_hf = 0x%lx (requested 0x%llx)\n", port_cfg->port_conf.rx_adv_conf.rss_conf.rss_hf, ETH_RSS_IP|ETH_RSS_UDP);
 
        // rxmode such as hw src strip
 #if RTE_VERSION >= RTE_VERSION_NUM(18,8,0,1)
        CONFIGURE_RX_OFFLOAD(DEV_RX_OFFLOAD_CRC_STRIP);
        CONFIGURE_RX_OFFLOAD(DEV_RX_OFFLOAD_JUMBO_FRAME);
+       CONFIGURE_RX_OFFLOAD(DEV_RX_OFFLOAD_VLAN_STRIP);
 #else
        if (port_cfg->requested_rx_offload & DEV_RX_OFFLOAD_CRC_STRIP) {
                port_cfg->port_conf.rxmode.hw_strip_crc = 1;
@@ -473,6 +535,7 @@ static void init_port(struct prox_port_cfg *port_cfg)
 #if RTE_VERSION >= RTE_VERSION_NUM(18,8,0,1)
        CONFIGURE_TX_OFFLOAD(DEV_TX_OFFLOAD_IPV4_CKSUM);
        CONFIGURE_TX_OFFLOAD(DEV_TX_OFFLOAD_UDP_CKSUM);
+       CONFIGURE_TX_OFFLOAD(DEV_TX_OFFLOAD_VLAN_INSERT);
 #else
        if ((port_cfg->dev_info.tx_offload_capa & (DEV_TX_OFFLOAD_IPV4_CKSUM | DEV_TX_OFFLOAD_UDP_CKSUM)) == 0) {
                port_cfg->tx_conf.txq_flags |= ETH_TXQ_FLAGS_NOOFFLOADS;
@@ -486,19 +549,6 @@ static void init_port(struct prox_port_cfg *port_cfg)
        // Multi Segments
 #if RTE_VERSION >= RTE_VERSION_NUM(18,8,0,1)
        CONFIGURE_TX_OFFLOAD(DEV_TX_OFFLOAD_MULTI_SEGS);
-       //if (port_cfg->requested_tx_offload & DEV_TX_OFFLOAD_MULTI_SEGS) {
-               //if (port_cfg->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MULTI_SEGS) {
-                       //port_cfg->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_MULTI_SEGS;
-                       //plog_info("\t\tMULTI SEGS TX offloads enabled on port)\n");
-               //} else if (port_cfg->dev_info.tx_queue_offload_capa & DEV_TX_OFFLOAD_MULTI_SEGS) {
-                       //port_cfg->tx_conf.offloads |= DEV_TX_OFFLOAD_MULTI_SEGS;
-                       //plog_info("\t\tMULTI SEGS TX offloads enabled on queue)\n");
-               //} else {
-                       //port_cfg->requested_tx_offload &= ~DEV_TX_OFFLOAD_MULTI_SEGS;
-                       //plog_info("\t\tMULTI SEGS TX offloads disabled) as neither port or queue supports it\n");
-               //}
-       //} else
-               //plog_info("\t\tMULTI SEGS TX offloads disabled)\n");
 #else
        if (!strcmp(port_cfg->short_name, "vmxnet3")) {
                port_cfg->tx_conf.txq_flags |= ETH_TXQ_FLAGS_NOMULTSEGS;
@@ -603,6 +653,7 @@ static void init_port(struct prox_port_cfg *port_cfg)
 
        port_cfg->link_up = link.link_status;
        port_cfg->link_speed = link.link_speed;
+
        if (link.link_status) {
                plog_info("Link Up - speed %'u Mbps - %s\n",
                          link.link_speed,