Use link speed from device capability instead of negotiated speeda 51/66151/5
authorXavier Simonart <xavier.simonart@intel.com>
Wed, 19 Dec 2018 14:30:38 +0000 (15:30 +0100)
committerXavier Simonart <xavier.simonart@intel.com>
Wed, 20 Feb 2019 15:32:05 +0000 (16:32 +0100)
JIRA: SAMPLEVNF-151

link speed is used in gen and lat latency extrapolations.
Using a link_speed value lower than the actual link speed
might result in errors (e.g. negative latencies).
Negotiated link speed might be reported slowly (as reported through irq)
Hence it is better to use the device capability link speed.
In addition, this remove the check for link speed changes in fastpath.

Change-Id: I0f475fe5e139b046012de6cd0b710e4390735078
Signed-off-by: Xavier Simonart <xavier.simonart@intel.com>
VNFs/DPPD-PROX/handle_gen.c
VNFs/DPPD-PROX/handle_lat.c
VNFs/DPPD-PROX/prox_port_cfg.c
VNFs/DPPD-PROX/run.c

index 4040b33..000d017 100644 (file)
@@ -642,6 +642,8 @@ static int handle_gen_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, uin
 
        int i, j;
 
+#if RTE_VERSION < RTE_VERSION_NUM(16,4,0,0)
+       // On more recent DPDK, we use the speed_capa of the port, and not the negotiated speed
        // If link is down, link_speed is 0
        if (unlikely(task->link_speed == 0)) {
                if (task->port && task->port->link_speed != 0) {
@@ -651,6 +653,7 @@ static int handle_gen_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, uin
                } else
                        return 0;
        }
+#endif
 
        task_gen_update_config(task);
 
@@ -1197,6 +1200,7 @@ static void start(struct task_base *tbase)
        if (task->port) {
                // task->port->link_speed reports the link speed in Mbps e.g. 40k for a 40 Gbps NIC.
                // task->link_speed reports link speed in Bytes per sec.
+#if RTE_VERSION < RTE_VERSION_NUM(16,4,0,0)
                // It can be 0 if link is down, and must hence be updated in fast path.
                task->link_speed = task->port->link_speed * 125000L;
                if (task->link_speed)
@@ -1205,6 +1209,15 @@ static void start(struct task_base *tbase)
                else
                        plog_info("\tPort %u: link speed is %ld Mbps - link might be down\n",
                                (uint8_t)(task->port - prox_port_cfg), 8 * task->link_speed / 1000000);
+#else
+               if (task->port->link_speed == UINT32_MAX)
+                       task->link_speed = UINT64_MAX;
+               else {
+                       task->link_speed = task->port->link_speed * 125000L;
+                       plog_info("\tPort %u: link max speed is %ld Mbps\n",
+                               (uint8_t)(task->port - prox_port_cfg), 8 * task->link_speed / 1000000);
+               }
+#endif
        }
        /* TODO
           Handle the case when two tasks transmit to the same port
index 8c7de8f..0273230 100644 (file)
@@ -507,6 +507,8 @@ static int handle_lat_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, uin
        struct task_lat *task = (struct task_lat *)tbase;
        int rc;
 
+#if RTE_VERSION < RTE_VERSION_NUM(16,4,0,0)
+       // On more recent DPDK, we use the speed_capa of the port, and not the negotiated speed
        // If link is down, link_speed is 0
        if (unlikely(task->link_speed == 0)) {
                if (task->port && task->port->link_speed != 0) {
@@ -519,7 +521,7 @@ static int handle_lat_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, uin
                        return 0;
                }
        }
-
+#endif
        if (n_pkts == 0) {
                task->begin = tbase->aux->tsc_rx.before;
                return 0;
@@ -729,6 +731,7 @@ static void lat_start(struct task_base *tbase)
        if (task->port) {
                // task->port->link_speed reports the link speed in Mbps e.g. 40k for a 40 Gbps NIC.
                // task->link_speed reports link speed in Bytes per sec.
+#if RTE_VERSION < RTE_VERSION_NUM(16,4,0,0)
                // It can be 0 if link is down, and must hence be updated in fast path.
                task->link_speed = task->port->link_speed * 125000L;
                if (task->link_speed)
@@ -737,6 +740,15 @@ static void lat_start(struct task_base *tbase)
                else
                        plog_info("\tPort %u: link speed is %ld Mbps - link might be down\n",
                                (uint8_t)(task->port - prox_port_cfg), 8 * task->link_speed / 1000000);
+#else
+               if (task->port->link_speed == UINT32_MAX)
+                       task->link_speed = UINT64_MAX;
+               else {
+                       task->link_speed = task->port->link_speed * 125000L;
+                       plog_info("\tPort %u: link max speed is %ld Mbps\n",
+                               (uint8_t)(task->port - prox_port_cfg), 8 * task->link_speed / 1000000);
+               }
+#endif
        }
 }
 
index fc4971f..6dc023d 100644 (file)
@@ -311,6 +311,20 @@ uint8_t init_rte_ring_dev(void)
 
 static void print_port_capa(struct prox_port_cfg *port_cfg)
 {
+       uint8_t port_id;
+
+       port_id = port_cfg - prox_port_cfg;
+       plog_info("\t*** Initializing port %u ***\n", port_id);
+       plog_info("\t\tPort name is set to %s\n", port_cfg->name);
+       plog_info("\t\tPort max RX/TX queue is %u/%u\n", port_cfg->max_rxq, port_cfg->max_txq);
+       plog_info("\t\tPort driver is %s\n", port_cfg->driver_name);
+#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);
+       if (port_cfg->link_speed != UINT32_MAX) {
+               plog_info("\t\tHighest link speed capa = %d Mbps\n", port_cfg->link_speed);
+       }
+#endif
+
 #if RTE_VERSION >= RTE_VERSION_NUM(18,8,0,1)
        plog_info("\t\tRX offload capa = 0x%lx = ", port_cfg->dev_info.rx_offload_capa);
        if (port_cfg->dev_info.rx_offload_capa & DEV_RX_OFFLOAD_VLAN_STRIP)
@@ -396,6 +410,48 @@ static void print_port_capa(struct prox_port_cfg *port_cfg)
 #endif
 }
 
+static void get_link_speed(struct prox_port_cfg *port_cfg)
+{
+#if RTE_VERSION >= RTE_VERSION_NUM(16,4,0,0)
+       port_cfg->link_speed = UINT32_MAX;
+
+       // virtio and vmxnet3 reports fake 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->link_speed = ETH_SPEED_NUM_100G;
+               else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_56G)
+                       port_cfg->link_speed = ETH_SPEED_NUM_56G;
+               else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_50G)
+                       port_cfg->link_speed = ETH_SPEED_NUM_50G;
+               else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_40G)
+                       port_cfg->link_speed = ETH_SPEED_NUM_40G;
+               else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_25G)
+                       port_cfg->link_speed = ETH_SPEED_NUM_25G;
+               else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_20G)
+                       port_cfg->link_speed = ETH_SPEED_NUM_20G;
+               else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_10G)
+                       port_cfg->link_speed = ETH_SPEED_NUM_10G;
+               else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_5G)
+                       port_cfg->link_speed = ETH_SPEED_NUM_5G;
+               else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_2_5G)
+                       port_cfg->link_speed = ETH_SPEED_NUM_2_5G;
+               else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_1G)
+                       port_cfg->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->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->link_speed = ETH_SPEED_NUM_10M;
+
+       }
+#endif
+}
+
 static void init_port(struct prox_port_cfg *port_cfg)
 {
        static char dummy_pool_name[] = "0_dummy";
@@ -403,15 +459,9 @@ static void init_port(struct prox_port_cfg *port_cfg)
        uint8_t port_id;
        int ret;
 
+       get_link_speed(port_cfg);
+       print_port_capa(port_cfg);
        port_id = port_cfg - prox_port_cfg;
-       plog_info("\t*** Initializing port %u ***\n", port_id);
-       plog_info("\t\tPort name is set to %s\n", port_cfg->name);
-       plog_info("\t\tPort max RX/TX queue is %u/%u\n", port_cfg->max_rxq, port_cfg->max_txq);
-       plog_info("\t\tPort driver is %s\n", port_cfg->driver_name);
-#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);
 
@@ -449,8 +499,6 @@ static void init_port(struct prox_port_cfg *port_cfg)
                }
        }
 
-       print_port_capa(port_cfg);
-
        if (port_cfg->n_rxq > 1)  {
                // Enable RSS if multiple receive queues
                port_cfg->port_conf.rxmode.mq_mode                      |= ETH_MQ_RX_RSS;
@@ -604,7 +652,10 @@ static void init_port(struct prox_port_cfg *port_cfg)
                rte_eth_link_get(port_id, &link);
 
        port_cfg->link_up = link.link_status;
+#if RTE_VERSION < RTE_VERSION_NUM(16,4,0,0)
        port_cfg->link_speed = link.link_speed;
+#endif
+
        if (link.link_status) {
                plog_info("Link Up - speed %'u Mbps - %s\n",
                          link.link_speed,
index 6ffd76b..2ad8aca 100644 (file)
@@ -78,9 +78,14 @@ static void update_link_states(void)
 
                port_cfg  = &prox_port_cfg[portid];
                rte_eth_link_get_nowait(portid, &link);
-               port_cfg->link_up = link.link_status;
+#if RTE_VERSION < RTE_VERSION_NUM(16,4,0,0)
+               // On more recent DPDK, we use the speed_capa of the port, and not the negotiated speed
                port_cfg->link_speed = link.link_speed;
-               plog_info("Link speed now %d Mbps\n", port_cfg->link_speed);
+#endif
+               if (port_cfg->link_up != link.link_status) {
+                       port_cfg->link_up = link.link_status;
+                       plog_info("port %d: Link speed now %d Mbps\n", portid, link.link_speed);
+               }
        }
 }