aboutsummaryrefslogtreecommitdiffstats
path: root/app/test-pmd/testpmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/test-pmd/testpmd.c')
-rw-r--r--app/test-pmd/testpmd.c389
1 files changed, 296 insertions, 93 deletions
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index a0332c26..d1041afa 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -1,7 +1,7 @@
/*-
* BSD LICENSE
*
- * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -59,6 +59,7 @@
#include <rte_memzone.h>
#include <rte_launch.h>
#include <rte_eal.h>
+#include <rte_alarm.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include <rte_atomic.h>
@@ -78,6 +79,14 @@
#ifdef RTE_LIBRTE_PDUMP
#include <rte_pdump.h>
#endif
+#include <rte_flow.h>
+#include <rte_metrics.h>
+#ifdef RTE_LIBRTE_BITRATE
+#include <rte_bitrate.h>
+#endif
+#ifdef RTE_LIBRTE_LATENCY_STATS
+#include <rte_latencystats.h>
+#endif
#include "testpmd.h"
@@ -86,6 +95,7 @@ uint16_t verbose_level = 0; /**< Silent by default. */
/* use master core for command line ? */
uint8_t interactive = 0;
uint8_t auto_start = 0;
+char cmdline_filename[PATH_MAX] = {0};
/*
* NUMA support configuration.
@@ -94,7 +104,7 @@ uint8_t auto_start = 0;
* probed ports among the CPU sockets 0 and 1.
* Otherwise, all memory is allocated from CPU socket 0.
*/
-uint8_t numa_support = 0; /**< No numa support by default */
+uint8_t numa_support = 1; /**< numa enabled by default */
/*
* In UMA mode,all memory is allocated from socket 0 if --socket-num is
@@ -110,7 +120,7 @@ uint8_t mp_anon = 0;
/*
* Record the Ethernet address of peer target ports to which packets are
* forwarded.
- * Must be instanciated with the ethernet addresses of peer traffic generator
+ * Must be instantiated with the ethernet addresses of peer traffic generator
* ports.
*/
struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
@@ -262,6 +272,27 @@ uint8_t no_flush_rx = 0; /* flush by default */
uint8_t no_link_check = 0; /* check by default */
/*
+ * Enable link status change notification
+ */
+uint8_t lsc_interrupt = 1; /* enabled by default */
+
+/*
+ * Enable device removal notification.
+ */
+uint8_t rmv_interrupt = 1; /* enabled by default */
+
+/*
+ * Display or mask ether events
+ * Default to all events except VF_MBOX
+ */
+uint32_t event_print_mask = (UINT32_C(1) << RTE_ETH_EVENT_UNKNOWN) |
+ (UINT32_C(1) << RTE_ETH_EVENT_INTR_LSC) |
+ (UINT32_C(1) << RTE_ETH_EVENT_QUEUE_STATE) |
+ (UINT32_C(1) << RTE_ETH_EVENT_INTR_RESET) |
+ (UINT32_C(1) << RTE_ETH_EVENT_MACSEC) |
+ (UINT32_C(1) << RTE_ETH_EVENT_INTR_RMV);
+
+/*
* NIC bypass mode configuration options.
*/
#ifdef RTE_NIC_BYPASS
@@ -271,6 +302,20 @@ uint32_t bypass_timeout = RTE_BYPASS_TMT_OFF;
#endif
+#ifdef RTE_LIBRTE_LATENCY_STATS
+
+/*
+ * Set when latency stats is enabled in the commandline
+ */
+uint8_t latencystats_enabled;
+
+/*
+ * Lcore ID to serive latency statistics.
+ */
+lcoreid_t latencystats_lcore_id = -1;
+
+#endif
+
/*
* Ethernet device configuration.
*/
@@ -283,7 +328,7 @@ struct rte_eth_rxmode rx_mode = {
.hw_vlan_strip = 1, /**< VLAN strip enabled. */
.hw_vlan_extend = 0, /**< Extended VLAN disabled. */
.jumbo_frame = 0, /**< Jumbo Frame Support disabled. */
- .hw_strip_crc = 0, /**< CRC stripping by hardware disabled. */
+ .hw_strip_crc = 1, /**< CRC stripping by hardware enabled. */
};
struct rte_fdir_conf fdir_conf = {
@@ -320,11 +365,22 @@ struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_a
uint16_t nb_tx_queue_stats_mappings = 0;
uint16_t nb_rx_queue_stats_mappings = 0;
-unsigned max_socket = 0;
+unsigned int num_sockets = 0;
+unsigned int socket_ids[RTE_MAX_NUMA_NODES];
+
+#ifdef RTE_LIBRTE_BITRATE
+/* Bitrate statistics */
+struct rte_stats_bitrates *bitrate_data;
+lcoreid_t bitrate_lcore_id;
+uint8_t bitrate_enabled;
+#endif
/* Forward function declarations */
static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port);
static void check_all_ports_link_status(uint32_t port_mask);
+static void eth_event_callback(uint8_t port_id,
+ enum rte_eth_event_type type,
+ void *param);
/*
* Check if all the ports are started.
@@ -333,17 +389,19 @@ static void check_all_ports_link_status(uint32_t port_mask);
static int all_ports_started(void);
/*
- * Find next enabled port
+ * Helper function to check if socket is allready discovered.
+ * If yes, return positive value. If not, return zero.
*/
-portid_t
-find_next_port(portid_t p, struct rte_port *ports, int size)
+int
+new_socket_id(unsigned int socket_id)
{
- if (ports == NULL)
- rte_exit(-EINVAL, "failed to find a next port id\n");
+ unsigned int i;
- while ((p < size) && (ports[p].enabled == 0))
- p++;
- return p;
+ for (i = 0; i < num_sockets; i++) {
+ if (socket_ids[i] == socket_id)
+ return 0;
+ }
+ return 1;
}
/*
@@ -358,11 +416,14 @@ set_default_fwd_lcores_config(void)
nb_lc = 0;
for (i = 0; i < RTE_MAX_LCORE; i++) {
- sock_num = rte_lcore_to_socket_id(i) + 1;
- if (sock_num > max_socket) {
- if (sock_num > RTE_MAX_NUMA_NODES)
- rte_exit(EXIT_FAILURE, "Total sockets greater than %u\n", RTE_MAX_NUMA_NODES);
- max_socket = sock_num;
+ sock_num = rte_lcore_to_socket_id(i);
+ if (new_socket_id(sock_num)) {
+ if (num_sockets >= RTE_MAX_NUMA_NODES) {
+ rte_exit(EXIT_FAILURE,
+ "Total sockets greater than %u\n",
+ RTE_MAX_NUMA_NODES);
+ }
+ socket_ids[num_sockets++] = sock_num;
}
if (!rte_lcore_is_enabled(i))
continue;
@@ -476,7 +537,7 @@ check_socket_id(const unsigned int socket_id)
{
static int warning_once = 0;
- if (socket_id >= max_socket) {
+ if (new_socket_id(socket_id)) {
if (!warning_once && numa_support)
printf("Warning: NUMA should be configured manually by"
" using --port-numa-config and"
@@ -499,6 +560,13 @@ init_config(void)
uint8_t port_per_socket[RTE_MAX_NUMA_NODES];
memset(port_per_socket,0,RTE_MAX_NUMA_NODES);
+
+ if (numa_support) {
+ memset(port_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
+ memset(rxring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
+ memset(txring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
+ }
+
/* Configuration of logical cores. */
fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
sizeof(struct fwd_lcore *) * nb_lcores,
@@ -518,35 +586,7 @@ init_config(void)
fwd_lcores[lc_id]->cpuid_idx = lc_id;
}
- /*
- * Create pools of mbuf.
- * If NUMA support is disabled, create a single pool of mbuf in
- * socket 0 memory by default.
- * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
- *
- * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
- * nb_txd can be configured at run time.
- */
- if (param_total_num_mbufs)
- nb_mbuf_per_pool = param_total_num_mbufs;
- else {
- nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + (nb_lcores * mb_mempool_cache)
- + RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
-
- if (!numa_support)
- nb_mbuf_per_pool =
- (nb_mbuf_per_pool * RTE_MAX_ETHPORTS);
- }
-
- if (!numa_support) {
- if (socket_num == UMA_NO_CONFIG)
- mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
- else
- mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
- socket_num);
- }
-
- FOREACH_PORT(pid, ports) {
+ RTE_ETH_FOREACH_DEV(pid) {
port = &ports[pid];
rte_eth_dev_info_get(pid, &port->dev_info);
@@ -568,20 +608,38 @@ init_config(void)
port->need_reconfig_queues = 1;
}
+ /*
+ * Create pools of mbuf.
+ * If NUMA support is disabled, create a single pool of mbuf in
+ * socket 0 memory by default.
+ * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
+ *
+ * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
+ * nb_txd can be configured at run time.
+ */
+ if (param_total_num_mbufs)
+ nb_mbuf_per_pool = param_total_num_mbufs;
+ else {
+ nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX +
+ (nb_lcores * mb_mempool_cache) +
+ RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
+ nb_mbuf_per_pool *= RTE_MAX_ETHPORTS;
+ }
+
if (numa_support) {
uint8_t i;
- unsigned int nb_mbuf;
-
- if (param_total_num_mbufs)
- nb_mbuf_per_pool = nb_mbuf_per_pool/nb_ports;
- for (i = 0; i < max_socket; i++) {
- nb_mbuf = (nb_mbuf_per_pool * RTE_MAX_ETHPORTS);
- if (nb_mbuf)
- mbuf_pool_create(mbuf_data_size,
- nb_mbuf,i);
- }
+ for (i = 0; i < num_sockets; i++)
+ mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
+ socket_ids[i]);
+ } else {
+ if (socket_num == UMA_NO_CONFIG)
+ mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
+ else
+ mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
+ socket_num);
}
+
init_port_config();
/*
@@ -631,7 +689,7 @@ init_fwd_streams(void)
queueid_t q;
/* set socket id according to numa or not */
- FOREACH_PORT(pid, ports) {
+ RTE_ETH_FOREACH_DEV(pid) {
port = &ports[pid];
if (nb_rxq > port->dev_info.max_rx_queues) {
printf("Fail: nb_rxq(%d) is greater than "
@@ -921,12 +979,42 @@ run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
struct fwd_stream **fsm;
streamid_t nb_fs;
streamid_t sm_id;
-
+#ifdef RTE_LIBRTE_BITRATE
+ uint64_t tics_per_1sec;
+ uint64_t tics_datum;
+ uint64_t tics_current;
+ uint8_t idx_port, cnt_ports;
+
+ cnt_ports = rte_eth_dev_count();
+ tics_datum = rte_rdtsc();
+ tics_per_1sec = rte_get_timer_hz();
+#endif
fsm = &fwd_streams[fc->stream_idx];
nb_fs = fc->stream_nb;
do {
for (sm_id = 0; sm_id < nb_fs; sm_id++)
(*pkt_fwd)(fsm[sm_id]);
+#ifdef RTE_LIBRTE_BITRATE
+ if (bitrate_enabled != 0 &&
+ bitrate_lcore_id == rte_lcore_id()) {
+ tics_current = rte_rdtsc();
+ if (tics_current - tics_datum >= tics_per_1sec) {
+ /* Periodic bitrate calculation */
+ for (idx_port = 0;
+ idx_port < cnt_ports;
+ idx_port++)
+ rte_stats_bitrate_calc(bitrate_data,
+ idx_port);
+ tics_datum = tics_current;
+ }
+ }
+#endif
+#ifdef RTE_LIBRTE_LATENCY_STATS
+ if (latencystats_enabled != 0 &&
+ latencystats_lcore_id == rte_lcore_id())
+ rte_latencystats_update();
+#endif
+
} while (! fc->stopped);
}
@@ -1252,7 +1340,7 @@ all_ports_started(void)
portid_t pi;
struct rte_port *port;
- FOREACH_PORT(pi, ports) {
+ RTE_ETH_FOREACH_DEV(pi) {
port = &ports[pi];
/* Check if there is a port which is not started */
if ((port->port_status != RTE_PORT_STARTED) &&
@@ -1270,7 +1358,7 @@ all_ports_stopped(void)
portid_t pi;
struct rte_port *port;
- FOREACH_PORT(pi, ports) {
+ RTE_ETH_FOREACH_DEV(pi) {
port = &ports[pi];
if ((port->port_status != RTE_PORT_STOPPED) &&
(port->slave_flag == 0))
@@ -1312,13 +1400,14 @@ start_port(portid_t pid)
queueid_t qi;
struct rte_port *port;
struct ether_addr mac_addr;
+ enum rte_eth_event_type event_type;
if (port_id_is_invalid(pid, ENABLED_WARN))
return 0;
if(dcb_config)
dcb_test = 1;
- FOREACH_PORT(pi, ports) {
+ RTE_ETH_FOREACH_DEV(pi) {
if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
continue;
@@ -1423,6 +1512,21 @@ start_port(portid_t pid)
return -1;
}
}
+
+ for (event_type = RTE_ETH_EVENT_UNKNOWN;
+ event_type < RTE_ETH_EVENT_MAX;
+ event_type++) {
+ diag = rte_eth_dev_callback_register(pi,
+ event_type,
+ eth_event_callback,
+ NULL);
+ if (diag) {
+ printf("Failed to setup even callback for event %d\n",
+ event_type);
+ return -1;
+ }
+ }
+
/* start port */
if (rte_eth_dev_start(pi) < 0) {
printf("Fail to start port %d\n", pi);
@@ -1475,7 +1579,7 @@ stop_port(portid_t pid)
printf("Stopping ports...\n");
- FOREACH_PORT(pi, ports) {
+ RTE_ETH_FOREACH_DEV(pi) {
if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
continue;
@@ -1518,7 +1622,7 @@ close_port(portid_t pid)
printf("Closing ports...\n");
- FOREACH_PORT(pi, ports) {
+ RTE_ETH_FOREACH_DEV(pi) {
if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
continue;
@@ -1545,6 +1649,8 @@ close_port(portid_t pid)
continue;
}
+ if (port->flow_list)
+ port_flow_flush(pi);
rte_eth_dev_close(pi);
if (rte_atomic16_cmpset(&(port->port_status),
@@ -1571,7 +1677,6 @@ attach_port(char *identifier)
if (rte_eth_dev_attach(identifier, &pi))
return;
- ports[pi].enabled = 1;
socket_id = (unsigned)rte_eth_dev_socket_id(pi);
/* if socket_id is invalid, set to 0 */
if (check_socket_id(socket_id) < 0)
@@ -1599,10 +1704,12 @@ detach_port(uint8_t port_id)
return;
}
+ if (ports[port_id].flow_list)
+ port_flow_flush(port_id);
+
if (rte_eth_dev_detach(port_id, name))
return;
- ports[port_id].enabled = 0;
nb_ports = rte_eth_dev_count();
printf("Port '%s' is detached. Now total ports is %d\n",
@@ -1621,7 +1728,7 @@ pmd_test_exit(void)
if (ports != NULL) {
no_link_check = 1;
- FOREACH_PORT(pt_id, ports) {
+ RTE_ETH_FOREACH_DEV(pt_id) {
printf("\nShutting down port %d...\n", pt_id);
fflush(stdout);
stop_port(pt_id);
@@ -1652,7 +1759,7 @@ check_all_ports_link_status(uint32_t port_mask)
fflush(stdout);
for (count = 0; count <= MAX_CHECK_TIME; count++) {
all_ports_up = 1;
- FOREACH_PORT(portid, ports) {
+ RTE_ETH_FOREACH_DEV(portid) {
if ((port_mask & (1 << portid)) == 0)
continue;
memset(&link, 0, sizeof(link));
@@ -1689,6 +1796,70 @@ check_all_ports_link_status(uint32_t port_mask)
if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
print_flag = 1;
}
+
+ if (lsc_interrupt)
+ break;
+ }
+}
+
+static void
+rmv_event_callback(void *arg)
+{
+ struct rte_eth_dev *dev;
+ struct rte_devargs *da;
+ char name[32] = "";
+ uint8_t port_id = (intptr_t)arg;
+
+ RTE_ETH_VALID_PORTID_OR_RET(port_id);
+ dev = &rte_eth_devices[port_id];
+ da = dev->device->devargs;
+
+ stop_port(port_id);
+ close_port(port_id);
+ if (da->type == RTE_DEVTYPE_VIRTUAL)
+ snprintf(name, sizeof(name), "%s", da->virt.drv_name);
+ else if (da->type == RTE_DEVTYPE_WHITELISTED_PCI)
+ rte_pci_device_name(&da->pci.addr, name, sizeof(name));
+ printf("removing device %s\n", name);
+ rte_eal_dev_detach(name);
+ dev->state = RTE_ETH_DEV_UNUSED;
+}
+
+/* This function is used by the interrupt thread */
+static void
+eth_event_callback(uint8_t port_id, enum rte_eth_event_type type, void *param)
+{
+ static const char * const event_desc[] = {
+ [RTE_ETH_EVENT_UNKNOWN] = "Unknown",
+ [RTE_ETH_EVENT_INTR_LSC] = "LSC",
+ [RTE_ETH_EVENT_QUEUE_STATE] = "Queue state",
+ [RTE_ETH_EVENT_INTR_RESET] = "Interrupt reset",
+ [RTE_ETH_EVENT_VF_MBOX] = "VF Mbox",
+ [RTE_ETH_EVENT_MACSEC] = "MACsec",
+ [RTE_ETH_EVENT_INTR_RMV] = "device removal",
+ [RTE_ETH_EVENT_MAX] = NULL,
+ };
+
+ RTE_SET_USED(param);
+
+ if (type >= RTE_ETH_EVENT_MAX) {
+ fprintf(stderr, "\nPort %" PRIu8 ": %s called upon invalid event %d\n",
+ port_id, __func__, type);
+ fflush(stderr);
+ } else if (event_print_mask & (UINT32_C(1) << type)) {
+ printf("\nPort %" PRIu8 ": %s event\n", port_id,
+ event_desc[type]);
+ fflush(stdout);
+ }
+
+ switch (type) {
+ case RTE_ETH_EVENT_INTR_RMV:
+ if (rte_eal_alarm_set(100000,
+ rmv_event_callback, (void *)(intptr_t)port_id))
+ fprintf(stderr, "Could not set up deferred device removal\n");
+ break;
+ default:
+ break;
}
}
@@ -1817,7 +1988,7 @@ init_port_config(void)
portid_t pid;
struct rte_port *port;
- FOREACH_PORT(pid, ports) {
+ RTE_ETH_FOREACH_DEV(pid) {
port = &ports[pid];
port->dev_conf.rxmode = rx_mode;
port->dev_conf.fdir_conf = fdir_conf;
@@ -1829,24 +2000,13 @@ init_port_config(void)
port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
}
- if (port->dcb_flag == 0 && port->dev_info.max_vfs == 0) {
+ if (port->dcb_flag == 0) {
if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
else
port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
}
- if (port->dev_info.max_vfs != 0) {
- if (port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
- port->dev_conf.rxmode.mq_mode =
- ETH_MQ_RX_VMDQ_RSS;
- else
- port->dev_conf.rxmode.mq_mode =
- ETH_MQ_RX_NONE;
-
- port->dev_conf.txmode.mq_mode = ETH_MQ_TX_NONE;
- }
-
rxtx_port_config(port);
rte_eth_macaddr_get(pid, &port->eth_addr);
@@ -1855,6 +2015,15 @@ init_port_config(void)
#ifdef RTE_NIC_BYPASS
rte_eth_dev_bypass_init(pid);
#endif
+
+ if (lsc_interrupt &&
+ (rte_eth_devices[pid].data->dev_flags &
+ RTE_ETH_DEV_INTR_LSC))
+ port->dev_conf.intr_conf.lsc = 1;
+ if (rmv_interrupt &&
+ (rte_eth_devices[pid].data->dev_flags &
+ RTE_ETH_DEV_INTR_RMV))
+ port->dev_conf.intr_conf.rmv = 1;
}
}
@@ -1907,7 +2076,7 @@ get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf =
&eth_conf->tx_adv_conf.vmdq_dcb_tx_conf;
- /* VMDQ+DCB RX and TX configrations */
+ /* VMDQ+DCB RX and TX configurations */
vmdq_rx_conf->enable_default_pool = 0;
vmdq_rx_conf->default_pool = 0;
vmdq_rx_conf->nb_queue_pools =
@@ -1938,9 +2107,9 @@ get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
rx_conf->nb_tcs = num_tcs;
tx_conf->nb_tcs = num_tcs;
- for (i = 0; i < num_tcs; i++) {
- rx_conf->dcb_tc[i] = i;
- tx_conf->dcb_tc[i] = i;
+ for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
+ rx_conf->dcb_tc[i] = i % num_tcs;
+ tx_conf->dcb_tc[i] = i % num_tcs;
}
eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS;
eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_hf;
@@ -2041,8 +2210,6 @@ init_port_dcb_config(portid_t pid,
static void
init_port(void)
{
- portid_t pid;
-
/* Configuration of Ethernet ports. */
ports = rte_zmalloc("testpmd: ports",
sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
@@ -2052,10 +2219,6 @@ init_port(void)
"rte_zmalloc(%d struct rte_port) failed\n",
RTE_MAX_ETHPORTS);
}
-
- /* enabled allocated ports */
- for (pid = 0; pid < nb_ports; pid++)
- ports[pid].enabled = 1;
}
static void
@@ -2075,6 +2238,9 @@ signal_handler(int signum)
/* uninitialize packet capture framework */
rte_pdump_uninit();
#endif
+#ifdef RTE_LIBRTE_LATENCY_STATS
+ rte_latencystats_uninit();
+#endif
force_quit();
/* exit with the expected status */
signal(signum, SIG_DFL);
@@ -2112,6 +2278,14 @@ main(int argc, char** argv)
rte_panic("Empty set of forwarding logical cores - check the "
"core mask supplied in the command parameters\n");
+ /* Bitrate/latency stats disabled by default */
+#ifdef RTE_LIBRTE_BITRATE
+ bitrate_enabled = 0;
+#endif
+#ifdef RTE_LIBRTE_LATENCY_STATS
+ latencystats_enabled = 0;
+#endif
+
argc -= diag;
argv += diag;
if (argc > 1)
@@ -2130,16 +2304,45 @@ main(int argc, char** argv)
rte_exit(EXIT_FAILURE, "Start ports failed\n");
/* set all ports to promiscuous mode by default */
- FOREACH_PORT(port_id, ports)
+ RTE_ETH_FOREACH_DEV(port_id)
rte_eth_promiscuous_enable(port_id);
+ /* Init metrics library */
+ rte_metrics_init(rte_socket_id());
+
+#ifdef RTE_LIBRTE_LATENCY_STATS
+ if (latencystats_enabled != 0) {
+ int ret = rte_latencystats_init(1, NULL);
+ if (ret)
+ printf("Warning: latencystats init()"
+ " returned error %d\n", ret);
+ printf("Latencystats running on lcore %d\n",
+ latencystats_lcore_id);
+ }
+#endif
+
+ /* Setup bitrate stats */
+#ifdef RTE_LIBRTE_BITRATE
+ if (bitrate_enabled != 0) {
+ bitrate_data = rte_stats_bitrate_create();
+ if (bitrate_data == NULL)
+ rte_exit(EXIT_FAILURE,
+ "Could not allocate bitrate data.\n");
+ rte_stats_bitrate_reg(bitrate_data);
+ }
+#endif
+
#ifdef RTE_LIBRTE_CMDLINE
+ if (strlen(cmdline_filename) != 0)
+ cmdline_read_from_file(cmdline_filename);
+
if (interactive == 1) {
if (auto_start) {
printf("Start automatic packet forwarding\n");
start_packet_forwarding(0);
}
prompt();
+ pmd_test_exit();
} else
#endif
{