aboutsummaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/bbdev_app/main.c6
-rw-r--r--examples/bond/main.c15
-rw-r--r--examples/distributor/main.c13
-rw-r--r--examples/ethtool/Makefile2
-rw-r--r--examples/ethtool/ethtool-app/main.c2
-rw-r--r--examples/ethtool/lib/Makefile2
-rw-r--r--examples/eventdev_pipeline/main.c13
-rw-r--r--examples/exception_path/main.c5
-rw-r--r--examples/flow_classify/flow_classify.c2
-rw-r--r--examples/flow_filtering/main.c17
-rw-r--r--examples/ip_fragmentation/main.c2
-rw-r--r--examples/ip_pipeline/Makefile2
-rw-r--r--examples/ip_pipeline/cli.c859
-rw-r--r--examples/ip_pipeline/examples/rss.cli112
-rw-r--r--examples/ip_pipeline/link.c20
-rw-r--r--examples/ip_pipeline/link.h3
-rw-r--r--examples/ip_pipeline/thread.c639
-rw-r--r--examples/ip_reassembly/main.c14
-rw-r--r--examples/ipsec-secgw/ipsec-secgw.c27
-rw-r--r--examples/ipsec-secgw/ipsec.h2
-rw-r--r--examples/ipsec-secgw/sa.c2
-rw-r--r--examples/ipv4_multicast/main.c2
-rw-r--r--examples/kni/Makefile2
-rw-r--r--examples/kni/main.c2
-rw-r--r--examples/kni/meson.build5
-rw-r--r--examples/l2fwd-crypto/Makefile6
-rw-r--r--examples/l2fwd-crypto/main.c565
-rw-r--r--examples/l2fwd-jobstats/main.c2
-rw-r--r--examples/l2fwd-keepalive/main.c2
-rw-r--r--examples/l2fwd/main.c2
-rw-r--r--examples/l3fwd-acl/main.c14
-rw-r--r--examples/l3fwd-power/Makefile6
-rw-r--r--examples/l3fwd-power/main.c88
-rw-r--r--examples/l3fwd-power/main.h20
-rw-r--r--examples/l3fwd-power/meson.build4
-rw-r--r--examples/l3fwd-power/perf_core.c230
-rw-r--r--examples/l3fwd-power/perf_core.h12
-rw-r--r--examples/l3fwd-vf/main.c14
-rw-r--r--examples/l3fwd/l3fwd_em.c1
-rw-r--r--examples/l3fwd/l3fwd_lpm.c1
-rw-r--r--examples/l3fwd/main.c14
-rw-r--r--examples/link_status_interrupt/main.c2
-rw-r--r--examples/load_balancer/init.c14
-rw-r--r--examples/meson.build7
-rw-r--r--examples/multi_process/client_server_mp/mp_server/Makefile2
-rw-r--r--examples/multi_process/l2fwd_fork/Makefile22
-rw-r--r--examples/multi_process/l2fwd_fork/flib.c280
-rw-r--r--examples/multi_process/l2fwd_fork/flib.h120
-rw-r--r--examples/multi_process/l2fwd_fork/main.c1259
-rw-r--r--examples/multi_process/symmetric_mp/main.c14
-rw-r--r--examples/netmap_compat/bridge/Makefile2
-rw-r--r--examples/netmap_compat/bridge/bridge.c1
-rw-r--r--examples/netmap_compat/lib/compat_netmap.c1
-rw-r--r--examples/packet_ordering/main.c7
-rw-r--r--examples/performance-thread/common/lthread_pool.h68
-rw-r--r--examples/performance-thread/common/lthread_queue.h68
-rw-r--r--examples/performance-thread/l3fwd-thread/main.c14
-rw-r--r--examples/ptpclient/ptpclient.c3
-rw-r--r--examples/qos_meter/Makefile1
-rw-r--r--examples/qos_meter/main.c25
-rw-r--r--examples/qos_meter/meson.build1
-rw-r--r--examples/qos_sched/Makefile2
-rw-r--r--examples/qos_sched/init.c2
-rw-r--r--examples/quota_watermark/qw/init.c2
-rw-r--r--examples/rxtx_callbacks/main.c2
-rw-r--r--examples/server_node_efd/server/Makefile2
-rw-r--r--examples/server_node_efd/server/init.c2
-rw-r--r--examples/skeleton/basicfwd.c2
-rw-r--r--examples/tep_termination/Makefile2
-rw-r--r--examples/tep_termination/vxlan_setup.c2
-rw-r--r--examples/vhost/Makefile2
-rw-r--r--examples/vhost/main.c2
-rw-r--r--examples/vhost_crypto/Makefile2
-rw-r--r--examples/vhost_scsi/Makefile2
-rw-r--r--examples/vm_power_manager/Makefile7
-rw-r--r--examples/vm_power_manager/channel_monitor.c23
-rw-r--r--examples/vm_power_manager/guest_cli/Makefile2
-rw-r--r--examples/vm_power_manager/guest_cli/main.c151
-rw-r--r--examples/vm_power_manager/guest_cli/parse.c82
-rw-r--r--examples/vm_power_manager/guest_cli/parse.h19
-rw-r--r--examples/vm_power_manager/guest_cli/vm_power_cli_guest.c113
-rw-r--r--examples/vm_power_manager/guest_cli/vm_power_cli_guest.h6
-rw-r--r--examples/vm_power_manager/main.c169
-rw-r--r--examples/vm_power_manager/oob_monitor.h68
-rw-r--r--examples/vm_power_manager/oob_monitor_nop.c38
-rw-r--r--examples/vm_power_manager/oob_monitor_x86.c258
-rw-r--r--examples/vm_power_manager/parse.c81
-rw-r--r--examples/vm_power_manager/parse.h20
-rw-r--r--examples/vm_power_manager/power_manager.c139
-rw-r--r--examples/vm_power_manager/power_manager.h23
-rw-r--r--examples/vmdq/main.c2
-rw-r--r--examples/vmdq_dcb/main.c15
92 files changed, 3201 insertions, 2703 deletions
diff --git a/examples/bbdev_app/main.c b/examples/bbdev_app/main.c
index 254cc067..045a190b 100644
--- a/examples/bbdev_app/main.c
+++ b/examples/bbdev_app/main.c
@@ -64,11 +64,7 @@ static const struct rte_eth_conf port_conf = {
.mq_mode = ETH_MQ_RX_NONE,
.max_rx_pkt_len = ETHER_MAX_LEN,
.split_hdr_size = 0,
- .header_split = 0, /**< Header Split disabled */
- .hw_ip_checksum = 0, /**< IP checksum offload disabled */
- .hw_vlan_filter = 0, /**< VLAN filtering disabled */
- .jumbo_frame = 0, /**< Jumbo Frame Support disabled */
- .hw_strip_crc = 0, /**< CRC stripped by hardware */
+ .offloads = DEV_RX_OFFLOAD_CRC_STRIP,
},
.txmode = {
.mq_mode = ETH_MQ_TX_NONE,
diff --git a/examples/bond/main.c b/examples/bond/main.c
index 65e0edd2..23d0981a 100644
--- a/examples/bond/main.c
+++ b/examples/bond/main.c
@@ -122,7 +122,6 @@ static struct rte_eth_conf port_conf = {
.mq_mode = ETH_MQ_RX_NONE,
.max_rx_pkt_len = ETHER_MAX_LEN,
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
.offloads = DEV_RX_OFFLOAD_CRC_STRIP,
},
.rx_adv_conf = {
@@ -154,6 +153,18 @@ slave_port_init(uint16_t portid, struct rte_mempool *mbuf_pool)
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
local_port_conf.txmode.offloads |=
DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+ local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
+ dev_info.flow_type_rss_offloads;
+ if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
+ port_conf.rx_adv_conf.rss_conf.rss_hf) {
+ printf("Port %u modified RSS hash function based on hardware support,"
+ "requested:%#"PRIx64" configured:%#"PRIx64"\n",
+ portid,
+ port_conf.rx_adv_conf.rss_conf.rss_hf,
+ local_port_conf.rx_adv_conf.rss_conf.rss_hf);
+ }
+
retval = rte_eth_dev_configure(portid, 1, 1, &local_port_conf);
if (retval != 0)
rte_exit(EXIT_FAILURE, "port %u: configuration failed (res=%d)\n",
@@ -177,7 +188,6 @@ slave_port_init(uint16_t portid, struct rte_mempool *mbuf_pool)
/* TX setup */
txq_conf = dev_info.default_txconf;
- txq_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
txq_conf.offloads = local_port_conf.txmode.offloads;
retval = rte_eth_tx_queue_setup(portid, 0, nb_txd,
rte_eth_dev_socket_id(portid), &txq_conf);
@@ -246,7 +256,6 @@ bond_port_init(struct rte_mempool *mbuf_pool)
/* TX setup */
txq_conf = dev_info.default_txconf;
- txq_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
txq_conf.offloads = local_port_conf.txmode.offloads;
retval = rte_eth_tx_queue_setup(BOND_PORT, 0, nb_txd,
rte_eth_dev_socket_id(BOND_PORT), &txq_conf);
diff --git a/examples/distributor/main.c b/examples/distributor/main.c
index 2c593648..03a05e3d 100644
--- a/examples/distributor/main.c
+++ b/examples/distributor/main.c
@@ -80,7 +80,6 @@ static const struct rte_eth_conf port_conf_default = {
.rxmode = {
.mq_mode = ETH_MQ_RX_RSS,
.max_rx_pkt_len = ETHER_MAX_LEN,
- .ignore_offload_bitfield = 1,
},
.txmode = {
.mq_mode = ETH_MQ_TX_NONE,
@@ -124,6 +123,17 @@ port_init(uint16_t port, struct rte_mempool *mbuf_pool)
port_conf.txmode.offloads |=
DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+ port_conf.rx_adv_conf.rss_conf.rss_hf &=
+ dev_info.flow_type_rss_offloads;
+ if (port_conf.rx_adv_conf.rss_conf.rss_hf !=
+ port_conf_default.rx_adv_conf.rss_conf.rss_hf) {
+ printf("Port %u modified RSS hash function based on hardware support,"
+ "requested:%#"PRIx64" configured:%#"PRIx64"\n",
+ port,
+ port_conf_default.rx_adv_conf.rss_conf.rss_hf,
+ port_conf.rx_adv_conf.rss_conf.rss_hf);
+ }
+
retval = rte_eth_dev_configure(port, rxRings, txRings, &port_conf);
if (retval != 0)
return retval;
@@ -141,7 +151,6 @@ port_init(uint16_t port, struct rte_mempool *mbuf_pool)
}
txconf = dev_info.default_txconf;
- txconf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
txconf.offloads = port_conf.txmode.offloads;
for (q = 0; q < txRings; q++) {
retval = rte_eth_tx_queue_setup(port, q, nb_txd,
diff --git a/examples/ethtool/Makefile b/examples/ethtool/Makefile
index 2b40b4b6..3d9d4f06 100644
--- a/examples/ethtool/Makefile
+++ b/examples/ethtool/Makefile
@@ -10,7 +10,7 @@ RTE_TARGET ?= x86_64-native-linuxapp-gcc
include $(RTE_SDK)/mk/rte.vars.mk
-ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
$(info This application can only operate in a linuxapp environment, \
please change the definition of the RTE_TARGET environment variable)
else
diff --git a/examples/ethtool/ethtool-app/main.c b/examples/ethtool/ethtool-app/main.c
index c1815bb9..dc93adfe 100644
--- a/examples/ethtool/ethtool-app/main.c
+++ b/examples/ethtool/ethtool-app/main.c
@@ -99,7 +99,6 @@ static void setup_ports(struct app_config *app_cfg, int cnt_ports)
memset(&cfg_port, 0, sizeof(cfg_port));
cfg_port.txmode.mq_mode = ETH_MQ_TX_NONE;
- cfg_port.rxmode.ignore_offload_bitfield = 1;
for (idx_port = 0; idx_port < cnt_ports; idx_port++) {
struct app_port *ptr_port = &app_cfg->ports[idx_port];
@@ -142,7 +141,6 @@ static void setup_ports(struct app_config *app_cfg, int cnt_ports)
"rte_eth_rx_queue_setup failed"
);
txconf = dev_info.default_txconf;
- txconf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
if (rte_eth_tx_queue_setup(
idx_port, 0, nb_txd,
rte_eth_dev_socket_id(idx_port), &txconf) < 0)
diff --git a/examples/ethtool/lib/Makefile b/examples/ethtool/lib/Makefile
index 2576910f..6eaa640b 100644
--- a/examples/ethtool/lib/Makefile
+++ b/examples/ethtool/lib/Makefile
@@ -10,7 +10,7 @@ RTE_TARGET ?= x86_64-native-linuxapp-gcc
include $(RTE_SDK)/mk/rte.vars.mk
-ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
$(error This application can only operate in a linuxapp environment, \
please change the definition of the RTE_TARGET environment variable)
endif
diff --git a/examples/eventdev_pipeline/main.c b/examples/eventdev_pipeline/main.c
index b698e4ca..700bc696 100644
--- a/examples/eventdev_pipeline/main.c
+++ b/examples/eventdev_pipeline/main.c
@@ -267,7 +267,6 @@ port_init(uint8_t port, struct rte_mempool *mbuf_pool)
.rxmode = {
.mq_mode = ETH_MQ_RX_RSS,
.max_rx_pkt_len = ETHER_MAX_LEN,
- .ignore_offload_bitfield = 1,
},
.rx_adv_conf = {
.rss_conf = {
@@ -293,6 +292,17 @@ port_init(uint8_t port, struct rte_mempool *mbuf_pool)
port_conf.txmode.offloads |=
DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+ port_conf.rx_adv_conf.rss_conf.rss_hf &=
+ dev_info.flow_type_rss_offloads;
+ if (port_conf.rx_adv_conf.rss_conf.rss_hf !=
+ port_conf_default.rx_adv_conf.rss_conf.rss_hf) {
+ printf("Port %u modified RSS hash function based on hardware support,"
+ "requested:%#"PRIx64" configured:%#"PRIx64"\n",
+ port,
+ port_conf_default.rx_adv_conf.rss_conf.rss_hf,
+ port_conf.rx_adv_conf.rss_conf.rss_hf);
+ }
+
/* Configure the Ethernet device. */
retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
if (retval != 0)
@@ -307,7 +317,6 @@ port_init(uint8_t port, struct rte_mempool *mbuf_pool)
}
txconf = dev_info.default_txconf;
- txconf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
txconf.offloads = port_conf_default.txmode.offloads;
/* Allocate and set up 1 TX queue per Ethernet port. */
for (q = 0; q < tx_rings; q++) {
diff --git a/examples/exception_path/main.c b/examples/exception_path/main.c
index 2b381a5d..440422bc 100644
--- a/examples/exception_path/main.c
+++ b/examples/exception_path/main.c
@@ -88,7 +88,6 @@
/* Options for configuring ethernet port */
static struct rte_eth_conf port_conf = {
.rxmode = {
- .ignore_offload_bitfield = 1,
.offloads = DEV_RX_OFFLOAD_CRC_STRIP,
},
.txmode = {
@@ -132,6 +131,9 @@ print_stats(void)
" Lcore Port RX TX Dropped on TX\n"
"------- ------ ------------ ------------ ---------------\n");
RTE_LCORE_FOREACH(i) {
+ /* limit ourselves to application supported cores only */
+ if (i >= APP_MAX_LCORE)
+ break;
printf("%6u %7u %13"PRIu64" %13"PRIu64" %16"PRIu64"\n",
i, (unsigned)port_ids[i],
lcore_stats[i].rx, lcore_stats[i].tx,
@@ -457,7 +459,6 @@ init_port(uint16_t port)
port, ret);
txq_conf = dev_info.default_txconf;
- txq_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
txq_conf.offloads = local_port_conf.txmode.offloads;
ret = rte_eth_tx_queue_setup(port, 0, nb_txd,
rte_eth_dev_socket_id(port),
diff --git a/examples/flow_classify/flow_classify.c b/examples/flow_classify/flow_classify.c
index 6412fe44..19961292 100644
--- a/examples/flow_classify/flow_classify.c
+++ b/examples/flow_classify/flow_classify.c
@@ -62,7 +62,6 @@ const char cb_port_delim[] = ":";
static const struct rte_eth_conf port_conf_default = {
.rxmode = {
.max_rx_pkt_len = ETHER_MAX_LEN,
- .ignore_offload_bitfield = 1,
},
};
@@ -222,7 +221,6 @@ port_init(uint8_t port, struct rte_mempool *mbuf_pool)
}
txconf = dev_info.default_txconf;
- txconf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
txconf.offloads = port_conf.txmode.offloads;
/* Allocate and set up 1 TX queue per Ethernet port. */
for (q = 0; q < tx_rings; q++) {
diff --git a/examples/flow_filtering/main.c b/examples/flow_filtering/main.c
index e0ee5167..ce91e8a6 100644
--- a/examples/flow_filtering/main.c
+++ b/examples/flow_filtering/main.c
@@ -121,7 +121,6 @@ init_port(void)
struct rte_eth_conf port_conf = {
.rxmode = {
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
.offloads = DEV_RX_OFFLOAD_CRC_STRIP,
},
.txmode = {
@@ -133,6 +132,22 @@ init_port(void)
DEV_TX_OFFLOAD_SCTP_CKSUM |
DEV_TX_OFFLOAD_TCP_TSO,
},
+ /*
+ * Initialize fdir_conf of rte_eth_conf.
+ * Fdir is used in flow filtering for I40e,
+ * so rte_flow rules involve some fdir
+ * configurations. In long term it's better
+ * that drivers don't require any fdir
+ * configuration for rte_flow, but we need to
+ * get this workaround so that sample app can
+ * run on I40e.
+ */
+ .fdir_conf = {
+ .mode = RTE_FDIR_MODE_PERFECT,
+ .pballoc = RTE_FDIR_PBALLOC_64K,
+ .status = RTE_FDIR_REPORT_STATUS,
+ .drop_queue = 127,
+ },
};
struct rte_eth_txconf txq_conf;
struct rte_eth_rxconf rxq_conf;
diff --git a/examples/ip_fragmentation/main.c b/examples/ip_fragmentation/main.c
index 8952ea45..5306d767 100644
--- a/examples/ip_fragmentation/main.c
+++ b/examples/ip_fragmentation/main.c
@@ -140,7 +140,6 @@ static struct rte_eth_conf port_conf = {
.rxmode = {
.max_rx_pkt_len = JUMBO_FRAME_MAX_SIZE,
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
.offloads = (DEV_RX_OFFLOAD_CHECKSUM |
DEV_RX_OFFLOAD_JUMBO_FRAME |
DEV_RX_OFFLOAD_CRC_STRIP),
@@ -973,7 +972,6 @@ main(int argc, char **argv)
fflush(stdout);
txconf = &dev_info.default_txconf;
- txconf->txq_flags = ETH_TXQ_FLAGS_IGNORE;
txconf->offloads = local_port_conf.txmode.offloads;
ret = rte_eth_tx_queue_setup(portid, queueid, nb_txd,
socket, txconf);
diff --git a/examples/ip_pipeline/Makefile b/examples/ip_pipeline/Makefile
index 11d2b35d..3fb98ce3 100644
--- a/examples/ip_pipeline/Makefile
+++ b/examples/ip_pipeline/Makefile
@@ -67,7 +67,7 @@ RTE_TARGET ?= x86_64-native-linuxapp-gcc
include $(RTE_SDK)/mk/rte.vars.mk
-ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
$(info This application can only operate in a linuxapp environment, \
please change the definition of the RTE_TARGET environment variable)
all:
diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c
index c9587f56..102a1d6b 100644
--- a/examples/ip_pipeline/cli.c
+++ b/examples/ip_pipeline/cli.c
@@ -9,6 +9,7 @@
#include <rte_common.h>
#include <rte_cycles.h>
+#include <rte_ethdev.h>
#include "cli.h"
#include "kni.h"
@@ -48,13 +49,13 @@ is_comment(char *in)
return 0;
}
-/**
- * mempool <mempool_name>
- * buffer <buffer_size>
- * pool <pool_size>
- * cache <cache_size>
- * cpu <cpu_id>
- */
+static const char cmd_mempool_help[] =
+"mempool <mempool_name>\n"
+" buffer <buffer_size>\n"
+" pool <pool_size>\n"
+" cache <cache_size>\n"
+" cpu <cpu_id>\n";
+
static void
cmd_mempool(char **tokens,
uint32_t n_tokens,
@@ -119,14 +120,14 @@ cmd_mempool(char **tokens,
}
}
-/**
- * link <link_name>
- * dev <device_name> | port <port_id>
- * rxq <n_queues> <queue_size> <mempool_name>
- * txq <n_queues> <queue_size>
- * promiscuous on | off
- * [rss <qid_0> ... <qid_n>]
- */
+static const char cmd_link_help[] =
+"link <link_name>\n"
+" dev <device_name> | port <port_id>\n"
+" rxq <n_queues> <queue_size> <mempool_name>\n"
+" txq <n_queues> <queue_size>\n"
+" promiscuous on | off\n"
+" [rss <qid_0> ... <qid_n>]\n";
+
static void
cmd_link(char **tokens,
uint32_t n_tokens,
@@ -237,12 +238,97 @@ cmd_link(char **tokens,
}
}
-/**
- * swq <swq_name>
- * size <size>
- * cpu <cpu_id>
+/* Print the link stats and info */
+static void
+print_link_info(struct link *link, char *out, size_t out_size)
+{
+ struct rte_eth_stats stats;
+ struct ether_addr mac_addr;
+ struct rte_eth_link eth_link;
+ uint16_t mtu;
+
+ memset(&stats, 0, sizeof(stats));
+ rte_eth_stats_get(link->port_id, &stats);
+
+ rte_eth_macaddr_get(link->port_id, &mac_addr);
+ rte_eth_link_get(link->port_id, &eth_link);
+ rte_eth_dev_get_mtu(link->port_id, &mtu);
+
+ snprintf(out, out_size,
+ "\n"
+ "%s: flags=<%s> mtu %u\n"
+ "\tether %02X:%02X:%02X:%02X:%02X:%02X rxqueues %u txqueues %u\n"
+ "\tport# %u speed %u Mbps\n"
+ "\tRX packets %" PRIu64" bytes %" PRIu64"\n"
+ "\tRX errors %" PRIu64" missed %" PRIu64" no-mbuf %" PRIu64"\n"
+ "\tTX packets %" PRIu64" bytes %" PRIu64"\n"
+ "\tTX errors %" PRIu64"\n",
+ link->name,
+ eth_link.link_status == 0 ? "DOWN" : "UP",
+ mtu,
+ mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
+ mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
+ mac_addr.addr_bytes[4], mac_addr.addr_bytes[5],
+ link->n_rxq,
+ link->n_txq,
+ link->port_id,
+ eth_link.link_speed,
+ stats.ipackets,
+ stats.ibytes,
+ stats.ierrors,
+ stats.imissed,
+ stats.rx_nombuf,
+ stats.opackets,
+ stats.obytes,
+ stats.oerrors);
+}
+
+/*
+ * link show [<link_name>]
*/
static void
+cmd_link_show(char **tokens, uint32_t n_tokens, char *out, size_t out_size)
+{
+ struct link *link;
+ char *link_name;
+
+ if (n_tokens != 2 && n_tokens != 3) {
+ snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
+ return;
+ }
+
+ if (n_tokens == 2) {
+ link = link_next(NULL);
+
+ while (link != NULL) {
+ out_size = out_size - strlen(out);
+ out = &out[strlen(out)];
+
+ print_link_info(link, out, out_size);
+ link = link_next(link);
+ }
+ } else {
+ out_size = out_size - strlen(out);
+ out = &out[strlen(out)];
+
+ link_name = tokens[2];
+ link = link_find(link_name);
+
+ if (link == NULL) {
+ snprintf(out, out_size, MSG_ARG_INVALID,
+ "Link does not exist");
+ return;
+ }
+ print_link_info(link, out, out_size);
+ }
+}
+
+static const char cmd_swq_help[] =
+"swq <swq_name>\n"
+" size <size>\n"
+" cpu <cpu_id>\n";
+
+static void
cmd_swq(char **tokens,
uint32_t n_tokens,
char *out,
@@ -286,12 +372,12 @@ cmd_swq(char **tokens,
}
}
-/**
- * tmgr subport profile
- * <tb_rate> <tb_size>
- * <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate>
- * <tc_period>
- */
+static const char cmd_tmgr_subport_profile_help[] =
+"tmgr subport profile\n"
+" <tb_rate> <tb_size>\n"
+" <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate>\n"
+" <tc_period>\n";
+
static void
cmd_tmgr_subport_profile(char **tokens,
uint32_t n_tokens,
@@ -334,14 +420,14 @@ cmd_tmgr_subport_profile(char **tokens,
}
}
-/**
- * tmgr pipe profile
- * <tb_rate> <tb_size>
- * <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate>
- * <tc_period>
- * <tc_ov_weight>
- * <wrr_weight0..15>
- */
+static const char cmd_tmgr_pipe_profile_help[] =
+"tmgr pipe profile\n"
+" <tb_rate> <tb_size>\n"
+" <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate>\n"
+" <tc_period>\n"
+" <tc_ov_weight>\n"
+" <wrr_weight0..15>\n";
+
static void
cmd_tmgr_pipe_profile(char **tokens,
uint32_t n_tokens,
@@ -397,16 +483,16 @@ cmd_tmgr_pipe_profile(char **tokens,
}
}
-/**
- * tmgr <tmgr_name>
- * rate <rate>
- * spp <n_subports_per_port>
- * pps <n_pipes_per_subport>
- * qsize <qsize_tc0> <qsize_tc1> <qsize_tc2> <qsize_tc3>
- * fo <frame_overhead>
- * mtu <mtu>
- * cpu <cpu_id>
- */
+static const char cmd_tmgr_help[] =
+"tmgr <tmgr_name>\n"
+" rate <rate>\n"
+" spp <n_subports_per_port>\n"
+" pps <n_pipes_per_subport>\n"
+" qsize <qsize_tc0> <qsize_tc1> <qsize_tc2> <qsize_tc3>\n"
+" fo <frame_overhead>\n"
+" mtu <mtu>\n"
+" cpu <cpu_id>\n";
+
static void
cmd_tmgr(char **tokens,
uint32_t n_tokens,
@@ -503,10 +589,10 @@ cmd_tmgr(char **tokens,
}
}
-/**
- * tmgr <tmgr_name> subport <subport_id>
- * profile <subport_profile_id>
- */
+static const char cmd_tmgr_subport_help[] =
+"tmgr <tmgr_name> subport <subport_id>\n"
+" profile <subport_profile_id>\n";
+
static void
cmd_tmgr_subport(char **tokens,
uint32_t n_tokens,
@@ -541,11 +627,12 @@ cmd_tmgr_subport(char **tokens,
}
}
-/**
- * tmgr <tmgr_name> subport <subport_id> pipe
- * from <pipe_id_first> to <pipe_id_last>
- * profile <pipe_profile_id>
- */
+
+static const char cmd_tmgr_subport_pipe_help[] =
+"tmgr <tmgr_name> subport <subport_id> pipe\n"
+" from <pipe_id_first> to <pipe_id_last>\n"
+" profile <pipe_profile_id>\n";
+
static void
cmd_tmgr_subport_pipe(char **tokens,
uint32_t n_tokens,
@@ -611,9 +698,10 @@ cmd_tmgr_subport_pipe(char **tokens,
}
}
-/**
- * tap <tap_name>
- */
+
+static const char cmd_tap_help[] =
+"tap <tap_name>\n";
+
static void
cmd_tap(char **tokens,
uint32_t n_tokens,
@@ -637,12 +725,12 @@ cmd_tap(char **tokens,
}
}
-/**
- * kni <kni_name>
- * link <link_name>
- * mempool <mempool_name>
- * [thread <thread_id>]
- */
+static const char cmd_kni_help[] =
+"kni <kni_name>\n"
+" link <link_name>\n"
+" mempool <mempool_name>\n"
+" [thread <thread_id>]\n";
+
static void
cmd_kni(char **tokens,
uint32_t n_tokens,
@@ -697,11 +785,12 @@ cmd_kni(char **tokens,
}
}
-/**
- * port in action profile <profile_name>
- * [filter match | mismatch offset <key_offset> mask <key_mask> key <key_value> port <port_id>]
- * [balance offset <key_offset> mask <key_mask> port <port_id0> ... <port_id15>]
- */
+
+static const char cmd_port_in_action_profile_help[] =
+"port in action profile <profile_name>\n"
+" [filter match | mismatch offset <key_offset> mask <key_mask> key <key_value> port <port_id>]\n"
+" [balance offset <key_offset> mask <key_mask> port <port_id0> ... <port_id15>]\n";
+
static void
cmd_port_in_action_profile(char **tokens,
uint32_t n_tokens,
@@ -861,24 +950,25 @@ cmd_port_in_action_profile(char **tokens,
}
}
-/**
- * table action profile <profile_name>
- * ipv4 | ipv6
- * offset <ip_offset>
- * fwd
- * [balance offset <key_offset> mask <key_mask> outoffset <out_offset>]
- * [meter srtcm | trtcm
- * tc <n_tc>
- * stats none | pkts | bytes | both]
- * [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]
- * [encap ether | vlan | qinq | mpls | pppoe]
- * [nat src | dst
- * proto udp | tcp]
- * [ttl drop | fwd
- * stats none | pkts]
- * [stats pkts | bytes | both]
- * [time]
- */
+
+static const char cmd_table_action_profile_help[] =
+"table action profile <profile_name>\n"
+" ipv4 | ipv6\n"
+" offset <ip_offset>\n"
+" fwd\n"
+" [balance offset <key_offset> mask <key_mask> outoffset <out_offset>]\n"
+" [meter srtcm | trtcm\n"
+" tc <n_tc>\n"
+" stats none | pkts | bytes | both]\n"
+" [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]\n"
+" [encap ether | vlan | qinq | mpls | pppoe]\n"
+" [nat src | dst\n"
+" proto udp | tcp]\n"
+" [ttl drop | fwd\n"
+" stats none | pkts]\n"
+" [stats pkts | bytes | both]\n"
+" [time]\n";
+
static void
cmd_table_action_profile(char **tokens,
uint32_t n_tokens,
@@ -1207,12 +1297,12 @@ cmd_table_action_profile(char **tokens,
}
}
-/**
- * pipeline <pipeline_name>
- * period <timer_period_ms>
- * offset_port_id <offset_port_id>
- * cpu <cpu_id>
- */
+static const char cmd_pipeline_help[] =
+"pipeline <pipeline_name>\n"
+" period <timer_period_ms>\n"
+" offset_port_id <offset_port_id>\n"
+" cpu <cpu_id>\n";
+
static void
cmd_pipeline(char **tokens,
uint32_t n_tokens,
@@ -1267,18 +1357,18 @@ cmd_pipeline(char **tokens,
}
}
-/**
- * pipeline <pipeline_name> port in
- * bsz <burst_size>
- * link <link_name> rxq <queue_id>
- * | swq <swq_name>
- * | tmgr <tmgr_name>
- * | tap <tap_name> mempool <mempool_name> mtu <mtu>
- * | kni <kni_name>
- * | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>
- * [action <port_in_action_profile_name>]
- * [disabled]
- */
+static const char cmd_pipeline_port_in_help[] =
+"pipeline <pipeline_name> port in\n"
+" bsz <burst_size>\n"
+" link <link_name> rxq <queue_id>\n"
+" | swq <swq_name>\n"
+" | tmgr <tmgr_name>\n"
+" | tap <tap_name> mempool <mempool_name> mtu <mtu>\n"
+" | kni <kni_name>\n"
+" | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>\n"
+" [action <port_in_action_profile_name>]\n"
+" [disabled]\n";
+
static void
cmd_pipeline_port_in(char **tokens,
uint32_t n_tokens,
@@ -1486,16 +1576,16 @@ cmd_pipeline_port_in(char **tokens,
}
}
-/**
- * pipeline <pipeline_name> port out
- * bsz <burst_size>
- * link <link_name> txq <txq_id>
- * | swq <swq_name>
- * | tmgr <tmgr_name>
- * | tap <tap_name>
- * | kni <kni_name>
- * | sink [file <file_name> pkts <max_n_pkts>]
- */
+static const char cmd_pipeline_port_out_help[] =
+"pipeline <pipeline_name> port out\n"
+" bsz <burst_size>\n"
+" link <link_name> txq <txq_id>\n"
+" | swq <swq_name>\n"
+" | tmgr <tmgr_name>\n"
+" | tap <tap_name>\n"
+" | kni <kni_name>\n"
+" | sink [file <file_name> pkts <max_n_pkts>]\n";
+
static void
cmd_pipeline_port_out(char **tokens,
uint32_t n_tokens,
@@ -1640,30 +1730,30 @@ cmd_pipeline_port_out(char **tokens,
}
}
-/**
- * pipeline <pipeline_name> table
- * match
- * acl
- * ipv4 | ipv6
- * offset <ip_header_offset>
- * size <n_rules>
- * | array
- * offset <key_offset>
- * size <n_keys>
- * | hash
- * ext | lru
- * key <key_size>
- * mask <key_mask>
- * offset <key_offset>
- * buckets <n_buckets>
- * size <n_keys>
- * | lpm
- * ipv4 | ipv6
- * offset <ip_header_offset>
- * size <n_rules>
- * | stub
- * [action <table_action_profile_name>]
- */
+static const char cmd_pipeline_table_help[] =
+"pipeline <pipeline_name> table\n"
+" match\n"
+" acl\n"
+" ipv4 | ipv6\n"
+" offset <ip_header_offset>\n"
+" size <n_rules>\n"
+" | array\n"
+" offset <key_offset>\n"
+" size <n_keys>\n"
+" | hash\n"
+" ext | lru\n"
+" key <key_size>\n"
+" mask <key_mask>\n"
+" offset <key_offset>\n"
+" buckets <n_buckets>\n"
+" size <n_keys>\n"
+" | lpm\n"
+" ipv4 | ipv6\n"
+" offset <ip_header_offset>\n"
+" size <n_rules>\n"
+" | stub\n"
+" [action <table_action_profile_name>]\n";
+
static void
cmd_pipeline_table(char **tokens,
uint32_t n_tokens,
@@ -1925,9 +2015,9 @@ cmd_pipeline_table(char **tokens,
}
}
-/**
- * pipeline <pipeline_name> port in <port_id> table <table_id>
- */
+static const char cmd_pipeline_port_in_table_help[] =
+"pipeline <pipeline_name> port in <port_id> table <table_id>\n";
+
static void
cmd_pipeline_port_in_table(char **tokens,
uint32_t n_tokens,
@@ -1979,9 +2069,9 @@ cmd_pipeline_port_in_table(char **tokens,
}
}
-/**
- * pipeline <pipeline_name> port in <port_id> stats read [clear]
- */
+
+static const char cmd_pipeline_port_in_stats_help[] =
+"pipeline <pipeline_name> port in <port_id> stats read [clear]\n";
#define MSG_PIPELINE_PORT_IN_STATS \
"Pkts in: %" PRIu64 "\n" \
@@ -2056,9 +2146,10 @@ cmd_pipeline_port_in_stats(char **tokens,
stats.stats.n_pkts_drop);
}
-/**
- * pipeline <pipeline_name> port in <port_id> enable
- */
+
+static const char cmd_pipeline_port_in_enable_help[] =
+"pipeline <pipeline_name> port in <port_id> enable\n";
+
static void
cmd_pipeline_port_in_enable(char **tokens,
uint32_t n_tokens,
@@ -2103,9 +2194,10 @@ cmd_pipeline_port_in_enable(char **tokens,
}
}
-/**
- * pipeline <pipeline_name> port in <port_id> disable
- */
+
+static const char cmd_pipeline_port_in_disable_help[] =
+"pipeline <pipeline_name> port in <port_id> disable\n";
+
static void
cmd_pipeline_port_in_disable(char **tokens,
uint32_t n_tokens,
@@ -2150,9 +2242,10 @@ cmd_pipeline_port_in_disable(char **tokens,
}
}
-/**
- * pipeline <pipeline_name> port out <port_id> stats read [clear]
- */
+
+static const char cmd_pipeline_port_out_stats_help[] =
+"pipeline <pipeline_name> port out <port_id> stats read [clear]\n";
+
#define MSG_PIPELINE_PORT_OUT_STATS \
"Pkts in: %" PRIu64 "\n" \
"Pkts dropped by AH: %" PRIu64 "\n" \
@@ -2226,9 +2319,10 @@ cmd_pipeline_port_out_stats(char **tokens,
stats.stats.n_pkts_drop);
}
-/**
- * pipeline <pipeline_name> table <table_id> stats read [clear]
- */
+
+static const char cmd_pipeline_table_stats_help[] =
+"pipeline <pipeline_name> table <table_id> stats read [clear]\n";
+
#define MSG_PIPELINE_TABLE_STATS \
"Pkts in: %" PRIu64 "\n" \
"Pkts in with lookup miss: %" PRIu64 "\n" \
@@ -3406,11 +3500,12 @@ parse_table_action(char **tokens,
return n_tokens0 - n_tokens;
}
-/**
- * pipeline <pipeline_name> table <table_id> rule add
- * match <match>
- * action <table_action>
- */
+
+static const char cmd_pipeline_table_rule_add_help[] =
+"pipeline <pipeline_name> table <table_id> rule add\n"
+" match <match>\n"
+" action <table_action>\n";
+
static void
cmd_pipeline_table_rule_add(char **tokens,
uint32_t n_tokens,
@@ -3486,17 +3581,18 @@ cmd_pipeline_table_rule_add(char **tokens,
}
}
-/**
- * pipeline <pipeline_name> table <table_id> rule add
- * match
- * default
- * action
- * fwd
- * drop
- * | port <port_id>
- * | meta
- * | table <table_id>
- */
+
+static const char cmd_pipeline_table_rule_add_default_help[] =
+"pipeline <pipeline_name> table <table_id> rule add\n"
+" match\n"
+" default\n"
+" action\n"
+" fwd\n"
+" drop\n"
+" | port <port_id>\n"
+" | meta\n"
+" | table <table_id>\n";
+
static void
cmd_pipeline_table_rule_add_default(char **tokens,
uint32_t n_tokens,
@@ -3618,12 +3714,13 @@ cmd_pipeline_table_rule_add_default(char **tokens,
}
}
-/**
- * pipeline <pipeline_name> table <table_id> rule add bulk <file_name> <n_rules>
- *
- * File <file_name>:
- * - line format: match <match> action <action>
- */
+
+static const char cmd_pipeline_table_rule_add_bulk_help[] =
+"pipeline <pipeline_name> table <table_id> rule add bulk <file_name> <n_rules>\n"
+"\n"
+" File <file_name>:\n"
+" - line format: match <match> action <action>\n";
+
static int
cli_rule_file_process(const char *file_name,
size_t line_len_max,
@@ -3745,10 +3842,11 @@ cmd_pipeline_table_rule_add_bulk(char **tokens,
free(match);
}
-/**
- * pipeline <pipeline_name> table <table_id> rule delete
- * match <match>
- */
+
+static const char cmd_pipeline_table_rule_delete_help[] =
+"pipeline <pipeline_name> table <table_id> rule delete\n"
+" match <match>\n";
+
static void
cmd_pipeline_table_rule_delete(char **tokens,
uint32_t n_tokens,
@@ -3813,11 +3911,12 @@ cmd_pipeline_table_rule_delete(char **tokens,
}
}
-/**
- * pipeline <pipeline_name> table <table_id> rule delete
- * match
- * default
- */
+
+static const char cmd_pipeline_table_rule_delete_default_help[] =
+"pipeline <pipeline_name> table <table_id> rule delete\n"
+" match\n"
+" default\n";
+
static void
cmd_pipeline_table_rule_delete_default(char **tokens,
uint32_t n_tokens,
@@ -3873,9 +3972,10 @@ cmd_pipeline_table_rule_delete_default(char **tokens,
}
}
-/**
- * pipeline <pipeline_name> table <table_id> rule read stats [clear]
- */
+
+static const char cmd_pipeline_table_rule_stats_read_help[] =
+"pipeline <pipeline_name> table <table_id> rule read stats [clear]\n";
+
static void
cmd_pipeline_table_rule_stats_read(char **tokens,
uint32_t n_tokens __rte_unused,
@@ -3885,11 +3985,12 @@ cmd_pipeline_table_rule_stats_read(char **tokens,
snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
}
-/**
- * pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>
- * add srtcm cir <cir> cbs <cbs> ebs <ebs>
- * | trtcm cir <cir> pir <pir> cbs <cbs> pbs <pbs>
- */
+
+static const char cmd_pipeline_table_meter_profile_add_help[] =
+"pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>\n"
+" add srtcm cir <cir> cbs <cbs> ebs <ebs>\n"
+" | trtcm cir <cir> pir <pir> cbs <cbs> pbs <pbs>\n";
+
static void
cmd_pipeline_table_meter_profile_add(char **tokens,
uint32_t n_tokens,
@@ -4037,10 +4138,11 @@ cmd_pipeline_table_meter_profile_add(char **tokens,
}
}
-/**
- * pipeline <pipeline_name> table <table_id>
- * meter profile <meter_profile_id> delete
- */
+
+static const char cmd_pipeline_table_meter_profile_delete_help[] =
+"pipeline <pipeline_name> table <table_id>\n"
+" meter profile <meter_profile_id> delete\n";
+
static void
cmd_pipeline_table_meter_profile_delete(char **tokens,
uint32_t n_tokens,
@@ -4097,9 +4199,10 @@ cmd_pipeline_table_meter_profile_delete(char **tokens,
}
}
-/**
- * pipeline <pipeline_name> table <table_id> rule read meter [clear]
- */
+
+static const char cmd_pipeline_table_rule_meter_read_help[] =
+"pipeline <pipeline_name> table <table_id> rule read meter [clear]\n";
+
static void
cmd_pipeline_table_rule_meter_read(char **tokens,
uint32_t n_tokens __rte_unused,
@@ -4109,13 +4212,14 @@ cmd_pipeline_table_rule_meter_read(char **tokens,
snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
}
-/**
- * pipeline <pipeline_name> table <table_id> dscp <file_name>
- *
- * File <file_name>:
- * - exactly 64 lines
- * - line format: <tc_id> <tc_queue_id> <color>, with <color> as: g | y | r
- */
+
+static const char cmd_pipeline_table_dscp_help[] =
+"pipeline <pipeline_name> table <table_id> dscp <file_name>\n"
+"\n"
+" File <file_name>:\n"
+" - exactly 64 lines\n"
+" - line format: <tc_id> <tc_queue_id> <color>, with <color> as: g | y | r\n";
+
static int
load_dscp_table(struct rte_table_action_dscp_table *dscp_table,
const char *file_name,
@@ -4258,9 +4362,10 @@ cmd_pipeline_table_dscp(char **tokens,
}
}
-/**
- * pipeline <pipeline_name> table <table_id> rule read ttl [clear]
- */
+
+static const char cmd_pipeline_table_rule_ttl_read_help[] =
+"pipeline <pipeline_name> table <table_id> rule read ttl [clear]\n";
+
static void
cmd_pipeline_table_rule_ttl_read(char **tokens,
uint32_t n_tokens __rte_unused,
@@ -4270,9 +4375,10 @@ cmd_pipeline_table_rule_ttl_read(char **tokens,
snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
}
-/**
- * thread <thread_id> pipeline <pipeline_name> enable
- */
+
+static const char cmd_thread_pipeline_enable_help[] =
+"thread <thread_id> pipeline <pipeline_name> enable\n";
+
static void
cmd_thread_pipeline_enable(char **tokens,
uint32_t n_tokens,
@@ -4312,9 +4418,10 @@ cmd_thread_pipeline_enable(char **tokens,
}
}
-/**
- * thread <thread_id> pipeline <pipeline_name> disable
- */
+
+static const char cmd_thread_pipeline_disable_help[] =
+"thread <thread_id> pipeline <pipeline_name> disable\n";
+
static void
cmd_thread_pipeline_disable(char **tokens,
uint32_t n_tokens,
@@ -4355,6 +4462,316 @@ cmd_thread_pipeline_disable(char **tokens,
}
}
+static void
+cmd_help(char **tokens, uint32_t n_tokens, char *out, size_t out_size)
+{
+ tokens++;
+ n_tokens--;
+
+ if (n_tokens == 0) {
+ snprintf(out, out_size,
+ "Type 'help <command>' for details on each command.\n\n"
+ "List of commands:\n"
+ "\tmempool\n"
+ "\tlink\n"
+ "\tswq\n"
+ "\ttmgr subport profile\n"
+ "\ttmgr pipe profile\n"
+ "\ttmgr\n"
+ "\ttmgr subport\n"
+ "\ttmgr subport pipe\n"
+ "\ttap\n"
+ "\tkni\n"
+ "\tport in action profile\n"
+ "\ttable action profile\n"
+ "\tpipeline\n"
+ "\tpipeline port in\n"
+ "\tpipeline port out\n"
+ "\tpipeline table\n"
+ "\tpipeline port in table\n"
+ "\tpipeline port in stats\n"
+ "\tpipeline port in enable\n"
+ "\tpipeline port in disable\n"
+ "\tpipeline port out stats\n"
+ "\tpipeline table stats\n"
+ "\tpipeline table rule add\n"
+ "\tpipeline table rule add default\n"
+ "\tpipeline table rule add bulk\n"
+ "\tpipeline table rule delete\n"
+ "\tpipeline table rule delete default\n"
+ "\tpipeline table rule stats read\n"
+ "\tpipeline table meter profile add\n"
+ "\tpipeline table meter profile delete\n"
+ "\tpipeline table rule meter read\n"
+ "\tpipeline table dscp\n"
+ "\tpipeline table rule ttl read\n"
+ "\tthread pipeline enable\n"
+ "\tthread pipeline disable\n\n");
+ return;
+ }
+
+ if (strcmp(tokens[0], "mempool") == 0) {
+ snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
+ return;
+ }
+
+ if (strcmp(tokens[0], "link") == 0) {
+ snprintf(out, out_size, "\n%s\n", cmd_link_help);
+ return;
+ }
+
+ if (strcmp(tokens[0], "swq") == 0) {
+ snprintf(out, out_size, "\n%s\n", cmd_swq_help);
+ return;
+ }
+
+ if (strcmp(tokens[0], "tmgr") == 0) {
+ if (n_tokens == 1) {
+ snprintf(out, out_size, "\n%s\n", cmd_tmgr_help);
+ return;
+ }
+
+ if ((n_tokens == 2) &&
+ (strcmp(tokens[1], "subport")) == 0) {
+ snprintf(out, out_size, "\n%s\n", cmd_tmgr_subport_help);
+ return;
+ }
+
+ if ((n_tokens == 3) &&
+ (strcmp(tokens[1], "subport") == 0) &&
+ (strcmp(tokens[2], "profile") == 0)) {
+ snprintf(out, out_size, "\n%s\n",
+ cmd_tmgr_subport_profile_help);
+ return;
+ }
+
+ if ((n_tokens == 3) &&
+ (strcmp(tokens[1], "subport") == 0) &&
+ (strcmp(tokens[2], "pipe") == 0)) {
+ snprintf(out, out_size, "\n%s\n", cmd_tmgr_subport_pipe_help);
+ return;
+ }
+
+ if ((n_tokens == 3) &&
+ (strcmp(tokens[1], "pipe") == 0) &&
+ (strcmp(tokens[2], "profile") == 0)) {
+ snprintf(out, out_size, "\n%s\n", cmd_tmgr_pipe_profile_help);
+ return;
+ }
+ }
+
+ if (strcmp(tokens[0], "tap") == 0) {
+ snprintf(out, out_size, "\n%s\n", cmd_tap_help);
+ return;
+ }
+
+ if (strcmp(tokens[0], "kni") == 0) {
+ snprintf(out, out_size, "\n%s\n", cmd_kni_help);
+ return;
+ }
+
+ if ((n_tokens == 4) &&
+ (strcmp(tokens[0], "port") == 0) &&
+ (strcmp(tokens[1], "in") == 0) &&
+ (strcmp(tokens[2], "action") == 0) &&
+ (strcmp(tokens[3], "profile") == 0)) {
+ snprintf(out, out_size, "\n%s\n", cmd_port_in_action_profile_help);
+ return;
+ }
+
+ if ((n_tokens == 3) &&
+ (strcmp(tokens[0], "table") == 0) &&
+ (strcmp(tokens[1], "action") == 0) &&
+ (strcmp(tokens[2], "profile") == 0)) {
+ snprintf(out, out_size, "\n%s\n", cmd_table_action_profile_help);
+ return;
+ }
+
+ if ((strcmp(tokens[0], "pipeline") == 0) && (n_tokens == 1)) {
+ snprintf(out, out_size, "\n%s\n", cmd_pipeline_help);
+ return;
+ }
+
+ if ((strcmp(tokens[0], "pipeline") == 0) &&
+ (strcmp(tokens[1], "port") == 0)) {
+ if ((n_tokens == 3) && (strcmp(tokens[2], "in")) == 0) {
+ snprintf(out, out_size, "\n%s\n", cmd_pipeline_port_in_help);
+ return;
+ }
+
+ if ((n_tokens == 3) && (strcmp(tokens[2], "out")) == 0) {
+ snprintf(out, out_size, "\n%s\n", cmd_pipeline_port_out_help);
+ return;
+ }
+
+ if ((n_tokens == 4) &&
+ (strcmp(tokens[2], "in") == 0) &&
+ (strcmp(tokens[3], "table") == 0)) {
+ snprintf(out, out_size, "\n%s\n",
+ cmd_pipeline_port_in_table_help);
+ return;
+ }
+
+ if ((n_tokens == 4) &&
+ (strcmp(tokens[2], "in") == 0) &&
+ (strcmp(tokens[3], "stats") == 0)) {
+ snprintf(out, out_size, "\n%s\n",
+ cmd_pipeline_port_in_stats_help);
+ return;
+ }
+
+ if ((n_tokens == 4) &&
+ (strcmp(tokens[2], "in") == 0) &&
+ (strcmp(tokens[3], "enable") == 0)) {
+ snprintf(out, out_size, "\n%s\n",
+ cmd_pipeline_port_in_enable_help);
+ return;
+ }
+
+ if ((n_tokens == 4) &&
+ (strcmp(tokens[2], "in") == 0) &&
+ (strcmp(tokens[3], "disable") == 0)) {
+ snprintf(out, out_size, "\n%s\n",
+ cmd_pipeline_port_in_disable_help);
+ return;
+ }
+
+ if ((n_tokens == 4) &&
+ (strcmp(tokens[2], "out") == 0) &&
+ (strcmp(tokens[3], "stats") == 0)) {
+ snprintf(out, out_size, "\n%s\n",
+ cmd_pipeline_port_out_stats_help);
+ return;
+ }
+ }
+
+ if ((strcmp(tokens[0], "pipeline") == 0) &&
+ (strcmp(tokens[1], "table") == 0)) {
+ if (n_tokens == 2) {
+ snprintf(out, out_size, "\n%s\n", cmd_pipeline_table_help);
+ return;
+ }
+
+ if ((n_tokens == 3) && strcmp(tokens[2], "stats") == 0) {
+ snprintf(out, out_size, "\n%s\n",
+ cmd_pipeline_table_stats_help);
+ return;
+ }
+
+ if ((n_tokens == 3) && strcmp(tokens[2], "dscp") == 0) {
+ snprintf(out, out_size, "\n%s\n",
+ cmd_pipeline_table_dscp_help);
+ return;
+ }
+
+ if ((n_tokens == 4) &&
+ (strcmp(tokens[2], "rule") == 0) &&
+ (strcmp(tokens[3], "add") == 0)) {
+ snprintf(out, out_size, "\n%s\n",
+ cmd_pipeline_table_rule_add_help);
+ return;
+ }
+
+ if ((n_tokens == 5) &&
+ (strcmp(tokens[2], "rule") == 0) &&
+ (strcmp(tokens[3], "add") == 0) &&
+ (strcmp(tokens[4], "default") == 0)) {
+ snprintf(out, out_size, "\n%s\n",
+ cmd_pipeline_table_rule_add_default_help);
+ return;
+ }
+
+ if ((n_tokens == 5) &&
+ (strcmp(tokens[2], "rule") == 0) &&
+ (strcmp(tokens[3], "add") == 0) &&
+ (strcmp(tokens[4], "bulk") == 0)) {
+ snprintf(out, out_size, "\n%s\n",
+ cmd_pipeline_table_rule_add_bulk_help);
+ return;
+ }
+
+ if ((n_tokens == 4) &&
+ (strcmp(tokens[2], "rule") == 0) &&
+ (strcmp(tokens[3], "delete") == 0)) {
+ snprintf(out, out_size, "\n%s\n",
+ cmd_pipeline_table_rule_delete_help);
+ return;
+ }
+
+ if ((n_tokens == 5) &&
+ (strcmp(tokens[2], "rule") == 0) &&
+ (strcmp(tokens[3], "delete") == 0) &&
+ (strcmp(tokens[4], "default") == 0)) {
+ snprintf(out, out_size, "\n%s\n",
+ cmd_pipeline_table_rule_delete_default_help);
+ return;
+ }
+
+ if ((n_tokens == 5) &&
+ (strcmp(tokens[2], "rule") == 0) &&
+ (strcmp(tokens[3], "stats") == 0) &&
+ (strcmp(tokens[4], "read") == 0)) {
+ snprintf(out, out_size, "\n%s\n",
+ cmd_pipeline_table_rule_stats_read_help);
+ return;
+ }
+
+ if ((n_tokens == 5) &&
+ (strcmp(tokens[2], "meter") == 0) &&
+ (strcmp(tokens[3], "profile") == 0) &&
+ (strcmp(tokens[4], "add") == 0)) {
+ snprintf(out, out_size, "\n%s\n",
+ cmd_pipeline_table_meter_profile_add_help);
+ return;
+ }
+
+ if ((n_tokens == 5) &&
+ (strcmp(tokens[2], "meter") == 0) &&
+ (strcmp(tokens[3], "profile") == 0) &&
+ (strcmp(tokens[4], "delete") == 0)) {
+ snprintf(out, out_size, "\n%s\n",
+ cmd_pipeline_table_meter_profile_delete_help);
+ return;
+ }
+
+ if ((n_tokens == 5) &&
+ (strcmp(tokens[2], "rule") == 0) &&
+ (strcmp(tokens[3], "meter") == 0) &&
+ (strcmp(tokens[4], "read") == 0)) {
+ snprintf(out, out_size, "\n%s\n",
+ cmd_pipeline_table_rule_meter_read_help);
+ return;
+ }
+
+ if ((n_tokens == 5) &&
+ (strcmp(tokens[2], "rule") == 0) &&
+ (strcmp(tokens[3], "ttl") == 0) &&
+ (strcmp(tokens[4], "read") == 0)) {
+ snprintf(out, out_size, "\n%s\n",
+ cmd_pipeline_table_rule_ttl_read_help);
+ return;
+ }
+ }
+
+ if ((n_tokens == 3) &&
+ (strcmp(tokens[0], "thread") == 0) &&
+ (strcmp(tokens[1], "pipeline") == 0)) {
+ if (strcmp(tokens[2], "enable") == 0) {
+ snprintf(out, out_size, "\n%s\n",
+ cmd_thread_pipeline_enable_help);
+ return;
+ }
+
+ if (strcmp(tokens[2], "disable") == 0) {
+ snprintf(out, out_size, "\n%s\n",
+ cmd_thread_pipeline_disable_help);
+ return;
+ }
+ }
+
+ snprintf(out, out_size, "Invalid command\n");
+}
+
void
cli_process(char *in, char *out, size_t out_size)
{
@@ -4374,12 +4791,22 @@ cli_process(char *in, char *out, size_t out_size)
if (n_tokens == 0)
return;
+ if (strcmp(tokens[0], "help") == 0) {
+ cmd_help(tokens, n_tokens, out, out_size);
+ return;
+ }
+
if (strcmp(tokens[0], "mempool") == 0) {
cmd_mempool(tokens, n_tokens, out, out_size);
return;
}
if (strcmp(tokens[0], "link") == 0) {
+ if (strcmp(tokens[1], "show") == 0) {
+ cmd_link_show(tokens, n_tokens, out, out_size);
+ return;
+ }
+
cmd_link(tokens, n_tokens, out, out_size);
return;
}
diff --git a/examples/ip_pipeline/examples/rss.cli b/examples/ip_pipeline/examples/rss.cli
new file mode 100644
index 00000000..29c0a913
--- /dev/null
+++ b/examples/ip_pipeline/examples/rss.cli
@@ -0,0 +1,112 @@
+; SPDX-License-Identifier: BSD-3-Clause
+; Copyright(c) 2010-2018 Intel Corporation
+
+; This setup demonstrates the usage of NIC Receive Side Scaling (RSS) feature.
+; Each NIC splits the input traffic into 4 RX queues, with each of its RX queues
+; being handled by a different pipeline:
+;
+; +-----------+ +----------+
+; +--------------------------->| | | |
+; | +------------------->| PIPELINE0 +--->| LINK 0 |--->
+; | | +------------->| (CORE A) | | TX |
+; | | | +------->| | | |
+; | | | | +-----------+ +----------+
+; +----------+ | | | |
+; | |-------+ | | |
+;--->| LINK 0 |-----------+ | | |
+; | RX |---------+ | | | |
+; | |-------+ | | | | |
+; +----------+ | | | | | | +-----------+ +----------+
+; | | +---|-----|-----|------->| | | |
+; +----------+ | | | +---|-----|------->| PIPELINE1 +--->| LINK 1 |--->
+; | |-------|-|-----+ | | +---|------->| (CORE B) | | TX |
+;--->| LINK 1 |-------|-|-------+ | | | +----->| | | |
+; | RX |-------|-|-------+ | | | | +-----------+ +----------+
+; | |-------|-|-----+ | | | | |
+; +----------+ | | | | | | | |
+; | | | | | | | |
+; +----------+ | | | | | | | |
+; | |-------|-|-----|-|---+ | | |
+;--->| LINK 2 |-------|-|-----|-|-----+ | | +-----------+ +----------+
+; | RX |-----+ | +-----|-|---------|-|----->| | | |
+; | |---+ | | | +---------|-|----->| PIPELINE2 +--->| LINK 2 |--->
+; +----------+ | +-|-------|-----------|-|----->| (CORE C) | | TX |
+; | | | | | +--->| | | |
+; +----------+ | | | | | | +-----------+ +----------+
+; | |---|---|-------|-----------+ | |
+;--->| LINK 3 |---|---|-------|-------------+ |
+; | RX |---|---|-------|---------------+
+; | |---|---|-------|-----------+
+; +----------+ | | | |
+; | | | | +-----------+ +----------+
+; | +-------|-----------|------->| | | |
+; | +-----------|------->| PIPELINE3 +--->| LINK 3 |--->
+; +-----------------------|------->| (CORE D) | | TX |
+; +------->| | | |
+; +-----------+ +----------+
+;
+;
+
+mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
+
+link LINK0 dev 0000:02:00.0 rxq 4 128 MEMPOOL0 txq 1 512 promiscuous on rss 0 1 2 3
+link LINK1 dev 0000:02:00.1 rxq 4 128 MEMPOOL0 txq 1 512 promiscuous on rss 0 1 2 3
+link LINK2 dev 0000:06:00.0 rxq 4 128 MEMPOOL0 txq 1 512 promiscuous on rss 0 1 2 3
+link LINK3 dev 0000:06:00.1 rxq 4 128 MEMPOOL0 txq 1 512 promiscuous on rss 0 1 2 3
+
+pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
+pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
+pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
+pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
+pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
+pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
+pipeline PIPELINE0 table match stub
+pipeline PIPELINE0 port in 0 table 0
+pipeline PIPELINE0 port in 1 table 0
+pipeline PIPELINE0 port in 2 table 0
+pipeline PIPELINE0 port in 3 table 0
+pipeline PIPELINE0 table 0 rule add match default action fwd port 0
+
+pipeline PIPELINE1 period 10 offset_port_id 0 cpu 0
+pipeline PIPELINE1 port in bsz 32 link LINK0 rxq 1
+pipeline PIPELINE1 port in bsz 32 link LINK1 rxq 1
+pipeline PIPELINE1 port in bsz 32 link LINK2 rxq 1
+pipeline PIPELINE1 port in bsz 32 link LINK3 rxq 1
+pipeline PIPELINE1 port out bsz 32 link LINK1 txq 0
+pipeline PIPELINE1 table match stub
+pipeline PIPELINE1 port in 0 table 0
+pipeline PIPELINE1 port in 1 table 0
+pipeline PIPELINE1 port in 2 table 0
+pipeline PIPELINE1 port in 3 table 0
+pipeline PIPELINE1 table 0 rule add match default action fwd port 0
+
+pipeline PIPELINE2 period 10 offset_port_id 0 cpu 0
+pipeline PIPELINE2 port in bsz 32 link LINK0 rxq 2
+pipeline PIPELINE2 port in bsz 32 link LINK1 rxq 2
+pipeline PIPELINE2 port in bsz 32 link LINK2 rxq 2
+pipeline PIPELINE2 port in bsz 32 link LINK3 rxq 2
+pipeline PIPELINE2 port out bsz 32 link LINK2 txq 0
+pipeline PIPELINE2 table match stub
+pipeline PIPELINE2 port in 0 table 0
+pipeline PIPELINE2 port in 1 table 0
+pipeline PIPELINE2 port in 2 table 0
+pipeline PIPELINE2 port in 3 table 0
+pipeline PIPELINE2 table 0 rule add match default action fwd port 0
+
+pipeline PIPELINE3 period 10 offset_port_id 0 cpu 0
+pipeline PIPELINE3 port in bsz 32 link LINK0 rxq 3
+pipeline PIPELINE3 port in bsz 32 link LINK1 rxq 3
+pipeline PIPELINE3 port in bsz 32 link LINK2 rxq 3
+pipeline PIPELINE3 port in bsz 32 link LINK3 rxq 3
+pipeline PIPELINE3 port out bsz 32 link LINK3 txq 0
+pipeline PIPELINE3 table match stub
+pipeline PIPELINE3 port in 0 table 0
+pipeline PIPELINE3 port in 1 table 0
+pipeline PIPELINE3 port in 2 table 0
+pipeline PIPELINE3 port in 3 table 0
+pipeline PIPELINE3 table 0 rule add match default action fwd port 0
+
+thread 1 pipeline PIPELINE0 enable
+thread 2 pipeline PIPELINE1 enable
+thread 3 pipeline PIPELINE2 enable
+thread 4 pipeline PIPELINE3 enable
diff --git a/examples/ip_pipeline/link.c b/examples/ip_pipeline/link.c
index b8a431f3..392a890f 100644
--- a/examples/ip_pipeline/link.c
+++ b/examples/ip_pipeline/link.c
@@ -36,22 +36,19 @@ link_find(const char *name)
return NULL;
}
+struct link *
+link_next(struct link *link)
+{
+ return (link == NULL) ? TAILQ_FIRST(&link_list) : TAILQ_NEXT(link, node);
+}
+
static struct rte_eth_conf port_conf_default = {
.link_speeds = 0,
.rxmode = {
.mq_mode = ETH_MQ_RX_NONE,
-
- .header_split = 0, /* Header split */
- .hw_ip_checksum = 0, /* IP checksum offload */
- .hw_vlan_filter = 0, /* VLAN filtering */
- .hw_vlan_strip = 0, /* VLAN strip */
- .hw_vlan_extend = 0, /* Extended VLAN */
- .jumbo_frame = 0, /* Jumbo frame support */
- .hw_strip_crc = 1, /* CRC strip by HW */
- .enable_scatter = 0, /* Scattered packets RX handler */
-
.max_rx_pkt_len = 9000, /* Jumbo frame max packet len */
.split_hdr_size = 0, /* Header split buffer size */
+ .offloads = DEV_RX_OFFLOAD_CRC_STRIP,
},
.rx_adv_conf = {
.rss_conf = {
@@ -162,7 +159,8 @@ link_create(const char *name, struct link_params *params)
if (rss) {
port_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
port_conf.rx_adv_conf.rss_conf.rss_hf =
- ETH_RSS_IPV4 | ETH_RSS_IPV6;
+ (ETH_RSS_IP | ETH_RSS_TCP | ETH_RSS_UDP) &
+ port_info.flow_type_rss_offloads;
}
cpu_id = (uint32_t) rte_eth_dev_socket_id(port_id);
diff --git a/examples/ip_pipeline/link.h b/examples/ip_pipeline/link.h
index 37d3dc43..34ff1149 100644
--- a/examples/ip_pipeline/link.h
+++ b/examples/ip_pipeline/link.h
@@ -30,6 +30,9 @@ link_init(void);
struct link *
link_find(const char *name);
+struct link *
+link_next(struct link *link);
+
struct link_params_rss {
uint32_t queue_id[LINK_RXQ_RSS_MAX];
uint32_t n_queues;
diff --git a/examples/ip_pipeline/thread.c b/examples/ip_pipeline/thread.c
index fa85cf63..7fc03332 100644
--- a/examples/ip_pipeline/thread.c
+++ b/examples/ip_pipeline/thread.c
@@ -155,6 +155,29 @@ thread_init(void)
return 0;
}
+static inline int
+thread_is_running(uint32_t thread_id)
+{
+ enum rte_lcore_state_t thread_state;
+
+ thread_state = rte_eal_get_lcore_state(thread_id);
+ return (thread_state == RUNNING) ? 1 : 0;
+}
+
+/**
+ * Pipeline is running when:
+ * (A) Pipeline is mapped to a data plane thread AND
+ * (B) Its data plane thread is in RUNNING state.
+ */
+static inline int
+pipeline_is_running(struct pipeline *p)
+{
+ if (p->enabled == 0)
+ return 0;
+
+ return thread_is_running(p->thread_id);
+}
+
/**
* Master thread & data plane threads: message passing
*/
@@ -254,6 +277,36 @@ thread_pipeline_enable(uint32_t thread_id,
p->enabled)
return -1;
+ if (!thread_is_running(thread_id)) {
+ struct thread_data *td = &thread_data[thread_id];
+ struct pipeline_data *tdp = &td->pipeline_data[td->n_pipelines];
+
+ if (td->n_pipelines >= THREAD_PIPELINES_MAX)
+ return -1;
+
+ /* Data plane thread */
+ td->p[td->n_pipelines] = p->p;
+
+ tdp->p = p->p;
+ for (i = 0; i < p->n_tables; i++)
+ tdp->table_data[i].a = p->table[i].a;
+
+ tdp->n_tables = p->n_tables;
+
+ tdp->msgq_req = p->msgq_req;
+ tdp->msgq_rsp = p->msgq_rsp;
+ tdp->timer_period = (rte_get_tsc_hz() * p->timer_period_ms) / 1000;
+ tdp->time_next = rte_get_tsc_cycles() + tdp->timer_period;
+
+ td->n_pipelines++;
+
+ /* Pipeline */
+ p->thread_id = thread_id;
+ p->enabled = 1;
+
+ return 0;
+ }
+
/* Allocate request */
req = thread_msg_alloc();
if (req == NULL)
@@ -316,6 +369,38 @@ thread_pipeline_disable(uint32_t thread_id,
if (p->thread_id != thread_id)
return -1;
+ if (!thread_is_running(thread_id)) {
+ struct thread_data *td = &thread_data[thread_id];
+ uint32_t i;
+
+ for (i = 0; i < td->n_pipelines; i++) {
+ struct pipeline_data *tdp = &td->pipeline_data[i];
+
+ if (tdp->p != p->p)
+ continue;
+
+ /* Data plane thread */
+ if (i < td->n_pipelines - 1) {
+ struct rte_pipeline *pipeline_last =
+ td->p[td->n_pipelines - 1];
+ struct pipeline_data *tdp_last =
+ &td->pipeline_data[td->n_pipelines - 1];
+
+ td->p[i] = pipeline_last;
+ memcpy(tdp, tdp_last, sizeof(*tdp));
+ }
+
+ td->n_pipelines--;
+
+ /* Pipeline */
+ p->enabled = 0;
+
+ break;
+ }
+
+ return 0;
+ }
+
/* Allocate request */
req = thread_msg_alloc();
if (req == NULL)
@@ -698,10 +783,18 @@ pipeline_port_in_stats_read(const char *pipeline_name,
p = pipeline_find(pipeline_name);
if ((p == NULL) ||
- (p->enabled == 0) ||
(port_id >= p->n_ports_in))
return -1;
+ if (!pipeline_is_running(p)) {
+ status = rte_pipeline_port_in_stats_read(p->p,
+ port_id,
+ stats,
+ clear);
+
+ return status;
+ }
+
/* Allocate request */
req = pipeline_msg_alloc();
if (req == NULL)
@@ -743,10 +836,14 @@ pipeline_port_in_enable(const char *pipeline_name,
p = pipeline_find(pipeline_name);
if ((p == NULL) ||
- (p->enabled == 0) ||
(port_id >= p->n_ports_in))
return -1;
+ if (!pipeline_is_running(p)) {
+ status = rte_pipeline_port_in_enable(p->p, port_id);
+ return status;
+ }
+
/* Allocate request */
req = pipeline_msg_alloc();
if (req == NULL)
@@ -785,10 +882,14 @@ pipeline_port_in_disable(const char *pipeline_name,
p = pipeline_find(pipeline_name);
if ((p == NULL) ||
- (p->enabled == 0) ||
(port_id >= p->n_ports_in))
return -1;
+ if (!pipeline_is_running(p)) {
+ status = rte_pipeline_port_in_disable(p->p, port_id);
+ return status;
+ }
+
/* Allocate request */
req = pipeline_msg_alloc();
if (req == NULL)
@@ -830,10 +931,18 @@ pipeline_port_out_stats_read(const char *pipeline_name,
p = pipeline_find(pipeline_name);
if ((p == NULL) ||
- (p->enabled == 0) ||
(port_id >= p->n_ports_out))
return -1;
+ if (!pipeline_is_running(p)) {
+ status = rte_pipeline_port_out_stats_read(p->p,
+ port_id,
+ stats,
+ clear);
+
+ return status;
+ }
+
/* Allocate request */
req = pipeline_msg_alloc();
if (req == NULL)
@@ -878,10 +987,18 @@ pipeline_table_stats_read(const char *pipeline_name,
p = pipeline_find(pipeline_name);
if ((p == NULL) ||
- (p->enabled == 0) ||
(table_id >= p->n_tables))
return -1;
+ if (!pipeline_is_running(p)) {
+ status = rte_pipeline_table_stats_read(p->p,
+ table_id,
+ stats,
+ clear);
+
+ return status;
+ }
+
/* Allocate request */
req = pipeline_msg_alloc();
if (req == NULL)
@@ -1070,6 +1187,25 @@ action_default_check(struct table_rule_action *action,
return 0;
}
+union table_rule_match_low_level {
+ struct rte_table_acl_rule_add_params acl_add;
+ struct rte_table_acl_rule_delete_params acl_delete;
+ struct rte_table_array_key array;
+ uint8_t hash[TABLE_RULE_MATCH_SIZE_MAX];
+ struct rte_table_lpm_key lpm_ipv4;
+ struct rte_table_lpm_ipv6_key lpm_ipv6;
+};
+
+static int
+match_convert(struct table_rule_match *mh,
+ union table_rule_match_low_level *ml,
+ int add);
+
+static int
+action_convert(struct rte_table_action *a,
+ struct table_rule_action *action,
+ struct rte_pipeline_table_entry *data);
+
int
pipeline_table_rule_add(const char *pipeline_name,
uint32_t table_id,
@@ -1091,12 +1227,56 @@ pipeline_table_rule_add(const char *pipeline_name,
p = pipeline_find(pipeline_name);
if ((p == NULL) ||
- (p->enabled == 0) ||
(table_id >= p->n_tables) ||
match_check(match, p, table_id) ||
action_check(action, p, table_id))
return -1;
+ if (!pipeline_is_running(p)) {
+ struct rte_table_action *a = p->table[table_id].a;
+ union table_rule_match_low_level match_ll;
+ struct rte_pipeline_table_entry *data_in, *data_out;
+ int key_found;
+ uint8_t *buffer;
+
+ buffer = calloc(TABLE_RULE_ACTION_SIZE_MAX, sizeof(uint8_t));
+ if (buffer == NULL)
+ return -1;
+
+ /* Table match-action rule conversion */
+ data_in = (struct rte_pipeline_table_entry *)buffer;
+
+ status = match_convert(match, &match_ll, 1);
+ if (status) {
+ free(buffer);
+ return -1;
+ }
+
+ status = action_convert(a, action, data_in);
+ if (status) {
+ free(buffer);
+ return -1;
+ }
+
+ /* Add rule (match, action) to table */
+ status = rte_pipeline_table_entry_add(p->p,
+ table_id,
+ &match_ll,
+ data_in,
+ &key_found,
+ &data_out);
+ if (status) {
+ free(buffer);
+ return -1;
+ }
+
+ /* Write Response */
+ *data = data_out;
+
+ free(buffer);
+ return 0;
+ }
+
/* Allocate request */
req = pipeline_msg_alloc();
if (req == NULL)
@@ -1143,11 +1323,44 @@ pipeline_table_rule_add_default(const char *pipeline_name,
p = pipeline_find(pipeline_name);
if ((p == NULL) ||
- (p->enabled == 0) ||
(table_id >= p->n_tables) ||
action_default_check(action, p, table_id))
return -1;
+ if (!pipeline_is_running(p)) {
+ struct rte_pipeline_table_entry *data_in, *data_out;
+ uint8_t *buffer;
+
+ buffer = calloc(TABLE_RULE_ACTION_SIZE_MAX, sizeof(uint8_t));
+ if (buffer == NULL)
+ return -1;
+
+ /* Apply actions */
+ data_in = (struct rte_pipeline_table_entry *)buffer;
+
+ data_in->action = action->fwd.action;
+ if (action->fwd.action == RTE_PIPELINE_ACTION_PORT)
+ data_in->port_id = action->fwd.id;
+ if (action->fwd.action == RTE_PIPELINE_ACTION_TABLE)
+ data_in->table_id = action->fwd.id;
+
+ /* Add default rule to table */
+ status = rte_pipeline_table_default_entry_add(p->p,
+ table_id,
+ data_in,
+ &data_out);
+ if (status) {
+ free(buffer);
+ return -1;
+ }
+
+ /* Write Response */
+ *data = data_out;
+
+ free(buffer);
+ return 0;
+ }
+
/* Allocate request */
req = pipeline_msg_alloc();
if (req == NULL)
@@ -1199,7 +1412,6 @@ pipeline_table_rule_add_bulk(const char *pipeline_name,
p = pipeline_find(pipeline_name);
if ((p == NULL) ||
- (p->enabled == 0) ||
(table_id >= p->n_tables))
return -1;
@@ -1208,6 +1420,99 @@ pipeline_table_rule_add_bulk(const char *pipeline_name,
action_check(action, p, table_id))
return -1;
+ if (!pipeline_is_running(p)) {
+ struct rte_table_action *a = p->table[table_id].a;
+ union table_rule_match_low_level *match_ll;
+ uint8_t *action_ll;
+ void **match_ll_ptr;
+ struct rte_pipeline_table_entry **action_ll_ptr;
+ struct rte_pipeline_table_entry **entries_ptr =
+ (struct rte_pipeline_table_entry **)data;
+ uint32_t bulk =
+ (p->table[table_id].params.match_type == TABLE_ACL) ? 1 : 0;
+ int *found;
+
+ /* Memory allocation */
+ match_ll = calloc(*n_rules, sizeof(union table_rule_match_low_level));
+ action_ll = calloc(*n_rules, TABLE_RULE_ACTION_SIZE_MAX);
+ match_ll_ptr = calloc(*n_rules, sizeof(void *));
+ action_ll_ptr =
+ calloc(*n_rules, sizeof(struct rte_pipeline_table_entry *));
+ found = calloc(*n_rules, sizeof(int));
+
+ if (match_ll == NULL ||
+ action_ll == NULL ||
+ match_ll_ptr == NULL ||
+ action_ll_ptr == NULL ||
+ found == NULL)
+ goto fail;
+
+ for (i = 0; i < *n_rules; i++) {
+ match_ll_ptr[i] = (void *)&match_ll[i];
+ action_ll_ptr[i] =
+ (struct rte_pipeline_table_entry *)&action_ll[i * TABLE_RULE_ACTION_SIZE_MAX];
+ }
+
+ /* Rule match conversion */
+ for (i = 0; i < *n_rules; i++) {
+ status = match_convert(&match[i], match_ll_ptr[i], 1);
+ if (status)
+ goto fail;
+ }
+
+ /* Rule action conversion */
+ for (i = 0; i < *n_rules; i++) {
+ status = action_convert(a, &action[i], action_ll_ptr[i]);
+ if (status)
+ goto fail;
+ }
+
+ /* Add rule (match, action) to table */
+ if (bulk) {
+ status = rte_pipeline_table_entry_add_bulk(p->p,
+ table_id,
+ match_ll_ptr,
+ action_ll_ptr,
+ *n_rules,
+ found,
+ entries_ptr);
+ if (status)
+ *n_rules = 0;
+ } else {
+ for (i = 0; i < *n_rules; i++) {
+ status = rte_pipeline_table_entry_add(p->p,
+ table_id,
+ match_ll_ptr[i],
+ action_ll_ptr[i],
+ &found[i],
+ &entries_ptr[i]);
+ if (status) {
+ *n_rules = i;
+ break;
+ }
+ }
+ }
+
+ /* Free */
+ free(found);
+ free(action_ll_ptr);
+ free(match_ll_ptr);
+ free(action_ll);
+ free(match_ll);
+
+ return status;
+
+fail:
+ free(found);
+ free(action_ll_ptr);
+ free(match_ll_ptr);
+ free(action_ll);
+ free(match_ll);
+
+ *n_rules = 0;
+ return -1;
+ }
+
/* Allocate request */
req = pipeline_msg_alloc();
if (req == NULL)
@@ -1256,11 +1561,27 @@ pipeline_table_rule_delete(const char *pipeline_name,
p = pipeline_find(pipeline_name);
if ((p == NULL) ||
- (p->enabled == 0) ||
(table_id >= p->n_tables) ||
match_check(match, p, table_id))
return -1;
+ if (!pipeline_is_running(p)) {
+ union table_rule_match_low_level match_ll;
+ int key_found;
+
+ status = match_convert(match, &match_ll, 0);
+ if (status)
+ return -1;
+
+ status = rte_pipeline_table_entry_delete(p->p,
+ table_id,
+ &match_ll,
+ &key_found,
+ NULL);
+
+ return status;
+ }
+
/* Allocate request */
req = pipeline_msg_alloc();
if (req == NULL)
@@ -1300,10 +1621,17 @@ pipeline_table_rule_delete_default(const char *pipeline_name,
p = pipeline_find(pipeline_name);
if ((p == NULL) ||
- (p->enabled == 0) ||
(table_id >= p->n_tables))
return -1;
+ if (!pipeline_is_running(p)) {
+ status = rte_pipeline_table_default_entry_delete(p->p,
+ table_id,
+ NULL);
+
+ return status;
+ }
+
/* Allocate request */
req = pipeline_msg_alloc();
if (req == NULL)
@@ -1347,10 +1675,20 @@ pipeline_table_rule_stats_read(const char *pipeline_name,
p = pipeline_find(pipeline_name);
if ((p == NULL) ||
- (p->enabled == 0) ||
(table_id >= p->n_tables))
return -1;
+ if (!pipeline_is_running(p)) {
+ struct rte_table_action *a = p->table[table_id].a;
+
+ status = rte_table_action_stats_read(a,
+ data,
+ stats,
+ clear);
+
+ return status;
+ }
+
/* Allocate request */
req = pipeline_msg_alloc();
if (req == NULL)
@@ -1396,10 +1734,19 @@ pipeline_table_mtr_profile_add(const char *pipeline_name,
p = pipeline_find(pipeline_name);
if ((p == NULL) ||
- (p->enabled == 0) ||
(table_id >= p->n_tables))
return -1;
+ if (!pipeline_is_running(p)) {
+ struct rte_table_action *a = p->table[table_id].a;
+
+ status = rte_table_action_meter_profile_add(a,
+ meter_profile_id,
+ profile);
+
+ return status;
+ }
+
/* Allocate request */
req = pipeline_msg_alloc();
if (req == NULL)
@@ -1441,10 +1788,18 @@ pipeline_table_mtr_profile_delete(const char *pipeline_name,
p = pipeline_find(pipeline_name);
if ((p == NULL) ||
- (p->enabled == 0) ||
(table_id >= p->n_tables))
return -1;
+ if (!pipeline_is_running(p)) {
+ struct rte_table_action *a = p->table[table_id].a;
+
+ status = rte_table_action_meter_profile_delete(a,
+ meter_profile_id);
+
+ return status;
+ }
+
/* Allocate request */
req = pipeline_msg_alloc();
if (req == NULL)
@@ -1490,10 +1845,21 @@ pipeline_table_rule_mtr_read(const char *pipeline_name,
p = pipeline_find(pipeline_name);
if ((p == NULL) ||
- (p->enabled == 0) ||
(table_id >= p->n_tables))
return -1;
+ if (!pipeline_is_running(p)) {
+ struct rte_table_action *a = p->table[table_id].a;
+
+ status = rte_table_action_meter_read(a,
+ data,
+ tc_mask,
+ stats,
+ clear);
+
+ return status;
+ }
+
/* Allocate request */
req = pipeline_msg_alloc();
if (req == NULL)
@@ -1540,10 +1906,19 @@ pipeline_table_dscp_table_update(const char *pipeline_name,
p = pipeline_find(pipeline_name);
if ((p == NULL) ||
- (p->enabled == 0) ||
(table_id >= p->n_tables))
return -1;
+ if (!pipeline_is_running(p)) {
+ struct rte_table_action *a = p->table[table_id].a;
+
+ status = rte_table_action_dscp_table_update(a,
+ dscp_mask,
+ dscp_table);
+
+ return status;
+ }
+
/* Allocate request */
req = pipeline_msg_alloc();
if (req == NULL)
@@ -1590,10 +1965,20 @@ pipeline_table_rule_ttl_read(const char *pipeline_name,
p = pipeline_find(pipeline_name);
if ((p == NULL) ||
- (p->enabled == 0) ||
(table_id >= p->n_tables))
return -1;
+ if (!pipeline_is_running(p)) {
+ struct rte_table_action *a = p->table[table_id].a;
+
+ status = rte_table_action_ttl_read(a,
+ data,
+ stats,
+ clear);
+
+ return status;
+ }
+
/* Allocate request */
req = pipeline_msg_alloc();
if (req == NULL)
@@ -1722,15 +2107,6 @@ pipeline_msg_handle_table_stats_read(struct pipeline_data *p,
return rsp;
}
-union table_rule_match_low_level {
- struct rte_table_acl_rule_add_params acl_add;
- struct rte_table_acl_rule_delete_params acl_delete;
- struct rte_table_array_key array;
- uint8_t hash[TABLE_RULE_MATCH_SIZE_MAX];
- struct rte_table_lpm_key lpm_ipv4;
- struct rte_table_lpm_ipv6_key lpm_ipv6;
-};
-
static int
match_convert_ipv6_depth(uint32_t depth, uint32_t *depth32)
{
@@ -2002,138 +2378,136 @@ match_convert(struct table_rule_match *mh,
}
}
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_add(struct pipeline_data *p,
- struct pipeline_msg_req *req)
+static int
+action_convert(struct rte_table_action *a,
+ struct table_rule_action *action,
+ struct rte_pipeline_table_entry *data)
{
- union table_rule_match_low_level match_ll;
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- struct table_rule_match *match = &req->table_rule_add.match;
- struct table_rule_action *action = &req->table_rule_add.action;
- struct rte_pipeline_table_entry *data_in, *data_out;
- uint32_t table_id = req->id;
- int key_found, status;
- struct rte_table_action *a = p->table_data[table_id].a;
+ int status;
/* Apply actions */
- memset(p->buffer, 0, sizeof(p->buffer));
- data_in = (struct rte_pipeline_table_entry *) p->buffer;
-
if (action->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
status = rte_table_action_apply(a,
- data_in,
+ data,
RTE_TABLE_ACTION_FWD,
&action->fwd);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
+ if (status)
+ return status;
}
if (action->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
status = rte_table_action_apply(a,
- data_in,
+ data,
RTE_TABLE_ACTION_LB,
&action->lb);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
+ if (status)
+ return status;
}
if (action->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
status = rte_table_action_apply(a,
- data_in,
+ data,
RTE_TABLE_ACTION_MTR,
&action->mtr);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
+ if (status)
+ return status;
}
if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
status = rte_table_action_apply(a,
- data_in,
+ data,
RTE_TABLE_ACTION_TM,
&action->tm);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
+ if (status)
+ return status;
}
if (action->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
status = rte_table_action_apply(a,
- data_in,
+ data,
RTE_TABLE_ACTION_ENCAP,
&action->encap);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
+ if (status)
+ return status;
}
if (action->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
status = rte_table_action_apply(a,
- data_in,
+ data,
RTE_TABLE_ACTION_NAT,
&action->nat);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
+ if (status)
+ return status;
}
if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {
status = rte_table_action_apply(a,
- data_in,
+ data,
RTE_TABLE_ACTION_TTL,
&action->ttl);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
+ if (status)
+ return status;
}
if (action->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {
status = rte_table_action_apply(a,
- data_in,
+ data,
RTE_TABLE_ACTION_STATS,
&action->stats);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
+ if (status)
+ return status;
}
if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
status = rte_table_action_apply(a,
- data_in,
+ data,
RTE_TABLE_ACTION_TIME,
&action->time);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
+ if (status)
+ return status;
}
- /* Add rule (match, action) to table */
+ return 0;
+}
+
+static struct pipeline_msg_rsp *
+pipeline_msg_handle_table_rule_add(struct pipeline_data *p,
+ struct pipeline_msg_req *req)
+{
+ union table_rule_match_low_level match_ll;
+ struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
+ struct table_rule_match *match = &req->table_rule_add.match;
+ struct table_rule_action *action = &req->table_rule_add.action;
+ struct rte_pipeline_table_entry *data_in, *data_out;
+ uint32_t table_id = req->id;
+ int key_found, status;
+ struct rte_table_action *a = p->table_data[table_id].a;
+
+ /* Apply actions */
+ memset(p->buffer, 0, sizeof(p->buffer));
+ data_in = (struct rte_pipeline_table_entry *) p->buffer;
+
status = match_convert(match, &match_ll, 1);
if (status) {
rsp->status = -1;
return rsp;
}
+ status = action_convert(a, action, data_in);
+ if (status) {
+ rsp->status = -1;
+ return rsp;
+ }
+
status = rte_pipeline_table_entry_add(p->p,
table_id,
&match_ll,
@@ -2242,98 +2616,9 @@ pipeline_msg_handle_table_rule_add_bulk(struct pipeline_data *p,
/* Rule action conversion */
for (i = 0; i < n_rules; i++) {
- void *data_in = action_ll_ptr[i];
- struct table_rule_action *act = &action[i];
-
- if (act->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- status = rte_table_action_apply(a,
- data_in,
- RTE_TABLE_ACTION_FWD,
- &act->fwd);
-
- if (status)
- goto fail;
- }
-
- if (act->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
- status = rte_table_action_apply(a,
- data_in,
- RTE_TABLE_ACTION_LB,
- &act->lb);
-
- if (status)
- goto fail;
- }
-
- if (act->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- status = rte_table_action_apply(a,
- data_in,
- RTE_TABLE_ACTION_MTR,
- &act->mtr);
-
- if (status)
- goto fail;
- }
-
- if (act->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
- status = rte_table_action_apply(a,
- data_in,
- RTE_TABLE_ACTION_TM,
- &act->tm);
-
- if (status)
- goto fail;
- }
-
- if (act->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- status = rte_table_action_apply(a,
- data_in,
- RTE_TABLE_ACTION_ENCAP,
- &act->encap);
-
- if (status)
- goto fail;
- }
-
- if (act->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- status = rte_table_action_apply(a,
- data_in,
- RTE_TABLE_ACTION_NAT,
- &act->nat);
-
- if (status)
- goto fail;
- }
-
- if (act->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {
- status = rte_table_action_apply(a,
- data_in,
- RTE_TABLE_ACTION_TTL,
- &act->ttl);
-
- if (status)
- goto fail;
- }
-
- if (act->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {
- status = rte_table_action_apply(a,
- data_in,
- RTE_TABLE_ACTION_STATS,
- &act->stats);
-
- if (status)
- goto fail;
- }
-
- if (act->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
- status = rte_table_action_apply(a,
- data_in,
- RTE_TABLE_ACTION_TIME,
- &act->time);
-
- if (status)
- goto fail;
- }
+ status = action_convert(a, &action[i], action_ll_ptr[i]);
+ if (status)
+ goto fail;
}
/* Add rule (match, action) to table */
diff --git a/examples/ip_reassembly/main.c b/examples/ip_reassembly/main.c
index 3e8e79c2..b830f67a 100644
--- a/examples/ip_reassembly/main.c
+++ b/examples/ip_reassembly/main.c
@@ -164,7 +164,6 @@ static struct rte_eth_conf port_conf = {
.mq_mode = ETH_MQ_RX_RSS,
.max_rx_pkt_len = JUMBO_FRAME_MAX_SIZE,
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
.offloads = (DEV_RX_OFFLOAD_CHECKSUM |
DEV_RX_OFFLOAD_JUMBO_FRAME |
DEV_RX_OFFLOAD_CRC_STRIP),
@@ -1083,6 +1082,18 @@ main(int argc, char **argv)
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
local_port_conf.txmode.offloads |=
DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+ local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
+ dev_info.flow_type_rss_offloads;
+ if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
+ port_conf.rx_adv_conf.rss_conf.rss_hf) {
+ printf("Port %u modified RSS hash function based on hardware support,"
+ "requested:%#"PRIx64" configured:%#"PRIx64"\n",
+ portid,
+ port_conf.rx_adv_conf.rss_conf.rss_hf,
+ local_port_conf.rx_adv_conf.rss_conf.rss_hf);
+ }
+
ret = rte_eth_dev_configure(portid, 1, (uint16_t)n_tx_queue,
&local_port_conf);
if (ret < 0) {
@@ -1121,7 +1132,6 @@ main(int argc, char **argv)
fflush(stdout);
txconf = &dev_info.default_txconf;
- txconf->txq_flags = ETH_TXQ_FLAGS_IGNORE;
txconf->offloads = local_port_conf.txmode.offloads;
ret = rte_eth_tx_queue_setup(portid, queueid, nb_txd,
diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c
index a5da8b28..b45b87bd 100644
--- a/examples/ipsec-secgw/ipsec-secgw.c
+++ b/examples/ipsec-secgw/ipsec-secgw.c
@@ -199,7 +199,6 @@ static struct rte_eth_conf port_conf = {
.split_hdr_size = 0,
.offloads = DEV_RX_OFFLOAD_CHECKSUM |
DEV_RX_OFFLOAD_CRC_STRIP,
- .ignore_offload_bitfield = 1,
},
.rx_adv_conf = {
.rss_conf = {
@@ -331,6 +330,7 @@ prepare_tx_pkt(struct rte_mbuf *pkt, uint16_t port)
pkt->l3_len = sizeof(struct ip);
pkt->l2_len = ETHER_HDR_LEN;
+ ip->ip_sum = 0;
ethhdr->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
} else {
pkt->ol_flags |= PKT_TX_IPV6;
@@ -510,11 +510,13 @@ outbound_sp(struct sp_ctx *sp, struct traffic_type *ip,
sa_idx = ip->res[i] & PROTECT_MASK;
if (ip->res[i] & DISCARD)
rte_pktmbuf_free(m);
+ else if (ip->res[i] & BYPASS)
+ ip->pkts[j++] = m;
else if (sa_idx < IPSEC_SA_MAX_ENTRIES) {
ipsec->res[ipsec->num] = sa_idx;
ipsec->pkts[ipsec->num++] = m;
- } else /* BYPASS */
- ip->pkts[j++] = m;
+ } else /* invalid SA idx */
+ rte_pktmbuf_free(m);
}
ip->num = j;
}
@@ -1440,6 +1442,12 @@ cryptodevs_init(void)
dev_conf.socket_id = rte_cryptodev_socket_id(cdev_id);
dev_conf.nb_queue_pairs = qp;
+ uint32_t dev_max_sess = cdev_info.sym.max_nb_sessions;
+ if (dev_max_sess != 0 && dev_max_sess < (CDEV_MP_NB_OBJS / 2))
+ rte_exit(EXIT_FAILURE,
+ "Device does not support at least %u "
+ "sessions", CDEV_MP_NB_OBJS / 2);
+
if (!socket_ctx[dev_conf.socket_id].session_pool) {
char mp_name[RTE_MEMPOOL_NAMESIZE];
struct rte_mempool *sess_mp;
@@ -1566,6 +1574,18 @@ port_init(uint16_t portid)
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
local_port_conf.txmode.offloads |=
DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+ local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
+ dev_info.flow_type_rss_offloads;
+ if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
+ port_conf.rx_adv_conf.rss_conf.rss_hf) {
+ printf("Port %u modified RSS hash function based on hardware support,"
+ "requested:%#"PRIx64" configured:%#"PRIx64"\n",
+ portid,
+ port_conf.rx_adv_conf.rss_conf.rss_hf,
+ local_port_conf.rx_adv_conf.rss_conf.rss_hf);
+ }
+
ret = rte_eth_dev_configure(portid, nb_rx_queue, nb_tx_queue,
&local_port_conf);
if (ret < 0)
@@ -1592,7 +1612,6 @@ port_init(uint16_t portid)
printf("Setup txq=%u,%d,%d\n", lcore_id, tx_queueid, socket_id);
txconf = &dev_info.default_txconf;
- txconf->txq_flags = ETH_TXQ_FLAGS_IGNORE;
txconf->offloads = local_port_conf.txmode.offloads;
ret = rte_eth_tx_queue_setup(portid, tx_queueid, nb_txd,
diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h
index 9b87278c..c998c807 100644
--- a/examples/ipsec-secgw/ipsec.h
+++ b/examples/ipsec-secgw/ipsec.h
@@ -191,7 +191,7 @@ ipsec_metadata_size(void)
static inline struct ipsec_mbuf_metadata *
get_priv(struct rte_mbuf *m)
{
- return RTE_PTR_ADD(m, sizeof(struct rte_mbuf));
+ return rte_mbuf_to_priv(m);
}
static inline void *
diff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c
index d9dcc0e0..4ab8e098 100644
--- a/examples/ipsec-secgw/sa.c
+++ b/examples/ipsec-secgw/sa.c
@@ -939,7 +939,7 @@ inbound_sa_check(struct sa_ctx *sa_ctx, struct rte_mbuf *m, uint32_t sa_idx)
{
struct ipsec_mbuf_metadata *priv;
- priv = RTE_PTR_ADD(m, sizeof(struct rte_mbuf));
+ priv = get_priv(m);
return (sa_ctx->sa[sa_idx].spi == priv->sa->spi);
}
diff --git a/examples/ipv4_multicast/main.c b/examples/ipv4_multicast/main.c
index ad2072f4..331c32e7 100644
--- a/examples/ipv4_multicast/main.c
+++ b/examples/ipv4_multicast/main.c
@@ -109,7 +109,6 @@ static struct rte_eth_conf port_conf = {
.rxmode = {
.max_rx_pkt_len = JUMBO_FRAME_MAX_SIZE,
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
.offloads = (DEV_RX_OFFLOAD_JUMBO_FRAME |
DEV_RX_OFFLOAD_CRC_STRIP),
},
@@ -764,7 +763,6 @@ main(int argc, char **argv)
fflush(stdout);
txconf = &dev_info.default_txconf;
- txconf->txq_flags = ETH_TXQ_FLAGS_IGNORE;
txconf->offloads = local_port_conf.txmode.offloads;
ret = rte_eth_tx_queue_setup(portid, queueid, nb_txd,
rte_lcore_to_socket_id(lcore_id), txconf);
diff --git a/examples/kni/Makefile b/examples/kni/Makefile
index 562dc274..7e19d2e2 100644
--- a/examples/kni/Makefile
+++ b/examples/kni/Makefile
@@ -48,7 +48,7 @@ RTE_TARGET ?= x86_64-native-linuxapp-gcc
include $(RTE_SDK)/mk/rte.vars.mk
-ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
$(error This application can only operate in a linuxapp environment, \
please change the definition of the RTE_TARGET environment variable)
endif
diff --git a/examples/kni/main.c b/examples/kni/main.c
index 4b162deb..81336087 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -95,7 +95,6 @@ static struct kni_port_params *kni_port_params_array[RTE_MAX_ETHPORTS];
/* Options for configuring ethernet port */
static struct rte_eth_conf port_conf = {
.rxmode = {
- .ignore_offload_bitfield = 1,
.offloads = DEV_RX_OFFLOAD_CRC_STRIP,
},
.txmode = {
@@ -607,7 +606,6 @@ init_port(uint16_t port)
"port%u (%d)\n", (unsigned)port, ret);
txq_conf = dev_info.default_txconf;
- txq_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
txq_conf.offloads = local_port_conf.txmode.offloads;
ret = rte_eth_tx_queue_setup(port, 0, nb_txd,
rte_eth_dev_socket_id(port), &txq_conf);
diff --git a/examples/kni/meson.build b/examples/kni/meson.build
index 0443ab99..79131639 100644
--- a/examples/kni/meson.build
+++ b/examples/kni/meson.build
@@ -6,9 +6,8 @@
# To build this example as a standalone application with an already-installed
# DPDK instance, use 'make'
-if host_machine.system() != 'linux'
- build = false
-endif
+# this app can be built if-and-only-if KNI library is buildable
+build = dpdk_conf.has('RTE_LIBRTE_KNI')
deps += ['kni', 'bus_pci']
sources = files(
'main.c'
diff --git a/examples/l2fwd-crypto/Makefile b/examples/l2fwd-crypto/Makefile
index a67f087b..6658fd0d 100644
--- a/examples/l2fwd-crypto/Makefile
+++ b/examples/l2fwd-crypto/Makefile
@@ -51,5 +51,11 @@ include $(RTE_SDK)/mk/rte.vars.mk
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
+ifeq ($(CONFIG_RTE_LIBRTE_PMD_CRYPTO_SCHEDULER),y)
+LDLIBS += -lrte_pmd_crypto_scheduler
+endif
+endif
+
include $(RTE_SDK)/mk/rte.extapp.mk
endif
diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c
index 4bca87b1..6061b751 100644
--- a/examples/l2fwd-crypto/main.c
+++ b/examples/l2fwd-crypto/main.c
@@ -42,6 +42,9 @@
#include <rte_prefetch.h>
#include <rte_random.h>
#include <rte_hexdump.h>
+#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER
+#include <rte_cryptodev_scheduler.h>
+#endif
enum cdev_type {
CDEV_TYPE_ANY,
@@ -59,7 +62,6 @@ enum cdev_type {
#define MAX_AAD_SIZE 65535
#define MAX_PKT_BURST 32
#define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */
-#define MAX_SESSIONS 32
#define SESSION_POOL_CACHE_SIZE 0
#define MAXIMUM_IV_LENGTH 16
@@ -211,7 +213,6 @@ static struct rte_eth_conf port_conf = {
.mq_mode = ETH_MQ_RX_NONE,
.max_rx_pkt_len = ETHER_MAX_LEN,
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
.offloads = DEV_RX_OFFLOAD_CRC_STRIP,
},
.txmode = {
@@ -407,7 +408,7 @@ l2fwd_simple_crypto_enqueue(struct rte_mbuf *m,
/* Zero pad data to be crypto'd so it is block aligned */
data_len = rte_pktmbuf_data_len(m) - ipdata_offset;
- if (cparams->do_hash && cparams->hash_verify)
+ if ((cparams->do_hash || cparams->do_aead) && cparams->hash_verify)
data_len -= cparams->digest_length;
if (cparams->do_cipher) {
@@ -1930,21 +1931,19 @@ check_supported_size(uint16_t length, uint16_t min, uint16_t max,
static int
check_iv_param(const struct rte_crypto_param_range *iv_range_size,
unsigned int iv_param, int iv_random_size,
- uint16_t *iv_length)
+ uint16_t iv_length)
{
/*
* Check if length of provided IV is supported
* by the algorithm chosen.
*/
if (iv_param) {
- if (check_supported_size(*iv_length,
+ if (check_supported_size(iv_length,
iv_range_size->min,
iv_range_size->max,
iv_range_size->increment)
- != 0) {
- printf("Unsupported IV length\n");
+ != 0)
return -1;
- }
/*
* Check if length of IV to be randomly generated
* is supported by the algorithm chosen.
@@ -1954,14 +1953,250 @@ check_iv_param(const struct rte_crypto_param_range *iv_range_size,
iv_range_size->min,
iv_range_size->max,
iv_range_size->increment)
- != 0) {
- printf("Unsupported IV length\n");
+ != 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+check_capabilities(struct l2fwd_crypto_options *options, uint8_t cdev_id)
+{
+ struct rte_cryptodev_info dev_info;
+ const struct rte_cryptodev_capabilities *cap;
+
+ rte_cryptodev_info_get(cdev_id, &dev_info);
+
+ /* Set AEAD parameters */
+ if (options->xform_chain == L2FWD_CRYPTO_AEAD) {
+ /* Check if device supports AEAD algo */
+ cap = check_device_support_aead_algo(options, &dev_info,
+ cdev_id);
+ if (cap == NULL)
+ return -1;
+
+ if (check_iv_param(&cap->sym.aead.iv_size,
+ options->aead_iv_param,
+ options->aead_iv_random_size,
+ options->aead_iv.length) != 0) {
+ RTE_LOG(DEBUG, USER1,
+ "Device %u does not support IV length\n",
+ cdev_id);
+ return -1;
+ }
+
+ /*
+ * Check if length of provided AEAD key is supported
+ * by the algorithm chosen.
+ */
+ if (options->aead_key_param) {
+ if (check_supported_size(
+ options->aead_xform.aead.key.length,
+ cap->sym.aead.key_size.min,
+ cap->sym.aead.key_size.max,
+ cap->sym.aead.key_size.increment)
+ != 0) {
+ RTE_LOG(DEBUG, USER1,
+ "Device %u does not support "
+ "AEAD key length\n",
+ cdev_id);
+ return -1;
+ }
+ /*
+ * Check if length of the aead key to be randomly generated
+ * is supported by the algorithm chosen.
+ */
+ } else if (options->aead_key_random_size != -1) {
+ if (check_supported_size(options->aead_key_random_size,
+ cap->sym.aead.key_size.min,
+ cap->sym.aead.key_size.max,
+ cap->sym.aead.key_size.increment)
+ != 0) {
+ RTE_LOG(DEBUG, USER1,
+ "Device %u does not support "
+ "AEAD key length\n",
+ cdev_id);
+ return -1;
+ }
+ }
+
+
+ /*
+ * Check if length of provided AAD is supported
+ * by the algorithm chosen.
+ */
+ if (options->aad_param) {
+ if (check_supported_size(options->aad.length,
+ cap->sym.aead.aad_size.min,
+ cap->sym.aead.aad_size.max,
+ cap->sym.aead.aad_size.increment)
+ != 0) {
+ RTE_LOG(DEBUG, USER1,
+ "Device %u does not support "
+ "AAD length\n",
+ cdev_id);
+ return -1;
+ }
+ /*
+ * Check if length of AAD to be randomly generated
+ * is supported by the algorithm chosen.
+ */
+ } else if (options->aad_random_size != -1) {
+ if (check_supported_size(options->aad_random_size,
+ cap->sym.aead.aad_size.min,
+ cap->sym.aead.aad_size.max,
+ cap->sym.aead.aad_size.increment)
+ != 0) {
+ RTE_LOG(DEBUG, USER1,
+ "Device %u does not support "
+ "AAD length\n",
+ cdev_id);
+ return -1;
+ }
+ }
+
+ /* Check if digest size is supported by the algorithm. */
+ if (options->digest_size != -1) {
+ if (check_supported_size(options->digest_size,
+ cap->sym.aead.digest_size.min,
+ cap->sym.aead.digest_size.max,
+ cap->sym.aead.digest_size.increment)
+ != 0) {
+ RTE_LOG(DEBUG, USER1,
+ "Device %u does not support "
+ "digest length\n",
+ cdev_id);
+ return -1;
+ }
+ }
+ }
+
+ /* Set cipher parameters */
+ if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH ||
+ options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER ||
+ options->xform_chain == L2FWD_CRYPTO_CIPHER_ONLY) {
+ /* Check if device supports cipher algo */
+ cap = check_device_support_cipher_algo(options, &dev_info,
+ cdev_id);
+ if (cap == NULL)
+ return -1;
+
+ if (check_iv_param(&cap->sym.cipher.iv_size,
+ options->cipher_iv_param,
+ options->cipher_iv_random_size,
+ options->cipher_iv.length) != 0) {
+ RTE_LOG(DEBUG, USER1,
+ "Device %u does not support IV length\n",
+ cdev_id);
+ return -1;
+ }
+
+ /*
+ * Check if length of provided cipher key is supported
+ * by the algorithm chosen.
+ */
+ if (options->ckey_param) {
+ if (check_supported_size(
+ options->cipher_xform.cipher.key.length,
+ cap->sym.cipher.key_size.min,
+ cap->sym.cipher.key_size.max,
+ cap->sym.cipher.key_size.increment)
+ != 0) {
+ RTE_LOG(DEBUG, USER1,
+ "Device %u does not support cipher "
+ "key length\n",
+ cdev_id);
+ return -1;
+ }
+ /*
+ * Check if length of the cipher key to be randomly generated
+ * is supported by the algorithm chosen.
+ */
+ } else if (options->ckey_random_size != -1) {
+ if (check_supported_size(options->ckey_random_size,
+ cap->sym.cipher.key_size.min,
+ cap->sym.cipher.key_size.max,
+ cap->sym.cipher.key_size.increment)
+ != 0) {
+ RTE_LOG(DEBUG, USER1,
+ "Device %u does not support cipher "
+ "key length\n",
+ cdev_id);
+ return -1;
+ }
+ }
+ }
+
+ /* Set auth parameters */
+ if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH ||
+ options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER ||
+ options->xform_chain == L2FWD_CRYPTO_HASH_ONLY) {
+ /* Check if device supports auth algo */
+ cap = check_device_support_auth_algo(options, &dev_info,
+ cdev_id);
+ if (cap == NULL)
return -1;
+
+ if (check_iv_param(&cap->sym.auth.iv_size,
+ options->auth_iv_param,
+ options->auth_iv_random_size,
+ options->auth_iv.length) != 0) {
+ RTE_LOG(DEBUG, USER1,
+ "Device %u does not support IV length\n",
+ cdev_id);
+ return -1;
+ }
+ /*
+ * Check if length of provided auth key is supported
+ * by the algorithm chosen.
+ */
+ if (options->akey_param) {
+ if (check_supported_size(
+ options->auth_xform.auth.key.length,
+ cap->sym.auth.key_size.min,
+ cap->sym.auth.key_size.max,
+ cap->sym.auth.key_size.increment)
+ != 0) {
+ RTE_LOG(DEBUG, USER1,
+ "Device %u does not support auth "
+ "key length\n",
+ cdev_id);
+ return -1;
+ }
+ /*
+ * Check if length of the auth key to be randomly generated
+ * is supported by the algorithm chosen.
+ */
+ } else if (options->akey_random_size != -1) {
+ if (check_supported_size(options->akey_random_size,
+ cap->sym.auth.key_size.min,
+ cap->sym.auth.key_size.max,
+ cap->sym.auth.key_size.increment)
+ != 0) {
+ RTE_LOG(DEBUG, USER1,
+ "Device %u does not support auth "
+ "key length\n",
+ cdev_id);
+ return -1;
+ }
+ }
+
+ /* Check if digest size is supported by the algorithm. */
+ if (options->digest_size != -1) {
+ if (check_supported_size(options->digest_size,
+ cap->sym.auth.digest_size.min,
+ cap->sym.auth.digest_size.max,
+ cap->sym.auth.digest_size.increment)
+ != 0) {
+ RTE_LOG(DEBUG, USER1,
+ "Device %u does not support "
+ "digest length\n",
+ cdev_id);
+ return -1;
+ }
}
- *iv_length = iv_random_size;
- /* No size provided, use minimum size. */
- } else
- *iv_length = iv_range_size->min;
+ }
return 0;
}
@@ -1970,9 +2205,10 @@ static int
initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
uint8_t *enabled_cdevs)
{
- unsigned int cdev_id, cdev_count, enabled_cdev_count = 0;
+ uint8_t cdev_id, cdev_count, enabled_cdev_count = 0;
const struct rte_cryptodev_capabilities *cap;
unsigned int sess_sz, max_sess_sz = 0;
+ uint32_t sessions_needed = 0;
int retval;
cdev_count = rte_cryptodev_count();
@@ -1981,16 +2217,31 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
return -1;
}
- for (cdev_id = 0; cdev_id < cdev_count; cdev_id++) {
+ for (cdev_id = 0; cdev_id < cdev_count && enabled_cdev_count < nb_ports;
+ cdev_id++) {
+ if (check_cryptodev_mask(options, cdev_id) < 0)
+ continue;
+
+ if (check_capabilities(options, cdev_id) < 0)
+ continue;
+
sess_sz = rte_cryptodev_sym_get_private_session_size(cdev_id);
if (sess_sz > max_sess_sz)
max_sess_sz = sess_sz;
+
+ l2fwd_enabled_crypto_mask |= (((uint64_t)1) << cdev_id);
+
+ enabled_cdevs[cdev_id] = 1;
+ enabled_cdev_count++;
}
- for (cdev_id = 0; cdev_id < cdev_count && enabled_cdev_count < nb_ports;
- cdev_id++) {
+ for (cdev_id = 0; cdev_id < cdev_count; cdev_id++) {
struct rte_cryptodev_qp_conf qp_conf;
struct rte_cryptodev_info dev_info;
+
+ if (enabled_cdevs[cdev_id] == 0)
+ continue;
+
retval = rte_cryptodev_socket_id(cdev_id);
if (retval < 0) {
@@ -2005,11 +2256,23 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
.socket_id = socket_id,
};
- if (check_cryptodev_mask(options, (uint8_t)cdev_id))
- continue;
-
rte_cryptodev_info_get(cdev_id, &dev_info);
+ /*
+ * Two sessions objects are required for each session
+ * (one for the header, one for the private data)
+ */
+ if (!strcmp(dev_info.driver_name, "crypto_scheduler")) {
+#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER
+ uint32_t nb_slaves =
+ rte_cryptodev_scheduler_slaves_get(cdev_id,
+ NULL);
+
+ sessions_needed = 2 * enabled_cdev_count * nb_slaves;
+#endif
+ } else
+ sessions_needed = 2 * enabled_cdev_count;
+
if (session_pool_socket[socket_id] == NULL) {
char mp_name[RTE_MEMPOOL_NAMESIZE];
struct rte_mempool *sess_mp;
@@ -2022,7 +2285,7 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
* device private data
*/
sess_mp = rte_mempool_create(mp_name,
- MAX_SESSIONS * 2,
+ sessions_needed,
max_sess_sz,
SESSION_POOL_CACHE_SIZE,
0, NULL, NULL, NULL,
@@ -2041,106 +2304,57 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
/* Set AEAD parameters */
if (options->xform_chain == L2FWD_CRYPTO_AEAD) {
- /* Check if device supports AEAD algo */
cap = check_device_support_aead_algo(options, &dev_info,
cdev_id);
- if (cap == NULL)
- continue;
options->block_size = cap->sym.aead.block_size;
- check_iv_param(&cap->sym.aead.iv_size,
- options->aead_iv_param,
- options->aead_iv_random_size,
- &options->aead_iv.length);
+ /* Set IV if not provided from command line */
+ if (options->aead_iv_param == 0) {
+ if (options->aead_iv_random_size != -1)
+ options->aead_iv.length =
+ options->aead_iv_random_size;
+ /* No size provided, use minimum size. */
+ else
+ options->aead_iv.length =
+ cap->sym.aead.iv_size.min;
+ }
- /*
- * Check if length of provided AEAD key is supported
- * by the algorithm chosen.
- */
- if (options->aead_key_param) {
- if (check_supported_size(
- options->aead_xform.aead.key.length,
- cap->sym.aead.key_size.min,
- cap->sym.aead.key_size.max,
- cap->sym.aead.key_size.increment)
- != 0) {
- printf("Unsupported aead key length\n");
- return -1;
- }
- /*
- * Check if length of the aead key to be randomly generated
- * is supported by the algorithm chosen.
- */
- } else if (options->aead_key_random_size != -1) {
- if (check_supported_size(options->aead_key_random_size,
- cap->sym.aead.key_size.min,
- cap->sym.aead.key_size.max,
- cap->sym.aead.key_size.increment)
- != 0) {
- printf("Unsupported aead key length\n");
- return -1;
- }
- options->aead_xform.aead.key.length =
- options->aead_key_random_size;
- /* No size provided, use minimum size. */
- } else
- options->aead_xform.aead.key.length =
+ /* Set key if not provided from command line */
+ if (options->aead_key_param == 0) {
+ if (options->aead_key_random_size != -1)
+ options->aead_xform.aead.key.length =
+ options->aead_key_random_size;
+ /* No size provided, use minimum size. */
+ else
+ options->aead_xform.aead.key.length =
cap->sym.aead.key_size.min;
- if (!options->aead_key_param)
generate_random_key(
options->aead_xform.aead.key.data,
options->aead_xform.aead.key.length);
+ }
- /*
- * Check if length of provided AAD is supported
- * by the algorithm chosen.
- */
- if (options->aad_param) {
- if (check_supported_size(options->aad.length,
- cap->sym.aead.aad_size.min,
- cap->sym.aead.aad_size.max,
- cap->sym.aead.aad_size.increment)
- != 0) {
- printf("Unsupported AAD length\n");
- return -1;
- }
- /*
- * Check if length of AAD to be randomly generated
- * is supported by the algorithm chosen.
- */
- } else if (options->aad_random_size != -1) {
- if (check_supported_size(options->aad_random_size,
- cap->sym.aead.aad_size.min,
- cap->sym.aead.aad_size.max,
- cap->sym.aead.aad_size.increment)
- != 0) {
- printf("Unsupported AAD length\n");
- return -1;
- }
- options->aad.length = options->aad_random_size;
- /* No size provided, use minimum size. */
- } else
- options->aad.length = cap->sym.auth.aad_size.min;
+ /* Set AAD if not provided from command line */
+ if (options->aad_param == 0) {
+ if (options->aad_random_size != -1)
+ options->aad.length =
+ options->aad_random_size;
+ /* No size provided, use minimum size. */
+ else
+ options->aad.length =
+ cap->sym.auth.aad_size.min;
+ }
options->aead_xform.aead.aad_length =
options->aad.length;
- /* Check if digest size is supported by the algorithm. */
- if (options->digest_size != -1) {
- if (check_supported_size(options->digest_size,
- cap->sym.aead.digest_size.min,
- cap->sym.aead.digest_size.max,
- cap->sym.aead.digest_size.increment)
- != 0) {
- printf("Unsupported digest length\n");
- return -1;
- }
+ /* Set digest size if not provided from command line */
+ if (options->digest_size != -1)
options->aead_xform.aead.digest_length =
options->digest_size;
- /* No size provided, use minimum size. */
- } else
+ /* No size provided, use minimum size. */
+ else
options->aead_xform.aead.digest_length =
cap->sym.aead.digest_size.min;
}
@@ -2149,127 +2363,76 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH ||
options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER ||
options->xform_chain == L2FWD_CRYPTO_CIPHER_ONLY) {
- /* Check if device supports cipher algo */
cap = check_device_support_cipher_algo(options, &dev_info,
cdev_id);
- if (cap == NULL)
- continue;
-
options->block_size = cap->sym.cipher.block_size;
- check_iv_param(&cap->sym.cipher.iv_size,
- options->cipher_iv_param,
- options->cipher_iv_random_size,
- &options->cipher_iv.length);
+ /* Set IV if not provided from command line */
+ if (options->cipher_iv_param == 0) {
+ if (options->cipher_iv_random_size != -1)
+ options->cipher_iv.length =
+ options->cipher_iv_random_size;
+ /* No size provided, use minimum size. */
+ else
+ options->cipher_iv.length =
+ cap->sym.cipher.iv_size.min;
+ }
- /*
- * Check if length of provided cipher key is supported
- * by the algorithm chosen.
- */
- if (options->ckey_param) {
- if (check_supported_size(
- options->cipher_xform.cipher.key.length,
- cap->sym.cipher.key_size.min,
- cap->sym.cipher.key_size.max,
- cap->sym.cipher.key_size.increment)
- != 0) {
- printf("Unsupported cipher key length\n");
- return -1;
- }
- /*
- * Check if length of the cipher key to be randomly generated
- * is supported by the algorithm chosen.
- */
- } else if (options->ckey_random_size != -1) {
- if (check_supported_size(options->ckey_random_size,
- cap->sym.cipher.key_size.min,
- cap->sym.cipher.key_size.max,
- cap->sym.cipher.key_size.increment)
- != 0) {
- printf("Unsupported cipher key length\n");
- return -1;
- }
- options->cipher_xform.cipher.key.length =
- options->ckey_random_size;
- /* No size provided, use minimum size. */
- } else
- options->cipher_xform.cipher.key.length =
+ /* Set key if not provided from command line */
+ if (options->ckey_param == 0) {
+ if (options->ckey_random_size != -1)
+ options->cipher_xform.cipher.key.length =
+ options->ckey_random_size;
+ /* No size provided, use minimum size. */
+ else
+ options->cipher_xform.cipher.key.length =
cap->sym.cipher.key_size.min;
- if (!options->ckey_param)
generate_random_key(
options->cipher_xform.cipher.key.data,
options->cipher_xform.cipher.key.length);
-
+ }
}
/* Set auth parameters */
if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH ||
options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER ||
options->xform_chain == L2FWD_CRYPTO_HASH_ONLY) {
- /* Check if device supports auth algo */
cap = check_device_support_auth_algo(options, &dev_info,
cdev_id);
- if (cap == NULL)
- continue;
- check_iv_param(&cap->sym.auth.iv_size,
- options->auth_iv_param,
- options->auth_iv_random_size,
- &options->auth_iv.length);
- /*
- * Check if length of provided auth key is supported
- * by the algorithm chosen.
- */
- if (options->akey_param) {
- if (check_supported_size(
- options->auth_xform.auth.key.length,
- cap->sym.auth.key_size.min,
- cap->sym.auth.key_size.max,
- cap->sym.auth.key_size.increment)
- != 0) {
- printf("Unsupported auth key length\n");
- return -1;
- }
- /*
- * Check if length of the auth key to be randomly generated
- * is supported by the algorithm chosen.
- */
- } else if (options->akey_random_size != -1) {
- if (check_supported_size(options->akey_random_size,
- cap->sym.auth.key_size.min,
- cap->sym.auth.key_size.max,
- cap->sym.auth.key_size.increment)
- != 0) {
- printf("Unsupported auth key length\n");
- return -1;
- }
- options->auth_xform.auth.key.length =
- options->akey_random_size;
- /* No size provided, use minimum size. */
- } else
- options->auth_xform.auth.key.length =
+ /* Set IV if not provided from command line */
+ if (options->auth_iv_param == 0) {
+ if (options->auth_iv_random_size != -1)
+ options->auth_iv.length =
+ options->auth_iv_random_size;
+ /* No size provided, use minimum size. */
+ else
+ options->auth_iv.length =
+ cap->sym.auth.iv_size.min;
+ }
+
+ /* Set key if not provided from command line */
+ if (options->akey_param == 0) {
+ if (options->akey_random_size != -1)
+ options->auth_xform.auth.key.length =
+ options->akey_random_size;
+ /* No size provided, use minimum size. */
+ else
+ options->auth_xform.auth.key.length =
cap->sym.auth.key_size.min;
- if (!options->akey_param)
generate_random_key(
options->auth_xform.auth.key.data,
options->auth_xform.auth.key.length);
+ }
- /* Check if digest size is supported by the algorithm. */
- if (options->digest_size != -1) {
- if (check_supported_size(options->digest_size,
- cap->sym.auth.digest_size.min,
- cap->sym.auth.digest_size.max,
- cap->sym.auth.digest_size.increment)
- != 0) {
- printf("Unsupported digest length\n");
- return -1;
- }
+ /* Set digest size if not provided from command line */
+ if (options->digest_size != -1)
options->auth_xform.auth.digest_length =
options->digest_size;
- /* No size provided, use minimum size. */
- } else
+ /* No size provided, use minimum size. */
+ else
options->auth_xform.auth.digest_length =
cap->sym.auth.digest_size.min;
}
@@ -2296,11 +2459,6 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
cdev_id, retval);
return -1;
}
-
- l2fwd_enabled_crypto_mask |= (((uint64_t)1) << cdev_id);
-
- enabled_cdevs[cdev_id] = 1;
- enabled_cdev_count++;
}
return enabled_cdev_count;
@@ -2371,7 +2529,6 @@ initialize_ports(struct l2fwd_crypto_options *options)
/* init one TX queue on each port */
fflush(stdout);
txq_conf = dev_info.default_txconf;
- txq_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
txq_conf.offloads = local_port_conf.txmode.offloads;
retval = rte_eth_tx_queue_setup(portid, 0, nb_txd,
rte_eth_dev_socket_id(portid),
diff --git a/examples/l2fwd-jobstats/main.c b/examples/l2fwd-jobstats/main.c
index 34553faa..af542338 100644
--- a/examples/l2fwd-jobstats/main.c
+++ b/examples/l2fwd-jobstats/main.c
@@ -90,7 +90,6 @@ struct rte_eth_dev_tx_buffer *tx_buffer[RTE_MAX_ETHPORTS];
static struct rte_eth_conf port_conf = {
.rxmode = {
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
.offloads = DEV_RX_OFFLOAD_CRC_STRIP,
},
.txmode = {
@@ -876,7 +875,6 @@ main(int argc, char **argv)
/* init one TX queue on each port */
txq_conf = dev_info.default_txconf;
- txq_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
txq_conf.offloads = local_port_conf.txmode.offloads;
fflush(stdout);
ret = rte_eth_tx_queue_setup(portid, 0, nb_txd,
diff --git a/examples/l2fwd-keepalive/main.c b/examples/l2fwd-keepalive/main.c
index a18b707c..2d8b4d1c 100644
--- a/examples/l2fwd-keepalive/main.c
+++ b/examples/l2fwd-keepalive/main.c
@@ -81,7 +81,6 @@ struct rte_eth_dev_tx_buffer *tx_buffer[RTE_MAX_ETHPORTS];
static struct rte_eth_conf port_conf = {
.rxmode = {
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
.offloads = DEV_RX_OFFLOAD_CRC_STRIP,
},
.txmode = {
@@ -671,7 +670,6 @@ main(int argc, char **argv)
/* init one TX queue on each port */
fflush(stdout);
txq_conf = dev_info.default_txconf;
- txq_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
txq_conf.offloads = local_port_conf.txmode.offloads;
ret = rte_eth_tx_queue_setup(portid, 0, nb_txd,
rte_eth_dev_socket_id(portid),
diff --git a/examples/l2fwd/main.c b/examples/l2fwd/main.c
index 69084357..9bb4c5bc 100644
--- a/examples/l2fwd/main.c
+++ b/examples/l2fwd/main.c
@@ -82,7 +82,6 @@ static struct rte_eth_dev_tx_buffer *tx_buffer[RTE_MAX_ETHPORTS];
static struct rte_eth_conf port_conf = {
.rxmode = {
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
.offloads = DEV_RX_OFFLOAD_CRC_STRIP,
},
.txmode = {
@@ -670,7 +669,6 @@ main(int argc, char **argv)
/* init one TX queue on each port */
fflush(stdout);
txq_conf = dev_info.default_txconf;
- txq_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
txq_conf.offloads = local_port_conf.txmode.offloads;
ret = rte_eth_tx_queue_setup(portid, 0, nb_txd,
rte_eth_dev_socket_id(portid),
diff --git a/examples/l3fwd-acl/main.c b/examples/l3fwd-acl/main.c
index 33ad467d..7c063a8d 100644
--- a/examples/l3fwd-acl/main.c
+++ b/examples/l3fwd-acl/main.c
@@ -127,7 +127,6 @@ static struct rte_eth_conf port_conf = {
.mq_mode = ETH_MQ_RX_RSS,
.max_rx_pkt_len = ETHER_MAX_LEN,
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
.offloads = (DEV_RX_OFFLOAD_CRC_STRIP |
DEV_RX_OFFLOAD_CHECKSUM),
},
@@ -1926,6 +1925,18 @@ main(int argc, char **argv)
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
local_port_conf.txmode.offloads |=
DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+ local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
+ dev_info.flow_type_rss_offloads;
+ if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
+ port_conf.rx_adv_conf.rss_conf.rss_hf) {
+ printf("Port %u modified RSS hash function based on hardware support,"
+ "requested:%#"PRIx64" configured:%#"PRIx64"\n",
+ portid,
+ port_conf.rx_adv_conf.rss_conf.rss_hf,
+ local_port_conf.rx_adv_conf.rss_conf.rss_hf);
+ }
+
ret = rte_eth_dev_configure(portid, nb_rx_queue,
(uint16_t)n_tx_queue, &local_port_conf);
if (ret < 0)
@@ -1982,7 +1993,6 @@ main(int argc, char **argv)
rte_eth_dev_info_get(portid, &dev_info);
txconf = &dev_info.default_txconf;
- txconf->txq_flags = ETH_TXQ_FLAGS_IGNORE;
txconf->offloads = local_port_conf.txmode.offloads;
ret = rte_eth_tx_queue_setup(portid, queueid, nb_txd,
socketid, txconf);
diff --git a/examples/l3fwd-power/Makefile b/examples/l3fwd-power/Makefile
index 390b7d6b..d7e39a34 100644
--- a/examples/l3fwd-power/Makefile
+++ b/examples/l3fwd-power/Makefile
@@ -1,11 +1,11 @@
# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2010-2014 Intel Corporation
+# Copyright(c) 2010-2018 Intel Corporation
# binary name
APP = l3fwd-power
# all source are stored in SRCS-y
-SRCS-y := main.c
+SRCS-y := main.c perf_core.c
# Build using pkg-config variables if possible
$(shell pkg-config --exists libdpdk)
@@ -48,7 +48,7 @@ RTE_TARGET ?= x86_64-native-linuxapp-gcc
include $(RTE_SDK)/mk/rte.vars.mk
-ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
$(info This application can only operate in a linuxapp environment, \
please change the definition of the RTE_TARGET environment variable)
all:
diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index 596d6454..d15cd520 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
+ * Copyright(c) 2010-2018 Intel Corporation
*/
#include <stdio.h>
@@ -44,6 +44,9 @@
#include <rte_power.h>
#include <rte_spinlock.h>
+#include "perf_core.h"
+#include "main.h"
+
#define RTE_LOGTYPE_L3FWD_POWER RTE_LOGTYPE_USER1
#define MAX_PKT_BURST 32
@@ -155,14 +158,7 @@ struct lcore_rx_queue {
#define MAX_RX_QUEUE_INTERRUPT_PER_PORT 16
-#define MAX_LCORE_PARAMS 1024
-struct lcore_params {
- uint16_t port_id;
- uint8_t queue_id;
- uint8_t lcore_id;
-} __rte_cache_aligned;
-
-static struct lcore_params lcore_params_array[MAX_LCORE_PARAMS];
+struct lcore_params lcore_params_array[MAX_LCORE_PARAMS];
static struct lcore_params lcore_params_array_default[] = {
{0, 0, 2},
{0, 1, 2},
@@ -175,8 +171,8 @@ static struct lcore_params lcore_params_array_default[] = {
{3, 1, 3},
};
-static struct lcore_params * lcore_params = lcore_params_array_default;
-static uint16_t nb_lcore_params = sizeof(lcore_params_array_default) /
+struct lcore_params *lcore_params = lcore_params_array_default;
+uint16_t nb_lcore_params = sizeof(lcore_params_array_default) /
sizeof(lcore_params_array_default[0]);
static struct rte_eth_conf port_conf = {
@@ -184,7 +180,6 @@ static struct rte_eth_conf port_conf = {
.mq_mode = ETH_MQ_RX_RSS,
.max_rx_pkt_len = ETHER_MAX_LEN,
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
.offloads = (DEV_RX_OFFLOAD_CRC_STRIP |
DEV_RX_OFFLOAD_CHECKSUM),
},
@@ -1121,10 +1116,15 @@ print_usage(const char *prgname)
{
printf ("%s [EAL options] -- -p PORTMASK -P"
" [--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"
" -p PORTMASK: hexadecimal bitmask of ports to configure\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"
@@ -1234,6 +1234,8 @@ parse_args(int argc, char **argv)
char *prgname = argv[0];
static struct option lgopts[] = {
{"config", 1, 0, 0},
+ {"perf-config", 1, 0, 0},
+ {"high-perf-cores", 1, 0, 0},
{"no-numa", 0, 0, 0},
{"enable-jumbo", 0, 0, 0},
{CMD_LINE_OPT_PARSE_PTYPE, 0, 0, 0},
@@ -1272,6 +1274,26 @@ parse_args(int argc, char **argv)
}
if (!strncmp(lgopts[option_index].name,
+ "perf-config", 11)) {
+ ret = parse_perf_config(optarg);
+ if (ret) {
+ printf("invalid perf-config\n");
+ print_usage(prgname);
+ return -1;
+ }
+ }
+
+ if (!strncmp(lgopts[option_index].name,
+ "high-perf-cores", 15)) {
+ ret = parse_perf_core_list(optarg);
+ if (ret) {
+ printf("invalid high-perf-cores\n");
+ print_usage(prgname);
+ return -1;
+ }
+ }
+
+ if (!strncmp(lgopts[option_index].name,
"no-numa", 7)) {
printf("numa is disabled \n");
numa_on = 0;
@@ -1609,6 +1631,23 @@ static int check_ptype(uint16_t portid)
}
+static int
+init_power_library(void)
+{
+ int ret = 0, lcore_id;
+ for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
+ if (rte_lcore_is_enabled(lcore_id)) {
+ /* init power management library */
+ ret = rte_power_init(lcore_id);
+ if (ret)
+ RTE_LOG(ERR, POWER,
+ "Library initialization failed on core %u\n",
+ lcore_id);
+ }
+ }
+ return ret;
+}
+
int
main(int argc, char **argv)
{
@@ -1643,6 +1682,12 @@ main(int argc, char **argv)
if (ret < 0)
rte_exit(EXIT_FAILURE, "Invalid L3FWD parameters\n");
+ if (init_power_library())
+ rte_exit(EXIT_FAILURE, "init_power_library failed\n");
+
+ if (update_lcore_params() < 0)
+ rte_exit(EXIT_FAILURE, "update_lcore_params failed\n");
+
if (check_lcore_params() < 0)
rte_exit(EXIT_FAILURE, "check_lcore_params failed\n");
@@ -1693,6 +1738,18 @@ main(int argc, char **argv)
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
local_port_conf.txmode.offloads |=
DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+ local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
+ dev_info.flow_type_rss_offloads;
+ if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
+ port_conf.rx_adv_conf.rss_conf.rss_hf) {
+ printf("Port %u modified RSS hash function based on hardware support,"
+ "requested:%#"PRIx64" configured:%#"PRIx64"\n",
+ portid,
+ port_conf.rx_adv_conf.rss_conf.rss_hf,
+ local_port_conf.rx_adv_conf.rss_conf.rss_hf);
+ }
+
ret = rte_eth_dev_configure(portid, nb_rx_queue,
(uint16_t)n_tx_queue, &local_port_conf);
if (ret < 0)
@@ -1750,7 +1807,6 @@ main(int argc, char **argv)
fflush(stdout);
txconf = &dev_info.default_txconf;
- txconf->txq_flags = ETH_TXQ_FLAGS_IGNORE;
txconf->offloads = local_port_conf.txmode.offloads;
ret = rte_eth_tx_queue_setup(portid, queueid, nb_txd,
socketid, txconf);
@@ -1773,12 +1829,6 @@ main(int argc, char **argv)
if (rte_lcore_is_enabled(lcore_id) == 0)
continue;
- /* init power management library */
- ret = rte_power_init(lcore_id);
- if (ret)
- RTE_LOG(ERR, POWER,
- "Library initialization failed on core %u\n", lcore_id);
-
/* init timer structures for each enabled lcore */
rte_timer_init(&power_timers[lcore_id]);
hz = rte_get_timer_hz();
diff --git a/examples/l3fwd-power/main.h b/examples/l3fwd-power/main.h
new file mode 100644
index 00000000..258de98f
--- /dev/null
+++ b/examples/l3fwd-power/main.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2018 Intel Corporation
+ */
+
+#ifndef _MAIN_H_
+#define _MAIN_H_
+
+
+#define MAX_LCORE_PARAMS 1024
+struct lcore_params {
+ uint16_t port_id;
+ uint8_t queue_id;
+ uint8_t lcore_id;
+} __rte_cache_aligned;
+
+extern struct lcore_params *lcore_params;
+extern uint16_t nb_lcore_params;
+extern struct lcore_params lcore_params_array[];
+
+#endif /* _MAIN_H_ */
diff --git a/examples/l3fwd-power/meson.build b/examples/l3fwd-power/meson.build
index f633a0f1..20c80543 100644
--- a/examples/l3fwd-power/meson.build
+++ b/examples/l3fwd-power/meson.build
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2017 Intel Corporation
+# Copyright(c) 2018 Intel Corporation
# meson file, for building this example as part of a main DPDK build.
#
@@ -11,5 +11,5 @@ if host_machine.system() != 'linux'
endif
deps += ['power', 'timer', 'lpm', 'hash']
sources = files(
- 'main.c'
+ 'main.c', 'perf_core.c'
)
diff --git a/examples/l3fwd-power/perf_core.c b/examples/l3fwd-power/perf_core.c
new file mode 100644
index 00000000..83948ea2
--- /dev/null
+++ b/examples/l3fwd-power/perf_core.c
@@ -0,0 +1,230 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2018 Intel Corporation
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <rte_common.h>
+#include <rte_memory.h>
+#include <rte_lcore.h>
+#include <rte_power.h>
+#include <rte_string_fns.h>
+
+#include "perf_core.h"
+#include "main.h"
+
+
+static uint16_t hp_lcores[RTE_MAX_LCORE];
+static uint16_t nb_hp_lcores;
+
+struct perf_lcore_params {
+ uint16_t port_id;
+ uint8_t queue_id;
+ uint8_t high_perf;
+ uint8_t lcore_idx;
+} __rte_cache_aligned;
+
+static struct perf_lcore_params prf_lc_prms[MAX_LCORE_PARAMS];
+static uint16_t nb_prf_lc_prms;
+
+int
+update_lcore_params(void)
+{
+ uint8_t non_perf_lcores[RTE_MAX_LCORE];
+ uint16_t nb_non_perf_lcores = 0;
+ int i, j, ret;
+
+ /* if perf-config option was not used do nothing */
+ if (nb_prf_lc_prms == 0)
+ return 0;
+
+ /* if high-perf-cores option was not used query every available core */
+ if (nb_hp_lcores == 0) {
+ for (i = 0; i < RTE_MAX_LCORE; i++) {
+ if (rte_lcore_is_enabled(i)) {
+ struct rte_power_core_capabilities caps;
+ ret = rte_power_get_capabilities(i, &caps);
+ if (ret == 0 && caps.turbo) {
+ hp_lcores[nb_hp_lcores] = i;
+ nb_hp_lcores++;
+ }
+ }
+ }
+ }
+
+ /* create a list on non high performance cores*/
+ for (i = 0; i < RTE_MAX_LCORE; i++) {
+ if (rte_lcore_is_enabled(i)) {
+ int hp = 0;
+ for (j = 0; j < nb_hp_lcores; j++) {
+ if (hp_lcores[j] == i) {
+ hp = 1;
+ break;
+ }
+ }
+ if (!hp)
+ non_perf_lcores[nb_non_perf_lcores++] = i;
+ }
+ }
+
+ /* update the lcore config */
+ for (i = 0; i < nb_prf_lc_prms; i++) {
+ int lcore = -1;
+ if (prf_lc_prms[i].high_perf) {
+ if (prf_lc_prms[i].lcore_idx < nb_hp_lcores)
+ lcore = hp_lcores[prf_lc_prms[i].lcore_idx];
+ } else {
+ if (prf_lc_prms[i].lcore_idx < nb_non_perf_lcores)
+ lcore =
+ non_perf_lcores[prf_lc_prms[i].lcore_idx];
+ }
+
+ if (lcore < 0) {
+ printf("Performance cores configuration error\n");
+ return -1;
+ }
+
+ lcore_params_array[i].lcore_id = lcore;
+ lcore_params_array[i].queue_id = prf_lc_prms[i].queue_id;
+ lcore_params_array[i].port_id = prf_lc_prms[i].port_id;
+ }
+
+ lcore_params = lcore_params_array;
+ nb_lcore_params = nb_prf_lc_prms;
+
+ printf("Updated performance core configuration\n");
+ for (i = 0; i < nb_prf_lc_prms; i++)
+ printf("\t(%d,%d,%d)\n", lcore_params[i].port_id,
+ lcore_params[i].queue_id,
+ lcore_params[i].lcore_id);
+
+ return 0;
+}
+
+int
+parse_perf_config(const char *q_arg)
+{
+ char s[256];
+ const char *p, *p0 = q_arg;
+ char *end;
+ enum fieldnames {
+ FLD_PORT = 0,
+ FLD_QUEUE,
+ FLD_LCORE_HP,
+ FLD_LCORE_IDX,
+ _NUM_FLD
+ };
+ unsigned long int_fld[_NUM_FLD];
+ char *str_fld[_NUM_FLD];
+ int i;
+ unsigned int size;
+
+ nb_prf_lc_prms = 0;
+
+ while ((p = strchr(p0, '(')) != NULL) {
+ ++p;
+ p0 = strchr(p, ')');
+ if (p0 == NULL)
+ return -1;
+
+ size = p0 - p;
+ if (size >= sizeof(s))
+ return -1;
+
+ snprintf(s, sizeof(s), "%.*s", size, p);
+ if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') !=
+ _NUM_FLD)
+ return -1;
+ for (i = 0; i < _NUM_FLD; i++) {
+ errno = 0;
+ int_fld[i] = strtoul(str_fld[i], &end, 0);
+ if (errno != 0 || end == str_fld[i] || int_fld[i] > 255)
+ return -1;
+ }
+ if (nb_prf_lc_prms >= MAX_LCORE_PARAMS) {
+ printf("exceeded max number of lcore params: %hu\n",
+ nb_prf_lc_prms);
+ return -1;
+ }
+ prf_lc_prms[nb_prf_lc_prms].port_id =
+ (uint8_t)int_fld[FLD_PORT];
+ prf_lc_prms[nb_prf_lc_prms].queue_id =
+ (uint8_t)int_fld[FLD_QUEUE];
+ prf_lc_prms[nb_prf_lc_prms].high_perf =
+ !!(uint8_t)int_fld[FLD_LCORE_HP];
+ prf_lc_prms[nb_prf_lc_prms].lcore_idx =
+ (uint8_t)int_fld[FLD_LCORE_IDX];
+ ++nb_prf_lc_prms;
+ }
+
+ return 0;
+}
+
+int
+parse_perf_core_list(const char *corelist)
+{
+ int i, idx = 0;
+ unsigned int count = 0;
+ char *end = NULL;
+ int min, max;
+
+ if (corelist == NULL) {
+ printf("invalid core list\n");
+ return -1;
+ }
+
+
+ /* Remove all blank characters ahead and after */
+ while (isblank(*corelist))
+ corelist++;
+ i = strlen(corelist);
+ while ((i > 0) && isblank(corelist[i - 1]))
+ i--;
+
+ /* Get list of cores */
+ min = RTE_MAX_LCORE;
+ do {
+ while (isblank(*corelist))
+ corelist++;
+ if (*corelist == '\0')
+ return -1;
+ errno = 0;
+ idx = strtoul(corelist, &end, 10);
+ if (errno || end == NULL)
+ return -1;
+ while (isblank(*end))
+ end++;
+ if (*end == '-') {
+ min = idx;
+ } else if ((*end == ',') || (*end == '\0')) {
+ max = idx;
+ if (min == RTE_MAX_LCORE)
+ min = idx;
+ for (idx = min; idx <= max; idx++) {
+ hp_lcores[count] = idx;
+ count++;
+ }
+ min = RTE_MAX_LCORE;
+ } else {
+ printf("invalid core list\n");
+ return -1;
+ }
+ corelist = end + 1;
+ } while (*end != '\0');
+
+ if (count == 0) {
+ printf("invalid core list\n");
+ return -1;
+ }
+
+ nb_hp_lcores = count;
+
+ printf("Configured %d high performance cores\n", nb_hp_lcores);
+ for (i = 0; i < nb_hp_lcores; i++)
+ printf("\tHigh performance core %d %d\n",
+ i, hp_lcores[i]);
+
+ return 0;
+}
+
diff --git a/examples/l3fwd-power/perf_core.h b/examples/l3fwd-power/perf_core.h
new file mode 100644
index 00000000..7b7b747b
--- /dev/null
+++ b/examples/l3fwd-power/perf_core.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2018 Intel Corporation
+ */
+
+#ifndef _PERF_CORE_H_
+#define _PERF_CORE_H_
+
+int parse_perf_config(const char *q_arg);
+int parse_perf_core_list(const char *corelist);
+int update_lcore_params(void);
+
+#endif /* _PERF_CORE_H_ */
diff --git a/examples/l3fwd-vf/main.c b/examples/l3fwd-vf/main.c
index aaafb7bc..5edd91a7 100644
--- a/examples/l3fwd-vf/main.c
+++ b/examples/l3fwd-vf/main.c
@@ -161,7 +161,6 @@ static struct rte_eth_conf port_conf = {
.mq_mode = ETH_MQ_RX_RSS,
.max_rx_pkt_len = ETHER_MAX_LEN,
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
.offloads = (DEV_RX_OFFLOAD_CRC_STRIP |
DEV_RX_OFFLOAD_CHECKSUM),
},
@@ -981,6 +980,18 @@ main(int argc, char **argv)
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
local_port_conf.txmode.offloads |=
DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+ local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
+ dev_info.flow_type_rss_offloads;
+ if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
+ port_conf.rx_adv_conf.rss_conf.rss_hf) {
+ printf("Port %u modified RSS hash function based on hardware support,"
+ "requested:%#"PRIx64" configured:%#"PRIx64"\n",
+ portid,
+ port_conf.rx_adv_conf.rss_conf.rss_hf,
+ local_port_conf.rx_adv_conf.rss_conf.rss_hf);
+ }
+
ret = rte_eth_dev_configure(portid, nb_rx_queue,
n_tx_queue, &local_port_conf);
if (ret < 0)
@@ -1009,7 +1020,6 @@ main(int argc, char **argv)
fflush(stdout);
txconf = &dev_info.default_txconf;
- txconf->txq_flags = ETH_TXQ_FLAGS_IGNORE;
txconf->offloads = local_port_conf.txmode.offloads;
ret = rte_eth_tx_queue_setup(portid, 0, nb_txd,
socketid, txconf);
diff --git a/examples/l3fwd/l3fwd_em.c b/examples/l3fwd/l3fwd_em.c
index 9dc3b8c4..fa8f82be 100644
--- a/examples/l3fwd/l3fwd_em.c
+++ b/examples/l3fwd/l3fwd_em.c
@@ -18,7 +18,6 @@
#include <rte_debug.h>
#include <rte_ether.h>
#include <rte_ethdev.h>
-#include <rte_mempool.h>
#include <rte_cycles.h>
#include <rte_mbuf.h>
#include <rte_ip.h>
diff --git a/examples/l3fwd/l3fwd_lpm.c b/examples/l3fwd/l3fwd_lpm.c
index a747126a..b1dc195a 100644
--- a/examples/l3fwd/l3fwd_lpm.c
+++ b/examples/l3fwd/l3fwd_lpm.c
@@ -17,7 +17,6 @@
#include <rte_debug.h>
#include <rte_ether.h>
#include <rte_ethdev.h>
-#include <rte_mempool.h>
#include <rte_cycles.h>
#include <rte_mbuf.h>
#include <rte_ip.h>
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index bf7dbd81..ab019b9e 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -120,7 +120,6 @@ static struct rte_eth_conf port_conf = {
.mq_mode = ETH_MQ_RX_RSS,
.max_rx_pkt_len = ETHER_MAX_LEN,
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
.offloads = (DEV_RX_OFFLOAD_CRC_STRIP |
DEV_RX_OFFLOAD_CHECKSUM),
},
@@ -861,6 +860,18 @@ main(int argc, char **argv)
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
local_port_conf.txmode.offloads |=
DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+ local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
+ dev_info.flow_type_rss_offloads;
+ if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
+ port_conf.rx_adv_conf.rss_conf.rss_hf) {
+ printf("Port %u modified RSS hash function based on hardware support,"
+ "requested:%#"PRIx64" configured:%#"PRIx64"\n",
+ portid,
+ port_conf.rx_adv_conf.rss_conf.rss_hf,
+ local_port_conf.rx_adv_conf.rss_conf.rss_hf);
+ }
+
ret = rte_eth_dev_configure(portid, nb_rx_queue,
(uint16_t)n_tx_queue, &local_port_conf);
if (ret < 0)
@@ -909,7 +920,6 @@ main(int argc, char **argv)
fflush(stdout);
txconf = &dev_info.default_txconf;
- txconf->txq_flags = ETH_TXQ_FLAGS_IGNORE;
txconf->offloads = local_port_conf.txmode.offloads;
ret = rte_eth_tx_queue_setup(portid, queueid, nb_txd,
socketid, txconf);
diff --git a/examples/link_status_interrupt/main.c b/examples/link_status_interrupt/main.c
index f5689568..3b732076 100644
--- a/examples/link_status_interrupt/main.c
+++ b/examples/link_status_interrupt/main.c
@@ -79,7 +79,6 @@ struct rte_eth_dev_tx_buffer *tx_buffer[RTE_MAX_ETHPORTS];
static struct rte_eth_conf port_conf = {
.rxmode = {
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
.offloads = DEV_RX_OFFLOAD_CRC_STRIP,
},
.txmode = {
@@ -653,7 +652,6 @@ main(int argc, char **argv)
/* init one TX queue logical core on each port */
fflush(stdout);
txq_conf = dev_info.default_txconf;
- txq_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
txq_conf.offloads = local_port_conf.txmode.offloads;
ret = rte_eth_tx_queue_setup(portid, 0, nb_txd,
rte_eth_dev_socket_id(portid),
diff --git a/examples/load_balancer/init.c b/examples/load_balancer/init.c
index 8d8dbe61..f2045f23 100644
--- a/examples/load_balancer/init.c
+++ b/examples/load_balancer/init.c
@@ -45,7 +45,6 @@ static struct rte_eth_conf port_conf = {
.rxmode = {
.mq_mode = ETH_MQ_RX_RSS,
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
.offloads = (DEV_RX_OFFLOAD_CHECKSUM |
DEV_RX_OFFLOAD_CRC_STRIP),
},
@@ -417,6 +416,18 @@ app_init_nics(void)
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
local_port_conf.txmode.offloads |=
DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+ local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
+ dev_info.flow_type_rss_offloads;
+ if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
+ port_conf.rx_adv_conf.rss_conf.rss_hf) {
+ printf("Port %u modified RSS hash function based on hardware support,"
+ "requested:%#"PRIx64" configured:%#"PRIx64"\n",
+ port,
+ port_conf.rx_adv_conf.rss_conf.rss_hf,
+ local_port_conf.rx_adv_conf.rss_conf.rss_hf);
+ }
+
ret = rte_eth_dev_configure(
port,
(uint8_t) n_rx_queues,
@@ -466,7 +477,6 @@ app_init_nics(void)
}
txq_conf = dev_info.default_txconf;
- txq_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
txq_conf.offloads = local_port_conf.txmode.offloads;
/* Init TX queues */
if (app.nic_tx_port_mask[port] == 1) {
diff --git a/examples/meson.build b/examples/meson.build
index 3d156849..4ee7a111 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -18,12 +18,17 @@ else
examples = get_option('examples').split(',')
allow_skips = false # error out if we can't build a requested app
endif
+default_cflags = machine_args
+if cc.has_argument('-Wno-format-truncation')
+ default_cflags += '-Wno-format-truncation'
+endif
foreach example: examples
name = example
build = true
sources = []
allow_experimental_apis = false
- cflags = machine_args
+ cflags = default_cflags
+
ext_deps = [execinfo]
includes = [include_directories(example)]
deps = ['eal', 'mempool', 'net', 'mbuf', 'ethdev', 'cmdline']
diff --git a/examples/multi_process/client_server_mp/mp_server/Makefile b/examples/multi_process/client_server_mp/mp_server/Makefile
index af7246e6..9c1caae7 100644
--- a/examples/multi_process/client_server_mp/mp_server/Makefile
+++ b/examples/multi_process/client_server_mp/mp_server/Makefile
@@ -10,7 +10,7 @@ RTE_TARGET ?= x86_64-native-linuxapp-gcc
include $(RTE_SDK)/mk/rte.vars.mk
-ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
$(error This application can only operate in a linuxapp environment, \
please change the definition of the RTE_TARGET environment variable)
endif
diff --git a/examples/multi_process/l2fwd_fork/Makefile b/examples/multi_process/l2fwd_fork/Makefile
deleted file mode 100644
index b65582ef..00000000
--- a/examples/multi_process/l2fwd_fork/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2010-2014 Intel Corporation
-
-# binary name
-APP = l2fwd-fork
-
-# all source are stored in SRCS-y
-SRCS-y := main.c flib.c
-
-ifeq ($(RTE_SDK),)
-$(error "Please define RTE_SDK environment variable")
-endif
-
-# Default target, can be overridden by command line or environment
-RTE_TARGET ?= x86_64-native-linuxapp-gcc
-
-include $(RTE_SDK)/mk/rte.vars.mk
-
-CFLAGS += -O3
-CFLAGS += $(WERROR_FLAGS)
-
-include $(RTE_SDK)/mk/rte.extapp.mk
diff --git a/examples/multi_process/l2fwd_fork/flib.c b/examples/multi_process/l2fwd_fork/flib.c
deleted file mode 100644
index 52c6152b..00000000
--- a/examples/multi_process/l2fwd_fork/flib.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/wait.h>
-#include <sys/prctl.h>
-#include <netinet/in.h>
-#include <setjmp.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <errno.h>
-#include <getopt.h>
-#include <dirent.h>
-#include <signal.h>
-
-#include <rte_common.h>
-#include <rte_log.h>
-#include <rte_malloc.h>
-#include <rte_memory.h>
-#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>
-#include <rte_per_lcore.h>
-#include <rte_branch_prediction.h>
-#include <rte_interrupts.h>
-#include <rte_random.h>
-#include <rte_debug.h>
-#include <rte_ether.h>
-#include <rte_ethdev.h>
-#include <rte_mempool.h>
-#include <rte_mbuf.h>
-#include <rte_string_fns.h>
-
-#include "flib.h"
-
-#define SIG_PARENT_EXIT SIGUSR1
-
-struct lcore_stat {
- pid_t pid; /**< pthread identifier */
- lcore_function_t *f; /**< function to call */
- void *arg; /**< argument of function */
- slave_exit_notify *cb_fn;
-} __rte_cache_aligned;
-
-
-static struct lcore_stat *core_cfg;
-static uint16_t *lcore_cfg = NULL;
-
-/* signal handler to be notified after parent leaves */
-static void
-sighand_parent_exit(int sig)
-{
- printf("lcore = %u : Find parent leaves, sig=%d\n", rte_lcore_id(),
- sig);
- printf("Child leaving\n");
- exit(0);
-
- return;
-}
-
-/**
- * Real function entrance ran in slave process
- **/
-static int
-slave_proc_func(void)
-{
- struct rte_config *config;
- unsigned slave_id = rte_lcore_id();
- struct lcore_stat *cfg = &core_cfg[slave_id];
-
- if (prctl(PR_SET_PDEATHSIG, SIG_PARENT_EXIT, 0, 0, 0, 0) != 0)
- printf("Warning: Slave can't register for being notified in"
- "case master process exited\n");
- else {
- struct sigaction act;
- memset(&act, 0 , sizeof(act));
- act.sa_handler = sighand_parent_exit;
- if (sigaction(SIG_PARENT_EXIT, &act, NULL) != 0)
- printf("Fail to register signal handler:%d\n", SIG_PARENT_EXIT);
- }
-
- /* Set slave process to SECONDARY to avoid operation like dev_start/stop etc */
- config = rte_eal_get_configuration();
- if (NULL == config)
- printf("Warning:Can't get rte_config\n");
- else
- config->process_type = RTE_PROC_SECONDARY;
-
- printf("Core %u is ready (pid=%d)\n", slave_id, (int)cfg->pid);
-
- exit(cfg->f(cfg->arg));
-}
-
-/**
- * function entrance ran in master thread, which will spawn slave process and wait until
- * specific slave exited.
- **/
-static int
-lcore_func(void *arg __attribute__((unused)))
-{
- unsigned slave_id = rte_lcore_id();
- struct lcore_stat *cfg = &core_cfg[slave_id];
- int pid, stat;
-
- if (rte_get_master_lcore() == slave_id)
- return cfg->f(cfg->arg);
-
- /* fork a slave process */
- pid = fork();
-
- if (pid == -1) {
- printf("Failed to fork\n");
- return -1;
- } else if (pid == 0) /* child */
- return slave_proc_func();
- else { /* parent */
- cfg->pid = pid;
-
- waitpid(pid, &stat, 0);
-
- cfg->pid = 0;
- cfg->f = NULL;
- cfg->arg = NULL;
- /* Notify slave's exit if applicable */
- if(cfg->cb_fn)
- cfg->cb_fn(slave_id, stat);
- return stat;
- }
-}
-
-static int
-lcore_id_init(void)
-{
- int i;
- /* Setup lcore ID allocation map */
- lcore_cfg = rte_zmalloc("LCORE_ID_MAP",
- sizeof(uint16_t) * RTE_MAX_LCORE,
- RTE_CACHE_LINE_SIZE);
-
- if(lcore_cfg == NULL)
- rte_panic("Failed to malloc\n");
-
- for (i = 0; i < RTE_MAX_LCORE; i++) {
- if (rte_lcore_is_enabled(i))
- lcore_cfg[i] = 1;
- }
- return 0;
-}
-
-int
-flib_assign_lcore_id(void)
-{
- unsigned i;
- int ret;
-
- /**
- * thread assigned a lcore id previously, or a slave thread. But still have
- * a bug here: If the core mask includes core 0, and that core call this
- * function, it still can get a new lcore id.
- **/
- if (rte_lcore_id() != 0)
- return -1;
-
- do {
- /* Find a lcore id not used yet, avoid to use lcore ID 0 */
- for (i = 1; i < RTE_MAX_LCORE; i++) {
- if (lcore_cfg[i] == 0)
- break;
- }
- if (i == RTE_MAX_LCORE)
- return -1;
-
- /* Assign new lcore id to this thread */
-
- ret = rte_atomic16_cmpset(&lcore_cfg[i], 0, 1);
- } while (unlikely(ret == 0));
-
- RTE_PER_LCORE(_lcore_id) = i;
- return i;
-}
-
-void
-flib_free_lcore_id(unsigned lcore_id)
-{
- /* id is not valid or belongs to pinned core id */
- if (lcore_id >= RTE_MAX_LCORE || lcore_id == 0 ||
- rte_lcore_is_enabled(lcore_id))
- return;
-
- lcore_cfg[lcore_id] = 0;
-}
-
-int
-flib_register_slave_exit_notify(unsigned slave_id,
- slave_exit_notify *cb)
-{
- if (cb == NULL)
- return -EFAULT;
-
- if (!rte_lcore_is_enabled(slave_id))
- return -ENOENT;
-
- core_cfg[slave_id].cb_fn = cb;
-
- return 0;
-}
-
-enum slave_stat
-flib_query_slave_status(unsigned slave_id)
-{
- if (!rte_lcore_is_enabled(slave_id))
- return ST_FREEZE;
- /* pid only be set when slave process spawned */
- if (core_cfg[slave_id].pid != 0)
- return ST_RUN;
- else
- return ST_IDLE;
-}
-
-int
-flib_remote_launch(lcore_function_t *f,
- void *arg, unsigned slave_id)
-{
- if (f == NULL)
- return -1;
-
- if (!rte_lcore_is_enabled(slave_id))
- return -1;
-
- /* Wait until specific lcore state change to WAIT */
- rte_eal_wait_lcore(slave_id);
-
- core_cfg[slave_id].f = f;
- core_cfg[slave_id].arg = arg;
-
- return rte_eal_remote_launch(lcore_func, NULL, slave_id);
-}
-
-int
-flib_mp_remote_launch(lcore_function_t *f, void *arg,
- enum rte_rmt_call_master_t call_master)
-{
- int i;
-
- RTE_LCORE_FOREACH_SLAVE(i) {
- core_cfg[i].arg = arg;
- core_cfg[i].f = f;
- }
-
- return rte_eal_mp_remote_launch(lcore_func, NULL, call_master);
-}
-
-int
-flib_init(void)
-{
- if ((core_cfg = rte_zmalloc("core_cfg",
- sizeof(struct lcore_stat) * RTE_MAX_LCORE,
- RTE_CACHE_LINE_SIZE)) == NULL ) {
- printf("rte_zmalloc failed\n");
- return -1;
- }
-
- if (lcore_id_init() != 0) {
- printf("lcore_id_init failed\n");
- return -1;
- }
-
- return 0;
-}
diff --git a/examples/multi_process/l2fwd_fork/flib.h b/examples/multi_process/l2fwd_fork/flib.h
deleted file mode 100644
index 8bc13a1f..00000000
--- a/examples/multi_process/l2fwd_fork/flib.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __FLIB_H
-#define __FLIB_H
-
-/* callback function pointer when specific slave leaves */
-typedef void (slave_exit_notify)(unsigned slaveid, int stat);
-
-enum slave_stat{
- ST_FREEZE = 1,
- ST_IDLE,
- ST_RUN,
- ST_ZOMBIE, /* Not implemented yet */
-};
-
-/**
- * Initialize the fork lib.
- *
- * @return
- * - 0 : fork lib initialized successfully
- * - -1 : fork lib initialized failed
- */
-int flib_init(void);
-
-/**
- * Check that every SLAVE lcores are in WAIT state, then call
- * flib_remote_launch() for all of them. If call_master is true
- * (set to CALL_MASTER), also call the function on the master lcore.
- *
- * @param f:
- * function pointer need to run
- * @param arg:
- * argument for f to carry
- * @param call_master
- * - SKIP_MASTER : only launch function on slave lcores
- * - CALL_MASTER : launch function on master and slave lcores
- * @return
- * - 0 : function execute successfully
- * - -1 : function execute failed
- */
-int flib_mp_remote_launch(lcore_function_t *f,
- void *arg, enum rte_rmt_call_master_t call_master);
-
-/**
- * Send a message to a slave lcore identified by slave_id to call a
- * function f with argument arg.
- *
- * @param f:
- * function pointer need to run
- * @param arg:
- * argument for f to carry
- * @param slave_id
- * slave lcore id to run on
- * @return
- * - 0 : function execute successfully
- * - -1 : function execute failed
- */
-int flib_remote_launch(lcore_function_t *f,
- void *arg, unsigned slave_id);
-
-/**
- * Query the running stat for specific slave, wont' work in with master id
- *
- * @param slave_id:
- * lcore id which should not be master id
- * @return
- * - ST_FREEZE : lcore is not in enabled core mask
- * - ST_IDLE : lcore is idle
- * - ST_RUN : lcore is running something
- */
-enum slave_stat
-flib_query_slave_status(unsigned slave_id);
-
-/**
- * Register a callback function to be notified in case specific slave exit.
- *
- * @param slave_id:
- * lcore id which should not be master id
- * @param cb:
- * callback pointer to register
- * @return
- * - 0 : function execute successfully
- * - -EFAULT : argument error
- * - -ENOENT : slave_id not correct
- */
-int flib_register_slave_exit_notify(unsigned slave_id,
- slave_exit_notify *cb);
-
-/**
- * Assign a lcore ID to non-slave thread. Non-slave thread refers to thread that
- * not created by function rte_eal_remote_launch or rte_eal_mp_remote_launch.
- * These threads can either bind lcore or float among different lcores.
- * This lcore ID will be unique in multi-thread or multi-process DPDK running
- * environment, then it can benefit from using the cache mechanism provided in
- * mempool library.
- * After calling successfully, use rte_lcore_id() to get the assigned lcore ID, but
- * other lcore funtions can't guarantee to work correctly.
- *
- * @return
- * - -1 : can't assign a lcore id with 3 possibilities.
- * - it's not non-slave thread.
- * - it had assign a lcore id previously
- * - the lcore id is running out.
- * - > 0 : the assigned lcore id.
- */
-int flib_assign_lcore_id(void);
-
-/**
- * Free the lcore_id that assigned in flib_assign_lcore_id().
- * call it in case non-slave thread is leaving or left.
- *
- * @param lcore_id
- * The identifier of the lcore, which MUST be between 1 and
- * RTE_MAX_LCORE-1.
- */
-void flib_free_lcore_id(unsigned lcore_id);
-
-#endif /* __FLIB_H */
diff --git a/examples/multi_process/l2fwd_fork/main.c b/examples/multi_process/l2fwd_fork/main.c
deleted file mode 100644
index 94318ab6..00000000
--- a/examples/multi_process/l2fwd_fork/main.c
+++ /dev/null
@@ -1,1259 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdint.h>
-#include <sched.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <netinet/in.h>
-#include <setjmp.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include <rte_common.h>
-#include <rte_log.h>
-#include <rte_memory.h>
-#include <rte_memcpy.h>
-#include <rte_eal.h>
-#include <rte_launch.h>
-#include <rte_atomic.h>
-#include <rte_spinlock.h>
-#include <rte_cycles.h>
-#include <rte_prefetch.h>
-#include <rte_lcore.h>
-#include <rte_per_lcore.h>
-#include <rte_branch_prediction.h>
-#include <rte_interrupts.h>
-#include <rte_random.h>
-#include <rte_debug.h>
-#include <rte_ether.h>
-#include <rte_ethdev.h>
-#include <rte_ring.h>
-#include <rte_mempool.h>
-#include <rte_mbuf.h>
-#include <rte_malloc.h>
-
-#include "flib.h"
-
-#define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1
-#define MBUF_NAME "mbuf_pool_%d"
-#define MBUF_DATA_SIZE RTE_MBUF_DEFAULT_BUF_SIZE
-#define NB_MBUF 8192
-#define RING_MASTER_NAME "l2fwd_ring_m2s_"
-#define RING_SLAVE_NAME "l2fwd_ring_s2m_"
-#define MAX_NAME_LEN 32
-/* RECREATE flag indicate needs initialize resource and launch slave_core again */
-#define SLAVE_RECREATE_FLAG 0x1
-/* RESTART flag indicate needs restart port and send START command again */
-#define SLAVE_RESTART_FLAG 0x2
-#define INVALID_MAPPING_ID ((unsigned)LCORE_ID_ANY)
-/* Maximum message buffer per slave */
-#define NB_CORE_MSGBUF 32
-enum l2fwd_cmd{
- CMD_START,
- CMD_STOP,
-};
-
-#define MAX_PKT_BURST 32
-#define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */
-
-/*
- * Configurable number of RX/TX ring descriptors
- */
-#define RTE_TEST_RX_DESC_DEFAULT 1024
-#define RTE_TEST_TX_DESC_DEFAULT 1024
-static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT;
-static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT;
-
-/* ethernet addresses of ports */
-static struct ether_addr l2fwd_ports_eth_addr[RTE_MAX_ETHPORTS];
-
-/* mask of enabled ports */
-static uint32_t l2fwd_enabled_port_mask = 0;
-
-/* list of enabled ports */
-static uint32_t l2fwd_dst_ports[RTE_MAX_ETHPORTS];
-
-static unsigned int l2fwd_rx_queue_per_lcore = 1;
-
-struct mbuf_table {
- unsigned len;
- struct rte_mbuf *m_table[MAX_PKT_BURST];
-};
-
-#define MAX_RX_QUEUE_PER_LCORE 16
-#define MAX_TX_QUEUE_PER_PORT 16
-struct lcore_queue_conf {
- unsigned n_rx_port;
- unsigned rx_port_list[MAX_RX_QUEUE_PER_LCORE];
-} __rte_cache_aligned;
-struct lcore_queue_conf lcore_queue_conf[RTE_MAX_LCORE];
-
-struct rte_eth_dev_tx_buffer *tx_buffer[RTE_MAX_ETHPORTS];
-
-struct lcore_resource_struct {
- int enabled; /* Only set in case this lcore involved into packet forwarding */
- int flags; /* Set only slave need to restart or recreate */
- unsigned lcore_id; /* lcore ID */
- unsigned pair_id; /* dependency lcore ID on port */
- char ring_name[2][MAX_NAME_LEN];
- /* ring[0] for master send cmd, slave read */
- /* ring[1] for slave send ack, master read */
- struct rte_ring *ring[2];
- int port_num; /* Total port numbers */
- /* Port id for that lcore to receive packets */
- uint16_t port[RTE_MAX_ETHPORTS];
-}__attribute__((packed)) __rte_cache_aligned;
-
-static struct lcore_resource_struct lcore_resource[RTE_MAX_LCORE];
-static struct rte_mempool *message_pool;
-static rte_spinlock_t res_lock = RTE_SPINLOCK_INITIALIZER;
-/* use floating processes */
-static int float_proc = 0;
-/* Save original cpu affinity */
-struct cpu_aff_arg{
- cpu_set_t set;
- size_t size;
-}cpu_aff;
-
-static const struct rte_eth_conf port_conf = {
- .rxmode = {
- .split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
- .offloads = DEV_RX_OFFLOAD_CRC_STRIP,
- },
- .txmode = {
- .mq_mode = ETH_MQ_TX_NONE,
- },
-};
-
-static struct rte_mempool * l2fwd_pktmbuf_pool[RTE_MAX_ETHPORTS];
-
-/* Per-port statistics struct */
-struct l2fwd_port_statistics {
- uint64_t tx;
- uint64_t rx;
- uint64_t dropped;
-} __rte_cache_aligned;
-struct l2fwd_port_statistics *port_statistics;
-/**
- * pointer to lcore ID mapping array, used to return lcore id in case slave
- * process exited unexpectedly, use only floating process option applied
- **/
-unsigned *mapping_id;
-
-/* A tsc-based timer responsible for triggering statistics printout */
-#define TIMER_MILLISECOND 2000000ULL /* around 1ms at 2 Ghz */
-#define MAX_TIMER_PERIOD 86400 /* 1 day max */
-static int64_t timer_period = 10 * TIMER_MILLISECOND * 1000; /* default period is 10 seconds */
-
-static int l2fwd_launch_one_lcore(void *dummy);
-
-/* Print out statistics on packets dropped */
-static void
-print_stats(void)
-{
- uint64_t total_packets_dropped, total_packets_tx, total_packets_rx;
- unsigned portid;
-
- total_packets_dropped = 0;
- total_packets_tx = 0;
- total_packets_rx = 0;
-
- const char clr[] = { 27, '[', '2', 'J', '\0' };
- const char topLeft[] = { 27, '[', '1', ';', '1', 'H','\0' };
-
- /* Clear screen and move to top left */
- printf("%s%s", clr, topLeft);
-
- printf("\nPort statistics ====================================");
-
- for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) {
- /* skip disabled ports */
- if ((l2fwd_enabled_port_mask & (1 << portid)) == 0)
- continue;
- printf("\nStatistics for port %u ------------------------------"
- "\nPackets sent: %24"PRIu64
- "\nPackets received: %20"PRIu64
- "\nPackets dropped: %21"PRIu64,
- portid,
- port_statistics[portid].tx,
- port_statistics[portid].rx,
- port_statistics[portid].dropped);
-
- total_packets_dropped += port_statistics[portid].dropped;
- total_packets_tx += port_statistics[portid].tx;
- total_packets_rx += port_statistics[portid].rx;
- }
- printf("\nAggregate statistics ==============================="
- "\nTotal packets sent: %18"PRIu64
- "\nTotal packets received: %14"PRIu64
- "\nTotal packets dropped: %15"PRIu64,
- total_packets_tx,
- total_packets_rx,
- total_packets_dropped);
- printf("\n====================================================\n");
-}
-
-static int
-clear_cpu_affinity(void)
-{
- int s;
-
- s = sched_setaffinity(0, cpu_aff.size, &cpu_aff.set);
- if (s != 0) {
- printf("sched_setaffinity failed:%s\n", strerror(errno));
- return -1;
- }
-
- return 0;
-}
-
-static int
-get_cpu_affinity(void)
-{
- int s;
-
- cpu_aff.size = sizeof(cpu_set_t);
- CPU_ZERO(&cpu_aff.set);
-
- s = sched_getaffinity(0, cpu_aff.size, &cpu_aff.set);
- if (s != 0) {
- printf("sched_getaffinity failed:%s\n", strerror(errno));
- return -1;
- }
-
- return 0;
-}
-
-/**
- * This fnciton demonstrates the approach to create ring in first instance
- * or re-attach an existed ring in later instance.
- **/
-static struct rte_ring *
-create_ring(const char *name, unsigned count,
- int socket_id,unsigned flags)
-{
- struct rte_ring *ring;
-
- if (name == NULL)
- return NULL;
-
- /* If already create, just attached it */
- if (likely((ring = rte_ring_lookup(name)) != NULL))
- return ring;
-
- /* First call it, create one */
- return rte_ring_create(name, count, socket_id, flags);
-}
-
-/* Malloc with rte_malloc on structures that shared by master and slave */
-static int
-l2fwd_malloc_shared_struct(void)
-{
- port_statistics = rte_zmalloc("port_stat",
- sizeof(struct l2fwd_port_statistics) * RTE_MAX_ETHPORTS,
- 0);
- if (port_statistics == NULL)
- return -1;
-
- /* allocate mapping_id array */
- if (float_proc) {
- int i;
- mapping_id = rte_malloc("mapping_id", sizeof(unsigned) * RTE_MAX_LCORE,
- 0);
-
- if (mapping_id == NULL)
- return -1;
-
- for (i = 0 ;i < RTE_MAX_LCORE; i++)
- mapping_id[i] = INVALID_MAPPING_ID;
- }
- return 0;
-}
-
-/* Create ring which used for communicate among master and slave */
-static int
-create_ms_ring(unsigned slaveid)
-{
- unsigned flag = RING_F_SP_ENQ | RING_F_SC_DEQ;
- struct lcore_resource_struct *res = &lcore_resource[slaveid];
- unsigned socketid = rte_socket_id();
-
- /* Always assume create ring on master socket_id */
- /* Default only create a ring size 32 */
- snprintf(res->ring_name[0], MAX_NAME_LEN, "%s%u",
- RING_MASTER_NAME, slaveid);
- if ((res->ring[0] = create_ring(res->ring_name[0], NB_CORE_MSGBUF,
- socketid, flag)) == NULL) {
- printf("Create m2s ring %s failed\n", res->ring_name[0]);
- return -1;
- }
-
- snprintf(res->ring_name[1], MAX_NAME_LEN, "%s%u",
- RING_SLAVE_NAME, slaveid);
- if ((res->ring[1] = create_ring(res->ring_name[1], NB_CORE_MSGBUF,
- socketid, flag)) == NULL) {
- printf("Create s2m ring %s failed\n", res->ring_name[1]);
- return -1;
- }
-
- return 0;
-}
-
-/* send command to pair in paired master and slave ring */
-static inline int
-sendcmd(unsigned slaveid, enum l2fwd_cmd cmd, int is_master)
-{
- struct lcore_resource_struct *res = &lcore_resource[slaveid];
- void *msg;
- int fd = !is_master;
-
- /* Only check master, it must be enabled and running if it is slave */
- if (is_master && !res->enabled)
- return -1;
-
- if (res->ring[fd] == NULL)
- return -1;
-
- if (rte_mempool_get(message_pool, &msg) < 0) {
- printf("Error to get message buffer\n");
- return -1;
- }
-
- *(enum l2fwd_cmd *)msg = cmd;
-
- if (rte_ring_enqueue(res->ring[fd], msg) != 0) {
- printf("Enqueue error\n");
- rte_mempool_put(message_pool, msg);
- return -1;
- }
-
- return 0;
-}
-
-/* Get command from pair in paired master and slave ring */
-static inline int
-getcmd(unsigned slaveid, enum l2fwd_cmd *cmd, int is_master)
-{
- struct lcore_resource_struct *res = &lcore_resource[slaveid];
- void *msg;
- int fd = !!is_master;
- int ret;
- /* Only check master, it must be enabled and running if it is slave */
- if (is_master && (!res->enabled))
- return -1;
-
- if (res->ring[fd] == NULL)
- return -1;
-
- ret = rte_ring_dequeue(res->ring[fd], &msg);
-
- if (ret == 0) {
- *cmd = *(enum l2fwd_cmd *)msg;
- rte_mempool_put(message_pool, msg);
- }
- return ret;
-}
-
-/* Master send command to slave and wait until ack received or error met */
-static int
-master_sendcmd_with_ack(unsigned slaveid, enum l2fwd_cmd cmd)
-{
- enum l2fwd_cmd ack_cmd;
- int ret = -1;
-
- if (sendcmd(slaveid, cmd, 1) != 0)
- rte_exit(EXIT_FAILURE, "Failed to send message\n");
-
- /* Get ack */
- while (1) {
- ret = getcmd(slaveid, &ack_cmd, 1);
- if (ret == 0 && cmd == ack_cmd)
- break;
-
- /* If slave not running yet, return an error */
- if (flib_query_slave_status(slaveid) != ST_RUN) {
- ret = -ENOENT;
- break;
- }
- }
-
- return ret;
-}
-
-/* restart all port that assigned to that slave lcore */
-static int
-reset_slave_all_ports(unsigned slaveid)
-{
- struct lcore_resource_struct *slave = &lcore_resource[slaveid];
- int i, ret = 0;
-
- /* stop/start port */
- for (i = 0; i < slave->port_num; i++) {
- char buf_name[RTE_MEMPOOL_NAMESIZE];
- struct rte_mempool *pool;
- printf("Stop port :%d\n", slave->port[i]);
- rte_eth_dev_stop(slave->port[i]);
- snprintf(buf_name, RTE_MEMPOOL_NAMESIZE, MBUF_NAME, slave->port[i]);
- pool = rte_mempool_lookup(buf_name);
- if (pool)
- printf("Port %d mempool free object is %u(%u)\n", slave->port[i],
- rte_mempool_avail_count(pool),
- (unsigned int)NB_MBUF);
- else
- printf("Can't find mempool %s\n", buf_name);
-
- printf("Start port :%d\n", slave->port[i]);
- ret = rte_eth_dev_start(slave->port[i]);
- if (ret != 0)
- break;
- }
- return ret;
-}
-
-static int
-reset_shared_structures(unsigned slaveid)
-{
- int ret;
- /* Only port are shared resource here */
- ret = reset_slave_all_ports(slaveid);
-
- return ret;
-}
-
-/**
- * Call this function to re-create resource that needed for slave process that
- * exited in last instance
- **/
-static int
-init_slave_res(unsigned slaveid)
-{
- struct lcore_resource_struct *slave = &lcore_resource[slaveid];
- enum l2fwd_cmd cmd;
-
- if (!slave->enabled) {
- printf("Something wrong with lcore=%u enabled=%d\n",slaveid,
- slave->enabled);
- return -1;
- }
-
- /* Initialize ring */
- if (create_ms_ring(slaveid) != 0)
- rte_exit(EXIT_FAILURE, "failed to create ring for slave %u\n",
- slaveid);
-
- /* drain un-read buffer if have */
- while (getcmd(slaveid, &cmd, 1) == 0);
- while (getcmd(slaveid, &cmd, 0) == 0);
-
- return 0;
-}
-
-static int
-recreate_one_slave(unsigned slaveid)
-{
- int ret = 0;
- /* Re-initialize resource for stalled slave */
- if ((ret = init_slave_res(slaveid)) != 0) {
- printf("Init slave=%u failed\n", slaveid);
- return ret;
- }
-
- if ((ret = flib_remote_launch(l2fwd_launch_one_lcore, NULL, slaveid))
- != 0)
- printf("Launch slave %u failed\n", slaveid);
-
- return ret;
-}
-
-/**
- * remapping resource belong to slave_id to new lcore that gets from flib_assign_lcore_id(),
- * used only floating process option applied.
- *
- * @param slaveid
- * original lcore_id that apply for remapping
- */
-static void
-remapping_slave_resource(unsigned slaveid, unsigned map_id)
-{
-
- /* remapping lcore_resource */
- memcpy(&lcore_resource[map_id], &lcore_resource[slaveid],
- sizeof(struct lcore_resource_struct));
-
- /* remapping lcore_queue_conf */
- memcpy(&lcore_queue_conf[map_id], &lcore_queue_conf[slaveid],
- sizeof(struct lcore_queue_conf));
-}
-
-static int
-reset_pair(unsigned slaveid, unsigned pairid)
-{
- int ret;
- if ((ret = reset_shared_structures(slaveid)) != 0)
- goto back;
-
- if((ret = reset_shared_structures(pairid)) != 0)
- goto back;
-
- if (float_proc) {
- unsigned map_id = mapping_id[slaveid];
-
- if (map_id != INVALID_MAPPING_ID) {
- printf("%u return mapping id %u\n", slaveid, map_id);
- flib_free_lcore_id(map_id);
- mapping_id[slaveid] = INVALID_MAPPING_ID;
- }
-
- map_id = mapping_id[pairid];
- if (map_id != INVALID_MAPPING_ID) {
- printf("%u return mapping id %u\n", pairid, map_id);
- flib_free_lcore_id(map_id);
- mapping_id[pairid] = INVALID_MAPPING_ID;
- }
- }
-
- if((ret = recreate_one_slave(slaveid)) != 0)
- goto back;
-
- ret = recreate_one_slave(pairid);
-
-back:
- return ret;
-}
-
-static void
-slave_exit_cb(unsigned slaveid, __attribute__((unused))int stat)
-{
- struct lcore_resource_struct *slave = &lcore_resource[slaveid];
-
- printf("Get slave %u leave info\n", slaveid);
- if (!slave->enabled) {
- printf("Lcore=%u not registered for it's exit\n", slaveid);
- return;
- }
- rte_spinlock_lock(&res_lock);
-
- /* Change the state and wait master to start them */
- slave->flags = SLAVE_RECREATE_FLAG;
-
- rte_spinlock_unlock(&res_lock);
-}
-
-static void
-l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid)
-{
- struct ether_hdr *eth;
- void *tmp;
- unsigned dst_port;
- int sent;
- struct rte_eth_dev_tx_buffer *buffer;
-
- dst_port = l2fwd_dst_ports[portid];
- eth = rte_pktmbuf_mtod(m, struct ether_hdr *);
-
- /* 02:00:00:00:00:xx */
- tmp = &eth->d_addr.addr_bytes[0];
- *((uint64_t *)tmp) = 0x000000000002 + ((uint64_t)dst_port << 40);
-
- /* src addr */
- ether_addr_copy(&l2fwd_ports_eth_addr[dst_port], &eth->s_addr);
-
- buffer = tx_buffer[dst_port];
- sent = rte_eth_tx_buffer(dst_port, 0, buffer, m);
- if (sent)
- port_statistics[dst_port].tx += sent;
-}
-
-/* main processing loop */
-static void
-l2fwd_main_loop(void)
-{
- struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
- struct rte_mbuf *m;
- int sent;
- unsigned lcore_id;
- uint64_t prev_tsc, diff_tsc, cur_tsc;
- unsigned i, j, portid, nb_rx;
- struct lcore_queue_conf *qconf;
- const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S *
- BURST_TX_DRAIN_US;
- struct rte_eth_dev_tx_buffer *buffer;
-
- prev_tsc = 0;
-
- lcore_id = rte_lcore_id();
-
- qconf = &lcore_queue_conf[lcore_id];
-
- if (qconf->n_rx_port == 0) {
- RTE_LOG(INFO, L2FWD, "lcore %u has nothing to do\n", lcore_id);
- return;
- }
-
- RTE_LOG(INFO, L2FWD, "entering main loop on lcore %u\n", lcore_id);
-
- for (i = 0; i < qconf->n_rx_port; i++) {
- portid = qconf->rx_port_list[i];
- RTE_LOG(INFO, L2FWD, " -- lcoreid=%u portid=%u\n", lcore_id,
- portid);
- }
-
- while (1) {
- enum l2fwd_cmd cmd;
- cur_tsc = rte_rdtsc();
-
- if (unlikely(getcmd(lcore_id, &cmd, 0) == 0)) {
- sendcmd(lcore_id, cmd, 0);
-
- /* If get stop command, stop forwarding and exit */
- if (cmd == CMD_STOP) {
- return;
- }
- }
-
- /*
- * TX burst queue drain
- */
- diff_tsc = cur_tsc - prev_tsc;
- if (unlikely(diff_tsc > drain_tsc)) {
-
- for (i = 0; i < qconf->n_rx_port; i++) {
-
- portid = l2fwd_dst_ports[qconf->rx_port_list[i]];
- buffer = tx_buffer[portid];
-
- sent = rte_eth_tx_buffer_flush(portid, 0, buffer);
- if (sent)
- port_statistics[portid].tx += sent;
-
- }
-
- prev_tsc = cur_tsc;
- }
-
- /*
- * Read packet from RX queues
- */
- for (i = 0; i < qconf->n_rx_port; i++) {
-
- portid = qconf->rx_port_list[i];
- nb_rx = rte_eth_rx_burst((uint8_t) portid, 0,
- pkts_burst, MAX_PKT_BURST);
-
- port_statistics[portid].rx += nb_rx;
-
- for (j = 0; j < nb_rx; j++) {
- m = pkts_burst[j];
- rte_prefetch0(rte_pktmbuf_mtod(m, void *));
- l2fwd_simple_forward(m, portid);
- }
- }
- }
-}
-
-static int
-l2fwd_launch_one_lcore(__attribute__((unused)) void *dummy)
-{
- unsigned lcore_id = rte_lcore_id();
-
- if (float_proc) {
- unsigned flcore_id;
-
- /* Change it to floating process, also change it's lcore_id */
- clear_cpu_affinity();
- RTE_PER_LCORE(_lcore_id) = 0;
- /* Get a lcore_id */
- if (flib_assign_lcore_id() < 0 ) {
- printf("flib_assign_lcore_id failed\n");
- return -1;
- }
- flcore_id = rte_lcore_id();
- /* Set mapping id, so master can return it after slave exited */
- mapping_id[lcore_id] = flcore_id;
- printf("Org lcore_id = %u, cur lcore_id = %u\n",
- lcore_id, flcore_id);
- remapping_slave_resource(lcore_id, flcore_id);
- }
-
- l2fwd_main_loop();
-
- /* return lcore_id before return */
- if (float_proc) {
- flib_free_lcore_id(rte_lcore_id());
- mapping_id[lcore_id] = INVALID_MAPPING_ID;
- }
- return 0;
-}
-
-/* display usage */
-static void
-l2fwd_usage(const char *prgname)
-{
- printf("%s [EAL options] -- -p PORTMASK -s COREMASK [-q NQ] -f\n"
- " -p PORTMASK: hexadecimal bitmask of ports to configure\n"
- " -q NQ: number of queue (=ports) per lcore (default is 1)\n"
- " -f use floating process which won't bind to any core to run\n"
- " -T PERIOD: statistics will be refreshed each PERIOD seconds (0 to disable, 10 default, 86400 maximum)\n",
- prgname);
-}
-
-static int
-l2fwd_parse_portmask(const char *portmask)
-{
- char *end = NULL;
- unsigned long pm;
-
- /* parse hexadecimal string */
- pm = strtoul(portmask, &end, 16);
- if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0'))
- return -1;
-
- if (pm == 0)
- return -1;
-
- return pm;
-}
-
-static unsigned int
-l2fwd_parse_nqueue(const char *q_arg)
-{
- char *end = NULL;
- unsigned long n;
-
- /* parse hexadecimal string */
- n = strtoul(q_arg, &end, 10);
- if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0'))
- return 0;
- if (n == 0)
- return 0;
- if (n >= MAX_RX_QUEUE_PER_LCORE)
- return 0;
-
- return n;
-}
-
-static int
-l2fwd_parse_timer_period(const char *q_arg)
-{
- char *end = NULL;
- int n;
-
- /* parse number string */
- n = strtol(q_arg, &end, 10);
- if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0'))
- return -1;
- if (n >= MAX_TIMER_PERIOD)
- return -1;
-
- return n;
-}
-
-/* Parse the argument given in the command line of the application */
-static int
-l2fwd_parse_args(int argc, char **argv)
-{
- int opt, ret;
- char **argvopt;
- int option_index;
- char *prgname = argv[0];
- static struct option lgopts[] = {
- {NULL, 0, 0, 0}
- };
- int has_pmask = 0;
-
- argvopt = argv;
-
- while ((opt = getopt_long(argc, argvopt, "p:q:T:f",
- lgopts, &option_index)) != EOF) {
-
- switch (opt) {
- /* portmask */
- case 'p':
- l2fwd_enabled_port_mask = l2fwd_parse_portmask(optarg);
- if (l2fwd_enabled_port_mask == 0) {
- printf("invalid portmask\n");
- l2fwd_usage(prgname);
- return -1;
- }
- has_pmask = 1;
- break;
-
- /* nqueue */
- case 'q':
- l2fwd_rx_queue_per_lcore = l2fwd_parse_nqueue(optarg);
- if (l2fwd_rx_queue_per_lcore == 0) {
- printf("invalid queue number\n");
- l2fwd_usage(prgname);
- return -1;
- }
- break;
-
- /* timer period */
- case 'T':
- timer_period = l2fwd_parse_timer_period(optarg) * 1000 * TIMER_MILLISECOND;
- if (timer_period < 0) {
- printf("invalid timer period\n");
- l2fwd_usage(prgname);
- return -1;
- }
- break;
-
- /* use floating process */
- case 'f':
- float_proc = 1;
- break;
-
- /* long options */
- case 0:
- l2fwd_usage(prgname);
- return -1;
-
- default:
- l2fwd_usage(prgname);
- return -1;
- }
- }
-
- if (optind >= 0)
- argv[optind-1] = prgname;
-
- if (!has_pmask) {
- l2fwd_usage(prgname);
- return -1;
- }
- ret = optind-1;
- optind = 1; /* reset getopt lib */
- return ret;
-}
-
-/* Check the link status of all ports in up to 9s, and print them finally */
-static void
-check_all_ports_link_status(uint32_t port_mask)
-{
-#define CHECK_INTERVAL 100 /* 100ms */
-#define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
- uint16_t portid;
- uint8_t count, all_ports_up, print_flag = 0;
- struct rte_eth_link link;
-
- printf("\nChecking link status");
- fflush(stdout);
- for (count = 0; count <= MAX_CHECK_TIME; count++) {
- all_ports_up = 1;
- RTE_ETH_FOREACH_DEV(portid) {
- if ((port_mask & (1 << portid)) == 0)
- continue;
- memset(&link, 0, sizeof(link));
- rte_eth_link_get_nowait(portid, &link);
- /* print link status if flag set */
- if (print_flag == 1) {
- if (link.link_status)
- printf(
- "Port%d Link Up- speed %u Mbps- %s\n",
- portid, link.link_speed,
- (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
- ("full-duplex") : ("half-duplex\n"));
- else
- printf("Port %d Link Down\n", portid);
- continue;
- }
- /* clear all_ports_up flag if any link down */
- if (link.link_status == ETH_LINK_DOWN) {
- all_ports_up = 0;
- break;
- }
- }
- /* after finally printing all link status, get out */
- if (print_flag == 1)
- break;
-
- if (all_ports_up == 0) {
- printf(".");
- fflush(stdout);
- rte_delay_ms(CHECK_INTERVAL);
- }
-
- /* set the print_flag if all ports up or timeout */
- if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
- print_flag = 1;
- printf("done\n");
- }
- }
-}
-
-int
-main(int argc, char **argv)
-{
- struct lcore_queue_conf *qconf;
- int ret;
- uint16_t nb_ports;
- uint16_t nb_ports_available = 0;
- uint16_t portid, last_port;
- unsigned rx_lcore_id;
- unsigned nb_ports_in_mask = 0;
- unsigned i;
- uint64_t prev_tsc, diff_tsc, cur_tsc, timer_tsc;
-
- /* Save cpu_affinity first, restore it in case it's floating process option */
- if (get_cpu_affinity() != 0)
- rte_exit(EXIT_FAILURE, "get_cpu_affinity error\n");
-
- /* Also tries to set cpu affinity to detect whether it will fail in child process */
- if(clear_cpu_affinity() != 0)
- rte_exit(EXIT_FAILURE, "clear_cpu_affinity error\n");
-
- /* init EAL */
- ret = rte_eal_init(argc, argv);
- if (ret < 0)
- rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n");
- argc -= ret;
- argv += ret;
-
- /* parse application arguments (after the EAL ones) */
- ret = l2fwd_parse_args(argc, argv);
- if (ret < 0)
- rte_exit(EXIT_FAILURE, "Invalid L2FWD arguments\n");
-
- /*flib init */
- if (flib_init() != 0)
- rte_exit(EXIT_FAILURE, "flib init error");
-
- /**
- * Allocated structures that slave lcore would change. For those that slaves are
- * read only, needn't use malloc to share and global or static variables is ok since
- * slave inherit all the knowledge that master initialized.
- **/
- if (l2fwd_malloc_shared_struct() != 0)
- rte_exit(EXIT_FAILURE, "malloc mem failed\n");
-
- /* Initialize lcore_resource structures */
- memset(lcore_resource, 0, sizeof(lcore_resource));
- for (i = 0; i < RTE_MAX_LCORE; i++)
- lcore_resource[i].lcore_id = i;
-
- nb_ports = rte_eth_dev_count_avail();
- if (nb_ports == 0)
- rte_exit(EXIT_FAILURE, "No Ethernet ports - bye\n");
-
- /* create the mbuf pool */
- RTE_ETH_FOREACH_DEV(portid) {
- /* skip ports that are not enabled */
- if ((l2fwd_enabled_port_mask & (1 << portid)) == 0)
- continue;
- char buf_name[RTE_MEMPOOL_NAMESIZE];
- snprintf(buf_name, RTE_MEMPOOL_NAMESIZE, MBUF_NAME, portid);
- l2fwd_pktmbuf_pool[portid] =
- rte_pktmbuf_pool_create(buf_name, NB_MBUF, 32,
- 0, MBUF_DATA_SIZE, rte_socket_id());
- if (l2fwd_pktmbuf_pool[portid] == NULL)
- rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
-
- printf("Create mbuf %s\n", buf_name);
- }
-
- /* reset l2fwd_dst_ports */
- for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++)
- l2fwd_dst_ports[portid] = 0;
- last_port = 0;
-
- /*
- * Each logical core is assigned a dedicated TX queue on each port.
- */
- RTE_ETH_FOREACH_DEV(portid) {
- /* skip ports that are not enabled */
- if ((l2fwd_enabled_port_mask & (1 << portid)) == 0)
- continue;
-
- if (nb_ports_in_mask % 2) {
- l2fwd_dst_ports[portid] = last_port;
- l2fwd_dst_ports[last_port] = portid;
- }
- else
- last_port = portid;
-
- nb_ports_in_mask++;
- }
- if (nb_ports_in_mask % 2) {
- printf("Notice: odd number of ports in portmask.\n");
- l2fwd_dst_ports[last_port] = last_port;
- }
-
- rx_lcore_id = 0;
- qconf = NULL;
-
- /* Initialize the port/queue configuration of each logical core */
- RTE_ETH_FOREACH_DEV(portid) {
- struct lcore_resource_struct *res;
- /* skip ports that are not enabled */
- if ((l2fwd_enabled_port_mask & (1 << portid)) == 0)
- continue;
-
- /* get the lcore_id for this port */
- /* skip master lcore */
- while (rte_lcore_is_enabled(rx_lcore_id) == 0 ||
- rte_get_master_lcore() == rx_lcore_id ||
- lcore_queue_conf[rx_lcore_id].n_rx_port ==
- l2fwd_rx_queue_per_lcore) {
-
- rx_lcore_id++;
- if (rx_lcore_id >= RTE_MAX_LCORE)
- rte_exit(EXIT_FAILURE, "Not enough cores\n");
- }
-
- if (qconf != &lcore_queue_conf[rx_lcore_id])
- /* Assigned a new logical core in the loop above. */
- qconf = &lcore_queue_conf[rx_lcore_id];
-
- qconf->rx_port_list[qconf->n_rx_port] = portid;
- qconf->n_rx_port++;
-
- /* Save the port resource info into lcore_resource strucutres */
- res = &lcore_resource[rx_lcore_id];
- res->enabled = 1;
- res->port[res->port_num++] = portid;
-
- printf("Lcore %u: RX port %u\n", rx_lcore_id, (unsigned) portid);
- }
-
- /* Initialise each port */
- RTE_ETH_FOREACH_DEV(portid) {
- struct rte_eth_rxconf rxq_conf;
- struct rte_eth_txconf txq_conf;
- struct rte_eth_conf local_port_conf = port_conf;
-
- /* skip ports that are not enabled */
- if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) {
- printf("Skipping disabled port %u\n", (unsigned) portid);
- continue;
- }
- nb_ports_available++;
- /* init port */
- printf("Initializing port %u... ", (unsigned) portid);
- fflush(stdout);
- rte_eth_dev_info_get(portid, &dev_info);
- if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
- local_port_conf.txmode.offloads |=
- DEV_TX_OFFLOAD_MBUF_FAST_FREE;
- ret = rte_eth_dev_configure(portid, 1, 1, &local_port_conf);
- if (ret < 0)
- rte_exit(EXIT_FAILURE, "Cannot configure device: err=%d, port=%u\n",
- ret, (unsigned) portid);
-
- ret = rte_eth_dev_adjust_nb_rx_tx_desc(portid, &nb_rxd,
- &nb_txd);
- if (ret < 0)
- rte_exit(EXIT_FAILURE,
- "rte_eth_dev_adjust_nb_rx_tx_desc: err=%d, port=%u\n",
- ret, (unsigned) portid);
-
- rte_eth_macaddr_get(portid,&l2fwd_ports_eth_addr[portid]);
-
- /* init one RX queue */
- fflush(stdout);
- rxq_conf = dev_info.default_rxconf;
- rxq_conf.offloads = local_port_conf.rxmode.offloads;
- ret = rte_eth_rx_queue_setup(portid, 0, nb_rxd,
- rte_eth_dev_socket_id(portid),
- &rxq_conf,
- l2fwd_pktmbuf_pool[portid]);
- if (ret < 0)
- rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup:err=%d, port=%u\n",
- ret, (unsigned) portid);
-
- /* init one TX queue on each port */
- fflush(stdout);
- txq_conf = dev_info.default_txconf;
- txq_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
- txq_conf.tx_offloads = local_port_conf.txmode.offloads;
- ret = rte_eth_tx_queue_setup(portid, 0, nb_txd,
- rte_eth_dev_socket_id(portid),
- &txq_conf);
- if (ret < 0)
- rte_exit(EXIT_FAILURE, "rte_eth_tx_queue_setup:err=%d, port=%u\n",
- ret, (unsigned) portid);
-
- /* Initialize TX buffers */
- tx_buffer[portid] = rte_zmalloc_socket("tx_buffer",
- RTE_ETH_TX_BUFFER_SIZE(MAX_PKT_BURST), 0,
- rte_eth_dev_socket_id(portid));
- if (tx_buffer[portid] == NULL)
- rte_exit(EXIT_FAILURE, "Cannot allocate buffer for tx on port %u\n",
- (unsigned) portid);
-
- rte_eth_tx_buffer_init(tx_buffer[portid], MAX_PKT_BURST);
-
- ret = rte_eth_tx_buffer_set_err_callback(tx_buffer[portid],
- rte_eth_tx_buffer_count_callback,
- &port_statistics[portid].dropped);
- if (ret < 0)
- rte_exit(EXIT_FAILURE, "Cannot set error callback for "
- "tx buffer on port %u\n", (unsigned) portid);
-
- /* Start device */
- ret = rte_eth_dev_start(portid);
- if (ret < 0)
- rte_exit(EXIT_FAILURE, "rte_eth_dev_start:err=%d, port=%u\n",
- ret, (unsigned) portid);
-
- printf("done: \n");
-
- rte_eth_promiscuous_enable(portid);
-
- printf("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n",
- (unsigned) portid,
- l2fwd_ports_eth_addr[portid].addr_bytes[0],
- l2fwd_ports_eth_addr[portid].addr_bytes[1],
- l2fwd_ports_eth_addr[portid].addr_bytes[2],
- l2fwd_ports_eth_addr[portid].addr_bytes[3],
- l2fwd_ports_eth_addr[portid].addr_bytes[4],
- l2fwd_ports_eth_addr[portid].addr_bytes[5]);
-
- /* initialize port stats */
- //memset(&port_statistics, 0, sizeof(port_statistics));
- }
-
- if (!nb_ports_available) {
- rte_exit(EXIT_FAILURE,
- "All available ports are disabled. Please set portmask.\n");
- }
-
- check_all_ports_link_status(l2fwd_enabled_port_mask);
-
- /* Record pair lcore */
- /**
- * Since l2fwd example would create pair between different neighbour port, that's
- * port 0 receive and forward to port 1, the same to port 1, these 2 ports will have
- * dependency. If one port stopped working (killed, for example), the port need to
- * be stopped/started again. During the time, another port need to wait until stop/start
- * procedure completed. So, record the pair relationship for those lcores working
- * on ports.
- **/
- RTE_ETH_FOREACH_DEV(portid) {
- uint32_t pair_port;
- unsigned lcore = 0, pair_lcore = 0;
- unsigned j, find_lcore, find_pair_lcore;
- /* skip ports that are not enabled */
- if ((l2fwd_enabled_port_mask & (1 << portid)) == 0)
- continue;
-
- /* Find pair ports' lcores */
- find_lcore = find_pair_lcore = 0;
- pair_port = l2fwd_dst_ports[portid];
- for (i = 0; i < RTE_MAX_LCORE; i++) {
- if (!rte_lcore_is_enabled(i))
- continue;
- for (j = 0; j < lcore_queue_conf[i].n_rx_port;j++) {
- if (lcore_queue_conf[i].rx_port_list[j] == portid) {
- lcore = i;
- find_lcore = 1;
- break;
- }
- if (lcore_queue_conf[i].rx_port_list[j] == pair_port) {
- pair_lcore = i;
- find_pair_lcore = 1;
- break;
- }
- }
- if (find_lcore && find_pair_lcore)
- break;
- }
- if (!find_lcore || !find_pair_lcore)
- rte_exit(EXIT_FAILURE, "Not find port=%d pair\n", portid);
-
- printf("lcore %u and %u paired\n", lcore, pair_lcore);
- lcore_resource[lcore].pair_id = pair_lcore;
- lcore_resource[pair_lcore].pair_id = lcore;
- }
-
- /* Create message buffer for all master and slave */
- message_pool = rte_mempool_create("ms_msg_pool",
- NB_CORE_MSGBUF * RTE_MAX_LCORE,
- sizeof(enum l2fwd_cmd), NB_CORE_MSGBUF / 2,
- 0, NULL, NULL, NULL, NULL, rte_socket_id(), 0);
-
- if (message_pool == NULL)
- rte_exit(EXIT_FAILURE, "Create msg mempool failed\n");
-
- /* Create ring for each master and slave pair, also register cb when slave leaves */
- for (i = 0; i < RTE_MAX_LCORE; i++) {
- /**
- * Only create ring and register slave_exit cb in case that core involved into
- * packet forwarding
- **/
- if (lcore_resource[i].enabled) {
- /* Create ring for master and slave communication */
- ret = create_ms_ring(i);
- if (ret != 0)
- rte_exit(EXIT_FAILURE, "Create ring for lcore=%u failed",
- i);
-
- if (flib_register_slave_exit_notify(i,
- slave_exit_cb) != 0)
- rte_exit(EXIT_FAILURE,
- "Register master_trace_slave_exit failed");
- }
- }
-
- /* launch per-lcore init on every lcore except master */
- flib_mp_remote_launch(l2fwd_launch_one_lcore, NULL, SKIP_MASTER);
-
- /* print statistics 10 second */
- prev_tsc = cur_tsc = rte_rdtsc();
- timer_tsc = 0;
- while (1) {
- sleep(1);
- cur_tsc = rte_rdtsc();
- diff_tsc = cur_tsc - prev_tsc;
- /* if timer is enabled */
- if (timer_period > 0) {
-
- /* advance the timer */
- timer_tsc += diff_tsc;
-
- /* if timer has reached its timeout */
- if (unlikely(timer_tsc >= (uint64_t) timer_period)) {
-
- print_stats();
- /* reset the timer */
- timer_tsc = 0;
- }
- }
-
- prev_tsc = cur_tsc;
-
- /* Check any slave need restart or recreate */
- rte_spinlock_lock(&res_lock);
- for (i = 0; i < RTE_MAX_LCORE; i++) {
- struct lcore_resource_struct *res = &lcore_resource[i];
- struct lcore_resource_struct *pair = &lcore_resource[res->pair_id];
-
- /* If find slave exited, try to reset pair */
- if (res->enabled && res->flags && pair->enabled) {
- if (!pair->flags) {
- master_sendcmd_with_ack(pair->lcore_id, CMD_STOP);
- rte_spinlock_unlock(&res_lock);
- sleep(1);
- rte_spinlock_lock(&res_lock);
- if (pair->flags)
- continue;
- }
- if (reset_pair(res->lcore_id, pair->lcore_id) != 0)
- rte_exit(EXIT_FAILURE, "failed to reset slave");
- res->flags = 0;
- pair->flags = 0;
- }
- }
- rte_spinlock_unlock(&res_lock);
- }
-
-}
diff --git a/examples/multi_process/symmetric_mp/main.c b/examples/multi_process/symmetric_mp/main.c
index 16f21a18..c6c6a537 100644
--- a/examples/multi_process/symmetric_mp/main.c
+++ b/examples/multi_process/symmetric_mp/main.c
@@ -178,7 +178,6 @@ smp_port_init(uint16_t port, struct rte_mempool *mbuf_pool,
.rxmode = {
.mq_mode = ETH_MQ_RX_RSS,
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
.offloads = (DEV_RX_OFFLOAD_CHECKSUM |
DEV_RX_OFFLOAD_CRC_STRIP),
},
@@ -200,6 +199,7 @@ smp_port_init(uint16_t port, struct rte_mempool *mbuf_pool,
uint16_t q;
uint16_t nb_rxd = RX_RING_SIZE;
uint16_t nb_txd = TX_RING_SIZE;
+ uint64_t rss_hf_tmp;
if (rte_eal_process_type() == RTE_PROC_SECONDARY)
return 0;
@@ -216,6 +216,17 @@ smp_port_init(uint16_t port, struct rte_mempool *mbuf_pool,
if (info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
port_conf.txmode.offloads |=
DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+ rss_hf_tmp = port_conf.rx_adv_conf.rss_conf.rss_hf;
+ port_conf.rx_adv_conf.rss_conf.rss_hf &= info.flow_type_rss_offloads;
+ if (port_conf.rx_adv_conf.rss_conf.rss_hf != rss_hf_tmp) {
+ printf("Port %u modified RSS hash function based on hardware support,"
+ "requested:%#"PRIx64" configured:%#"PRIx64"\n",
+ port,
+ rss_hf_tmp,
+ port_conf.rx_adv_conf.rss_conf.rss_hf);
+ }
+
retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
if (retval < 0)
return retval;
@@ -236,7 +247,6 @@ smp_port_init(uint16_t port, struct rte_mempool *mbuf_pool,
}
txq_conf = info.default_txconf;
- txq_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
txq_conf.offloads = port_conf.txmode.offloads;
for (q = 0; q < tx_rings; q ++) {
retval = rte_eth_tx_queue_setup(port, q, nb_txd,
diff --git a/examples/netmap_compat/bridge/Makefile b/examples/netmap_compat/bridge/Makefile
index a7c9c14a..856c847b 100644
--- a/examples/netmap_compat/bridge/Makefile
+++ b/examples/netmap_compat/bridge/Makefile
@@ -10,7 +10,7 @@ RTE_TARGET ?= x86_64-native-linuxapp-gcc
include $(RTE_SDK)/mk/rte.vars.mk
-ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
$(info This application can only operate in a linuxapp environment, \
please change the definition of the RTE_TARGET environment variable)
all:
diff --git a/examples/netmap_compat/bridge/bridge.c b/examples/netmap_compat/bridge/bridge.c
index cb1882e6..7afca28c 100644
--- a/examples/netmap_compat/bridge/bridge.c
+++ b/examples/netmap_compat/bridge/bridge.c
@@ -26,7 +26,6 @@
struct rte_eth_conf eth_conf = {
.rxmode = {
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
.offloads = DEV_RX_OFFLOAD_CRC_STRIP,
},
.txmode = {
diff --git a/examples/netmap_compat/lib/compat_netmap.c b/examples/netmap_compat/lib/compat_netmap.c
index af3dd223..0be0663e 100644
--- a/examples/netmap_compat/lib/compat_netmap.c
+++ b/examples/netmap_compat/lib/compat_netmap.c
@@ -708,7 +708,6 @@ rte_netmap_init_port(uint16_t portid, const struct rte_netmap_port_conf *conf)
rxq_conf = dev_info.default_rxconf;
rxq_conf.offloads = conf->eth_conf->rxmode.offloads;
txq_conf = dev_info.default_txconf;
- txq_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
txq_conf.offloads = conf->eth_conf->txmode.offloads;
for (i = 0; i < conf->nr_tx_rings; i++) {
ret = rte_eth_tx_queue_setup(portid, i, tx_slots,
diff --git a/examples/packet_ordering/main.c b/examples/packet_ordering/main.c
index 7ace7d10..149bfdd0 100644
--- a/examples/packet_ordering/main.c
+++ b/examples/packet_ordering/main.c
@@ -35,11 +35,7 @@ volatile uint8_t quit_signal;
static struct rte_mempool *mbuf_pool;
-static struct rte_eth_conf port_conf_default = {
- .rxmode = {
- .ignore_offload_bitfield = 1,
- },
-};
+static struct rte_eth_conf port_conf_default;
struct worker_thread_args {
struct rte_ring *ring_in;
@@ -293,7 +289,6 @@ configure_eth_port(uint16_t port_id)
}
txconf = dev_info.default_txconf;
- txconf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
txconf.offloads = port_conf.txmode.offloads;
for (q = 0; q < txRings; q++) {
ret = rte_eth_tx_queue_setup(port_id, q, nb_txd,
diff --git a/examples/performance-thread/common/lthread_pool.h b/examples/performance-thread/common/lthread_pool.h
index 315a2e21..6f93775f 100644
--- a/examples/performance-thread/common/lthread_pool.h
+++ b/examples/performance-thread/common/lthread_pool.h
@@ -1,69 +1,7 @@
/*
- *-
- * BSD LICENSE
- *
- * Copyright(c) 2015 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Some portions of this software is derived from the producer
- * consumer queues described by Dmitry Vyukov and published here
- * http://www.1024cores.net
- *
- * Copyright (c) 2010-2011 Dmitry Vyukov. All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY DMITRY VYUKOV "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DMITRY VYUKOV OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are
- * those of the authors and should not be interpreted as representing official
- * policies, either expressed or implied, of Dmitry Vyukov.
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2015 Intel Corporation.
+ * Copyright 2010-2011 Dmitry Vyukov
*/
#ifndef LTHREAD_POOL_H_
diff --git a/examples/performance-thread/common/lthread_queue.h b/examples/performance-thread/common/lthread_queue.h
index 833ed92b..5b63ba22 100644
--- a/examples/performance-thread/common/lthread_queue.h
+++ b/examples/performance-thread/common/lthread_queue.h
@@ -1,69 +1,7 @@
/*
- *-
- * BSD LICENSE
- *
- * Copyright(c) 2015 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Some portions of this software is derived from the producer
- * consumer queues described by Dmitry Vyukov and published here
- * http://www.1024cores.net
- *
- * Copyright (c) 2010-2011 Dmitry Vyukov. All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY DMITRY VYUKOV "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DMITRY VYUKOV OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are
- * those of the authors and should not be interpreted as representing official
- * policies, either expressed or implied, of Dmitry Vyukov.
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2015 Intel Corporation.
+ * Copyright 2010-2011 Dmitry Vyukov
*/
#ifndef LTHREAD_QUEUE_H_
diff --git a/examples/performance-thread/l3fwd-thread/main.c b/examples/performance-thread/l3fwd-thread/main.c
index 40d80723..5392fcea 100644
--- a/examples/performance-thread/l3fwd-thread/main.c
+++ b/examples/performance-thread/l3fwd-thread/main.c
@@ -306,7 +306,6 @@ static struct rte_eth_conf port_conf = {
.mq_mode = ETH_MQ_RX_RSS,
.max_rx_pkt_len = ETHER_MAX_LEN,
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
.offloads = (DEV_RX_OFFLOAD_CHECKSUM |
DEV_RX_OFFLOAD_CRC_STRIP),
},
@@ -3551,6 +3550,18 @@ main(int argc, char **argv)
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
local_port_conf.txmode.offloads |=
DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+ local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
+ dev_info.flow_type_rss_offloads;
+ if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
+ port_conf.rx_adv_conf.rss_conf.rss_hf) {
+ printf("Port %u modified RSS hash function based on hardware support,"
+ "requested:%#"PRIx64" configured:%#"PRIx64"\n",
+ portid,
+ port_conf.rx_adv_conf.rss_conf.rss_hf,
+ local_port_conf.rx_adv_conf.rss_conf.rss_hf);
+ }
+
ret = rte_eth_dev_configure(portid, nb_rx_queue,
(uint16_t)n_tx_queue, &local_port_conf);
if (ret < 0)
@@ -3597,7 +3608,6 @@ main(int argc, char **argv)
fflush(stdout);
txconf = &dev_info.default_txconf;
- txconf->txq_flags = ETH_TXQ_FLAGS_IGNORE;
txconf->offloads = local_port_conf.txmode.offloads;
ret = rte_eth_tx_queue_setup(portid, queueid, nb_txd,
socketid, txconf);
diff --git a/examples/ptpclient/ptpclient.c b/examples/ptpclient/ptpclient.c
index c44013bc..82ae71c1 100644
--- a/examples/ptpclient/ptpclient.c
+++ b/examples/ptpclient/ptpclient.c
@@ -50,7 +50,6 @@ static uint8_t ptp_enabled_ports[RTE_MAX_ETHPORTS];
static const struct rte_eth_conf port_conf_default = {
.rxmode = {
.max_rx_pkt_len = ETHER_MAX_LEN,
- .ignore_offload_bitfield = 1,
},
};
@@ -217,11 +216,9 @@ port_init(uint16_t port, struct rte_mempool *mbuf_pool)
/* Allocate and set up 1 TX queue per Ethernet port. */
for (q = 0; q < tx_rings; q++) {
- /* Setup txq_flags */
struct rte_eth_txconf *txconf;
txconf = &dev_info.default_txconf;
- txconf->txq_flags = ETH_TXQ_FLAGS_IGNORE;
txconf->offloads = port_conf.txmode.offloads;
retval = rte_eth_tx_queue_setup(port, q, nb_txd,
diff --git a/examples/qos_meter/Makefile b/examples/qos_meter/Makefile
index 6da24076..46341b1a 100644
--- a/examples/qos_meter/Makefile
+++ b/examples/qos_meter/Makefile
@@ -50,7 +50,6 @@ RTE_TARGET ?= x86_64-native-linuxapp-gcc
include $(RTE_SDK)/mk/rte.vars.mk
-CFLAGS += -DALLOW_EXPERIMENTAL_API
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
diff --git a/examples/qos_meter/main.c b/examples/qos_meter/main.c
index 42cf4b29..5cf4e9df 100644
--- a/examples/qos_meter/main.c
+++ b/examples/qos_meter/main.c
@@ -56,7 +56,6 @@ static struct rte_eth_conf port_conf = {
.mq_mode = ETH_MQ_RX_RSS,
.max_rx_pkt_len = ETHER_MAX_LEN,
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
.offloads = (DEV_RX_OFFLOAD_CHECKSUM |
DEV_RX_OFFLOAD_CRC_STRIP),
},
@@ -333,6 +332,17 @@ main(int argc, char **argv)
rte_eth_dev_info_get(port_rx, &dev_info);
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
conf.txmode.offloads |= DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+ conf.rx_adv_conf.rss_conf.rss_hf &= dev_info.flow_type_rss_offloads;
+ if (conf.rx_adv_conf.rss_conf.rss_hf !=
+ port_conf.rx_adv_conf.rss_conf.rss_hf) {
+ printf("Port %u modified RSS hash function based on hardware support,"
+ "requested:%#"PRIx64" configured:%#"PRIx64"\n",
+ port_rx,
+ port_conf.rx_adv_conf.rss_conf.rss_hf,
+ conf.rx_adv_conf.rss_conf.rss_hf);
+ }
+
ret = rte_eth_dev_configure(port_rx, 1, 1, &conf);
if (ret < 0)
rte_exit(EXIT_FAILURE, "Port %d configuration error (%d)\n", port_rx, ret);
@@ -351,7 +361,6 @@ main(int argc, char **argv)
rte_exit(EXIT_FAILURE, "Port %d RX queue setup error (%d)\n", port_rx, ret);
txq_conf = dev_info.default_txconf;
- txq_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
txq_conf.offloads = conf.txmode.offloads;
ret = rte_eth_tx_queue_setup(port_rx, NIC_TX_QUEUE, nb_txd,
rte_eth_dev_socket_id(port_rx),
@@ -363,6 +372,17 @@ main(int argc, char **argv)
rte_eth_dev_info_get(port_tx, &dev_info);
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
conf.txmode.offloads |= DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+ conf.rx_adv_conf.rss_conf.rss_hf &= dev_info.flow_type_rss_offloads;
+ if (conf.rx_adv_conf.rss_conf.rss_hf !=
+ port_conf.rx_adv_conf.rss_conf.rss_hf) {
+ printf("Port %u modified RSS hash function based on hardware support,"
+ "requested:%#"PRIx64" configured:%#"PRIx64"\n",
+ port_tx,
+ port_conf.rx_adv_conf.rss_conf.rss_hf,
+ conf.rx_adv_conf.rss_conf.rss_hf);
+ }
+
ret = rte_eth_dev_configure(port_tx, 1, 1, &conf);
if (ret < 0)
rte_exit(EXIT_FAILURE, "Port %d configuration error (%d)\n", port_tx, ret);
@@ -383,7 +403,6 @@ main(int argc, char **argv)
rte_exit(EXIT_FAILURE, "Port %d RX queue setup error (%d)\n", port_tx, ret);
txq_conf = dev_info.default_txconf;
- txq_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
txq_conf.offloads = conf.txmode.offloads;
ret = rte_eth_tx_queue_setup(port_tx, NIC_TX_QUEUE, nb_txd,
rte_eth_dev_socket_id(port_tx),
diff --git a/examples/qos_meter/meson.build b/examples/qos_meter/meson.build
index 10cd4bc7..ef7779f2 100644
--- a/examples/qos_meter/meson.build
+++ b/examples/qos_meter/meson.build
@@ -7,7 +7,6 @@
# DPDK instance, use 'make'
deps += 'meter'
-allow_experimental_apis = true
sources = files(
'main.c', 'rte_policer.c'
)
diff --git a/examples/qos_sched/Makefile b/examples/qos_sched/Makefile
index 0f0a31ff..a7ecf978 100644
--- a/examples/qos_sched/Makefile
+++ b/examples/qos_sched/Makefile
@@ -48,7 +48,7 @@ RTE_TARGET ?= x86_64-native-linuxapp-gcc
include $(RTE_SDK)/mk/rte.vars.mk
-ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
$(info This application can only operate in a linuxapp environment, \
please change the definition of the RTE_TARGET environment variable)
all:
diff --git a/examples/qos_sched/init.c b/examples/qos_sched/init.c
index c9e48797..94cbb26f 100644
--- a/examples/qos_sched/init.c
+++ b/examples/qos_sched/init.c
@@ -59,7 +59,6 @@ static struct rte_eth_conf port_conf = {
.rxmode = {
.max_rx_pkt_len = ETHER_MAX_LEN,
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
.offloads = DEV_RX_OFFLOAD_CRC_STRIP,
},
.txmode = {
@@ -96,7 +95,6 @@ app_init_port(uint16_t portid, struct rte_mempool *mp)
tx_conf.tx_free_thresh = 0;
tx_conf.tx_rs_thresh = 0;
tx_conf.tx_deferred_start = 0;
- tx_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
/* init port */
RTE_LOG(INFO, APP, "Initializing port %"PRIu16"... ", portid);
diff --git a/examples/quota_watermark/qw/init.c b/examples/quota_watermark/qw/init.c
index 00725bc9..19164385 100644
--- a/examples/quota_watermark/qw/init.c
+++ b/examples/quota_watermark/qw/init.c
@@ -24,7 +24,6 @@
static struct rte_eth_conf port_conf = {
.rxmode = {
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
.offloads = DEV_RX_OFFLOAD_CRC_STRIP,
},
.txmode = {
@@ -82,7 +81,6 @@ void configure_eth_port(uint16_t port_id)
/* Initialize the port's TX queue */
txq_conf = dev_info.default_txconf;
- txq_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
txq_conf.offloads = local_port_conf.txmode.offloads;
ret = rte_eth_tx_queue_setup(port_id, 0, nb_txd,
rte_eth_dev_socket_id(port_id),
diff --git a/examples/rxtx_callbacks/main.c b/examples/rxtx_callbacks/main.c
index e63ea288..2058be62 100644
--- a/examples/rxtx_callbacks/main.c
+++ b/examples/rxtx_callbacks/main.c
@@ -20,7 +20,6 @@
static const struct rte_eth_conf port_conf_default = {
.rxmode = {
.max_rx_pkt_len = ETHER_MAX_LEN,
- .ignore_offload_bitfield = 1,
},
};
@@ -104,7 +103,6 @@ port_init(uint16_t port, struct rte_mempool *mbuf_pool)
}
txconf = dev_info.default_txconf;
- txconf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
txconf.offloads = port_conf.txmode.offloads;
for (q = 0; q < tx_rings; q++) {
retval = rte_eth_tx_queue_setup(port, q, nb_txd,
diff --git a/examples/server_node_efd/server/Makefile b/examples/server_node_efd/server/Makefile
index cbb91ebe..df6614c6 100644
--- a/examples/server_node_efd/server/Makefile
+++ b/examples/server_node_efd/server/Makefile
@@ -10,7 +10,7 @@ RTE_TARGET ?= x86_64-native-linuxapp-gcc
include $(RTE_SDK)/mk/rte.vars.mk
-ifneq ($(CONFIG_RTE_EXEC_ENV), "linuxapp")
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
$(error This application can only operate in a linuxapp environment, \
please change the definition of the RTE_TARGET environment variable)
endif
diff --git a/examples/server_node_efd/server/init.c b/examples/server_node_efd/server/init.c
index 7dfe2fa2..af5a18e2 100644
--- a/examples/server_node_efd/server/init.c
+++ b/examples/server_node_efd/server/init.c
@@ -97,7 +97,6 @@ init_port(uint16_t port_num)
struct rte_eth_conf port_conf = {
.rxmode = {
.mq_mode = ETH_MQ_RX_RSS,
- .ignore_offload_bitfield = 1,
},
};
const uint16_t rx_rings = 1, tx_rings = num_nodes;
@@ -139,7 +138,6 @@ init_port(uint16_t port_num)
}
txconf = dev_info.default_txconf;
- txconf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
txconf.offloads = port_conf.txmode.offloads;
for (q = 0; q < tx_rings; q++) {
retval = rte_eth_tx_queue_setup(port_num, q, tx_ring_size,
diff --git a/examples/skeleton/basicfwd.c b/examples/skeleton/basicfwd.c
index 03bc3585..4aba1dc3 100644
--- a/examples/skeleton/basicfwd.c
+++ b/examples/skeleton/basicfwd.c
@@ -20,7 +20,6 @@
static const struct rte_eth_conf port_conf_default = {
.rxmode = {
.max_rx_pkt_len = ETHER_MAX_LEN,
- .ignore_offload_bitfield = 1,
},
};
@@ -68,7 +67,6 @@ port_init(uint16_t port, struct rte_mempool *mbuf_pool)
}
txconf = dev_info.default_txconf;
- txconf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
txconf.offloads = port_conf.txmode.offloads;
/* Allocate and set up 1 TX queue per Ethernet port. */
for (q = 0; q < tx_rings; q++) {
diff --git a/examples/tep_termination/Makefile b/examples/tep_termination/Makefile
index 2b93446c..8ec1a38e 100644
--- a/examples/tep_termination/Makefile
+++ b/examples/tep_termination/Makefile
@@ -52,7 +52,7 @@ RTE_TARGET ?= x86_64-native-linuxapp-gcc
include $(RTE_SDK)/mk/rte.vars.mk
-ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
$(error This application can only operate in a linuxapp environment, \
please change the definition of the RTE_TARGET environment variable)
endif
diff --git a/examples/tep_termination/vxlan_setup.c b/examples/tep_termination/vxlan_setup.c
index 299c29d2..b99ab97d 100644
--- a/examples/tep_termination/vxlan_setup.c
+++ b/examples/tep_termination/vxlan_setup.c
@@ -69,7 +69,6 @@ uint8_t tep_filter_type[] = {RTE_TUNNEL_FILTER_IMAC_TENID,
static struct rte_eth_conf port_conf = {
.rxmode = {
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
.offloads = DEV_RX_OFFLOAD_CRC_STRIP,
},
.txmode = {
@@ -131,7 +130,6 @@ vxlan_port_init(uint16_t port, struct rte_mempool *mbuf_pool)
rxconf = &dev_info.default_rxconf;
txconf = &dev_info.default_txconf;
- txconf->txq_flags = ETH_TXQ_FLAGS_IGNORE;
if (!rte_eth_dev_is_valid_port(port))
return -1;
diff --git a/examples/vhost/Makefile b/examples/vhost/Makefile
index 67cc55b1..a2ea97a0 100644
--- a/examples/vhost/Makefile
+++ b/examples/vhost/Makefile
@@ -52,7 +52,7 @@ RTE_TARGET ?= x86_64-native-linuxapp-gcc
include $(RTE_SDK)/mk/rte.vars.mk
-ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
$(info This application can only operate in a linuxapp environment, \
please change the definition of the RTE_TARGET environment variable)
all:
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 1659ef31..2175c118 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -116,7 +116,6 @@ static struct rte_eth_conf vmdq_conf_default = {
.rxmode = {
.mq_mode = ETH_MQ_RX_VMDQ_ONLY,
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
/*
* VLAN strip is necessary for 1G NIC such as I350,
* this fixes bug of ipv4 forwarding in guest can't
@@ -256,7 +255,6 @@ port_init(uint16_t port)
rxconf = &dev_info.default_rxconf;
txconf = &dev_info.default_txconf;
rxconf->rx_drop_en = 1;
- txconf->txq_flags = ETH_TXQ_FLAGS_IGNORE;
/*configure the number of supported virtio devices based on VMDQ limits */
num_devices = dev_info.max_vmdq_pools;
diff --git a/examples/vhost_crypto/Makefile b/examples/vhost_crypto/Makefile
index 1bb65e8f..83d33101 100644
--- a/examples/vhost_crypto/Makefile
+++ b/examples/vhost_crypto/Makefile
@@ -10,7 +10,7 @@ RTE_TARGET ?= x86_64-native-linuxapp-gcc
include $(RTE_SDK)/mk/rte.vars.mk
-ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
$(info This application can only operate in a linuxapp environment, \
please change the definition of the RTE_TARGET environment variable)
all:
diff --git a/examples/vhost_scsi/Makefile b/examples/vhost_scsi/Makefile
index 31bd2563..fa0cf727 100644
--- a/examples/vhost_scsi/Makefile
+++ b/examples/vhost_scsi/Makefile
@@ -51,7 +51,7 @@ RTE_TARGET ?= x86_64-native-linuxapp-gcc
include $(RTE_SDK)/mk/rte.vars.mk
-ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
$(info This application can only operate in a linuxapp environment, \
please change the definition of the RTE_TARGET environment variable)
all:
diff --git a/examples/vm_power_manager/Makefile b/examples/vm_power_manager/Makefile
index ef2a9f95..13a5205b 100644
--- a/examples/vm_power_manager/Makefile
+++ b/examples/vm_power_manager/Makefile
@@ -19,7 +19,12 @@ APP = vm_power_mgr
# all source are stored in SRCS-y
SRCS-y := main.c vm_power_cli.c power_manager.c channel_manager.c
-SRCS-y += channel_monitor.c
+SRCS-y += channel_monitor.c parse.c
+ifeq ($(CONFIG_RTE_ARCH_X86_64),y)
+SRCS-y += oob_monitor_x86.c
+else
+SRCS-y += oob_monitor_nop.c
+endif
CFLAGS += -O3 -I$(RTE_SDK)/lib/librte_power/
CFLAGS += $(WERROR_FLAGS)
diff --git a/examples/vm_power_manager/channel_monitor.c b/examples/vm_power_manager/channel_monitor.c
index 73bddd99..7fa47ba9 100644
--- a/examples/vm_power_manager/channel_monitor.c
+++ b/examples/vm_power_manager/channel_monitor.c
@@ -27,6 +27,7 @@
#include "channel_commands.h"
#include "channel_manager.h"
#include "power_manager.h"
+#include "oob_monitor.h"
#define RTE_LOGTYPE_CHANNEL_MONITOR RTE_LOGTYPE_USER1
@@ -92,6 +93,10 @@ get_pcpu_to_control(struct policy *pol)
struct vm_info info;
int pcpu, count;
uint64_t mask_u64b;
+ struct core_info *ci;
+ int ret;
+
+ ci = get_core_info();
RTE_LOG(INFO, CHANNEL_MONITOR, "Looking for pcpu for %s\n",
pol->pkt.vm_name);
@@ -100,8 +105,22 @@ get_pcpu_to_control(struct policy *pol)
for (count = 0; count < pol->pkt.num_vcpu; count++) {
mask_u64b = info.pcpu_mask[pol->pkt.vcpu_to_control[count]];
for (pcpu = 0; mask_u64b; mask_u64b &= ~(1ULL << pcpu++)) {
- if ((mask_u64b >> pcpu) & 1)
- pol->core_share[count].pcpu = pcpu;
+ if ((mask_u64b >> pcpu) & 1) {
+ if (pol->pkt.policy_to_use == BRANCH_RATIO) {
+ ci->cd[pcpu].oob_enabled = 1;
+ ret = add_core_to_monitor(pcpu);
+ if (ret == 0)
+ printf("Monitoring pcpu %d via Branch Ratio\n",
+ pcpu);
+ else
+ printf("Failed to start OOB Monitoring pcpu %d\n",
+ pcpu);
+
+ } else {
+ pol->core_share[count].pcpu = pcpu;
+ printf("Monitoring pcpu %d\n", pcpu);
+ }
+ }
}
}
}
diff --git a/examples/vm_power_manager/guest_cli/Makefile b/examples/vm_power_manager/guest_cli/Makefile
index d710e22d..8b1db861 100644
--- a/examples/vm_power_manager/guest_cli/Makefile
+++ b/examples/vm_power_manager/guest_cli/Makefile
@@ -14,7 +14,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
APP = guest_vm_power_mgr
# all source are stored in SRCS-y
-SRCS-y := main.c vm_power_cli_guest.c
+SRCS-y := main.c vm_power_cli_guest.c parse.c
CFLAGS += -O3 -I$(RTE_SDK)/lib/librte_power/
CFLAGS += $(WERROR_FLAGS)
diff --git a/examples/vm_power_manager/guest_cli/main.c b/examples/vm_power_manager/guest_cli/main.c
index b17936d6..36365b12 100644
--- a/examples/vm_power_manager/guest_cli/main.c
+++ b/examples/vm_power_manager/guest_cli/main.c
@@ -2,23 +2,20 @@
* Copyright(c) 2010-2014 Intel Corporation
*/
-/*
#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-#include <sys/epoll.h>
-#include <fcntl.h>
-#include <unistd.h>
#include <stdlib.h>
-#include <errno.h>
-*/
#include <signal.h>
+#include <getopt.h>
+#include <string.h>
#include <rte_lcore.h>
#include <rte_power.h>
#include <rte_debug.h>
+#include <rte_eal.h>
+#include <rte_log.h>
#include "vm_power_cli_guest.h"
+#include "parse.h"
static void
sig_handler(int signo)
@@ -32,6 +29,136 @@ sig_handler(int signo)
}
+#define MAX_HOURS 24
+
+/* Parse the argument given in the command line of the application */
+static int
+parse_args(int argc, char **argv)
+{
+ int opt, ret;
+ char **argvopt;
+ int option_index;
+ char *prgname = argv[0];
+ const struct option lgopts[] = {
+ { "vm-name", required_argument, 0, 'n'},
+ { "busy-hours", required_argument, 0, 'b'},
+ { "quiet-hours", required_argument, 0, 'q'},
+ { "port-list", required_argument, 0, 'p'},
+ { "vcpu-list", required_argument, 0, 'l'},
+ { "policy", required_argument, 0, 'o'},
+ {NULL, 0, 0, 0}
+ };
+ struct channel_packet *policy;
+ unsigned short int hours[MAX_HOURS];
+ unsigned short int cores[MAX_VCPU_PER_VM];
+ unsigned short int ports[MAX_VCPU_PER_VM];
+ int i, cnt, idx;
+
+ policy = get_policy();
+ set_policy_defaults(policy);
+
+ argvopt = argv;
+
+ while ((opt = getopt_long(argc, argvopt, "n:b:q:p:",
+ lgopts, &option_index)) != EOF) {
+
+ switch (opt) {
+ /* portmask */
+ case 'n':
+ strcpy(policy->vm_name, optarg);
+ printf("Setting VM Name to [%s]\n", policy->vm_name);
+ break;
+ case 'b':
+ case 'q':
+ //printf("***Processing set using [%s]\n", optarg);
+ cnt = parse_set(optarg, hours, MAX_HOURS);
+ if (cnt < 0) {
+ printf("Invalid value passed to quiet/busy hours - [%s]\n",
+ optarg);
+ break;
+ }
+ idx = 0;
+ for (i = 0; i < MAX_HOURS; i++) {
+ if (hours[i]) {
+ if (opt == 'b') {
+ printf("***Busy Hour %d\n", i);
+ policy->timer_policy.busy_hours
+ [idx++] = i;
+ } else {
+ printf("***Quiet Hour %d\n", i);
+ policy->timer_policy.quiet_hours
+ [idx++] = i;
+ }
+ }
+ }
+ break;
+ case 'l':
+ cnt = parse_set(optarg, cores, MAX_VCPU_PER_VM);
+ if (cnt < 0) {
+ printf("Invalid value passed to vcpu-list - [%s]\n",
+ optarg);
+ break;
+ }
+ idx = 0;
+ for (i = 0; i < MAX_VCPU_PER_VM; i++) {
+ if (cores[i]) {
+ printf("***Using core %d\n", i);
+ policy->vcpu_to_control[idx++] = i;
+ }
+ }
+ policy->num_vcpu = idx;
+ printf("Total cores: %d\n", idx);
+ break;
+ case 'p':
+ cnt = parse_set(optarg, ports, MAX_VCPU_PER_VM);
+ if (cnt < 0) {
+ printf("Invalid value passed to port-list - [%s]\n",
+ optarg);
+ break;
+ }
+ idx = 0;
+ for (i = 0; i < MAX_VCPU_PER_VM; i++) {
+ if (ports[i]) {
+ printf("***Using port %d\n", i);
+ set_policy_mac(i, idx++);
+ }
+ }
+ policy->nb_mac_to_monitor = idx;
+ printf("Total Ports: %d\n", idx);
+ break;
+ case 'o':
+ if (!strcmp(optarg, "TRAFFIC"))
+ policy->policy_to_use = TRAFFIC;
+ else if (!strcmp(optarg, "TIME"))
+ policy->policy_to_use = TIME;
+ else if (!strcmp(optarg, "WORKLOAD"))
+ policy->policy_to_use = WORKLOAD;
+ else if (!strcmp(optarg, "BRANCH_RATIO"))
+ policy->policy_to_use = BRANCH_RATIO;
+ else {
+ printf("Invalid policy specified: %s\n",
+ optarg);
+ return -1;
+ }
+ break;
+ /* long options */
+
+ case 0:
+ break;
+
+ default:
+ return -1;
+ }
+ }
+
+ if (optind >= 0)
+ argv[optind-1] = prgname;
+
+ ret = optind-1;
+ optind = 0; /* reset getopt lib */
+ return ret;
+}
+
int
main(int argc, char **argv)
{
@@ -45,6 +172,14 @@ main(int argc, char **argv)
signal(SIGINT, sig_handler);
signal(SIGTERM, sig_handler);
+ argc -= ret;
+ argv += ret;
+
+ /* parse application arguments (after the EAL ones) */
+ ret = parse_args(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Invalid arguments\n");
+
rte_power_set_env(PM_ENV_KVM_VM);
RTE_LCORE_FOREACH(lcore_id) {
rte_power_init(lcore_id);
diff --git a/examples/vm_power_manager/guest_cli/parse.c b/examples/vm_power_manager/guest_cli/parse.c
new file mode 100644
index 00000000..528df6d6
--- /dev/null
+++ b/examples/vm_power_manager/guest_cli/parse.c
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2014 Intel Corporation.
+ * Copyright(c) 2014 6WIND S.A.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <rte_log.h>
+#include "parse.h"
+
+/*
+ * Parse elem, the elem could be single number/range or group
+ * 1) A single number elem, it's just a simple digit. e.g. 9
+ * 2) A single range elem, two digits with a '-' between. e.g. 2-6
+ * 3) A group elem, combines multiple 1) or 2) e.g 0,2-4,6
+ * Within group, '-' used for a range separator;
+ * ',' used for a single number.
+ */
+int
+parse_set(const char *input, uint16_t set[], unsigned int num)
+{
+ unsigned int idx;
+ const char *str = input;
+ char *end = NULL;
+ unsigned int min, max;
+
+ memset(set, 0, num * sizeof(uint16_t));
+
+ while (isblank(*str))
+ str++;
+
+ /* only digit or left bracket is qualify for start point */
+ if (!isdigit(*str) || *str == '\0')
+ return -1;
+
+ while (isblank(*str))
+ str++;
+ if (*str == '\0')
+ return -1;
+
+ min = num;
+ do {
+
+ /* go ahead to the first digit */
+ while (isblank(*str))
+ str++;
+ if (!isdigit(*str))
+ return -1;
+
+ /* get the digit value */
+ errno = 0;
+ idx = strtoul(str, &end, 10);
+ if (errno || end == NULL || idx >= num)
+ return -1;
+
+ /* go ahead to separator '-' and ',' */
+ while (isblank(*end))
+ end++;
+ if (*end == '-') {
+ if (min == num)
+ min = idx;
+ else /* avoid continuous '-' */
+ return -1;
+ } else if ((*end == ',') || (*end == '\0')) {
+ max = idx;
+
+ if (min == num)
+ min = idx;
+
+ for (idx = RTE_MIN(min, max);
+ idx <= RTE_MAX(min, max); idx++) {
+ set[idx] = 1;
+ }
+ min = num;
+ } else
+ return -1;
+
+ str = end + 1;
+ } while (*end != '\0');
+
+ return str - input;
+}
diff --git a/examples/vm_power_manager/guest_cli/parse.h b/examples/vm_power_manager/guest_cli/parse.h
new file mode 100644
index 00000000..c8aa0ea5
--- /dev/null
+++ b/examples/vm_power_manager/guest_cli/parse.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#ifndef PARSE_H_
+#define PARSE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int
+parse_set(const char *, uint16_t [], unsigned int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PARSE_H_ */
diff --git a/examples/vm_power_manager/guest_cli/vm_power_cli_guest.c b/examples/vm_power_manager/guest_cli/vm_power_cli_guest.c
index 43bdeace..0db1b804 100644
--- a/examples/vm_power_manager/guest_cli/vm_power_cli_guest.c
+++ b/examples/vm_power_manager/guest_cli/vm_power_cli_guest.c
@@ -33,6 +33,71 @@ struct cmd_quit_result {
cmdline_fixed_string_t quit;
};
+union PFID {
+ struct ether_addr addr;
+ uint64_t pfid;
+};
+
+static struct channel_packet policy;
+
+struct channel_packet *
+get_policy(void)
+{
+ return &policy;
+}
+
+int
+set_policy_mac(int port, int idx)
+{
+ struct channel_packet *policy;
+ union PFID pfid;
+
+ /* Use port MAC address as the vfid */
+ rte_eth_macaddr_get(port, &pfid.addr);
+
+ printf("Port %u MAC: %02" PRIx8 ":%02" PRIx8 ":%02" PRIx8 ":"
+ "%02" PRIx8 ":%02" PRIx8 ":%02" PRIx8 "\n",
+ port,
+ pfid.addr.addr_bytes[0], pfid.addr.addr_bytes[1],
+ pfid.addr.addr_bytes[2], pfid.addr.addr_bytes[3],
+ pfid.addr.addr_bytes[4], pfid.addr.addr_bytes[5]);
+ policy = get_policy();
+ policy->vfid[idx] = pfid.pfid;
+ return 0;
+}
+
+void
+set_policy_defaults(struct channel_packet *pkt)
+{
+ set_policy_mac(0, 0);
+ pkt->nb_mac_to_monitor = 1;
+
+ pkt->t_boost_status.tbEnabled = false;
+
+ pkt->vcpu_to_control[0] = 0;
+ pkt->vcpu_to_control[1] = 1;
+ pkt->num_vcpu = 2;
+ /* Dummy Population. */
+ pkt->traffic_policy.min_packet_thresh = 96000;
+ pkt->traffic_policy.avg_max_packet_thresh = 1800000;
+ pkt->traffic_policy.max_max_packet_thresh = 2000000;
+
+ pkt->timer_policy.busy_hours[0] = 3;
+ pkt->timer_policy.busy_hours[1] = 4;
+ pkt->timer_policy.busy_hours[2] = 5;
+ pkt->timer_policy.quiet_hours[0] = 11;
+ pkt->timer_policy.quiet_hours[1] = 12;
+ pkt->timer_policy.quiet_hours[2] = 13;
+
+ pkt->timer_policy.hours_to_use_traffic_profile[0] = 8;
+ pkt->timer_policy.hours_to_use_traffic_profile[1] = 10;
+
+ pkt->workload = LOW;
+ pkt->policy_to_use = TIME;
+ pkt->command = PKT_POLICY;
+ strcpy(pkt->vm_name, "ubuntu2");
+}
+
static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
__attribute__((unused)) struct cmdline *cl,
__attribute__((unused)) void *data)
@@ -118,54 +183,12 @@ struct cmd_send_policy_result {
cmdline_fixed_string_t cmd;
};
-union PFID {
- struct ether_addr addr;
- uint64_t pfid;
-};
-
static inline int
-send_policy(void)
+send_policy(struct channel_packet *pkt)
{
- struct channel_packet pkt;
int ret;
- union PFID pfid;
- /* Use port MAC address as the vfid */
- rte_eth_macaddr_get(0, &pfid.addr);
- printf("Port %u MAC: %02" PRIx8 ":%02" PRIx8 ":%02" PRIx8 ":"
- "%02" PRIx8 ":%02" PRIx8 ":%02" PRIx8 "\n",
- 1,
- pfid.addr.addr_bytes[0], pfid.addr.addr_bytes[1],
- pfid.addr.addr_bytes[2], pfid.addr.addr_bytes[3],
- pfid.addr.addr_bytes[4], pfid.addr.addr_bytes[5]);
- pkt.vfid[0] = pfid.pfid;
-
- pkt.nb_mac_to_monitor = 1;
- pkt.t_boost_status.tbEnabled = false;
-
- pkt.vcpu_to_control[0] = 0;
- pkt.vcpu_to_control[1] = 1;
- pkt.num_vcpu = 2;
- /* Dummy Population. */
- pkt.traffic_policy.min_packet_thresh = 96000;
- pkt.traffic_policy.avg_max_packet_thresh = 1800000;
- pkt.traffic_policy.max_max_packet_thresh = 2000000;
-
- pkt.timer_policy.busy_hours[0] = 3;
- pkt.timer_policy.busy_hours[1] = 4;
- pkt.timer_policy.busy_hours[2] = 5;
- pkt.timer_policy.quiet_hours[0] = 11;
- pkt.timer_policy.quiet_hours[1] = 12;
- pkt.timer_policy.quiet_hours[2] = 13;
-
- pkt.timer_policy.hours_to_use_traffic_profile[0] = 8;
- pkt.timer_policy.hours_to_use_traffic_profile[1] = 10;
-
- pkt.workload = LOW;
- pkt.policy_to_use = TIME;
- pkt.command = PKT_POLICY;
- strcpy(pkt.vm_name, "ubuntu2");
- ret = rte_power_guest_channel_send_msg(&pkt, 1);
+ ret = rte_power_guest_channel_send_msg(pkt, 1);
if (ret == 0)
return 1;
RTE_LOG(DEBUG, POWER, "Error sending message: %s\n",
@@ -182,7 +205,7 @@ cmd_send_policy_parsed(void *parsed_result, struct cmdline *cl,
if (!strcmp(res->cmd, "now")) {
printf("Sending Policy down now!\n");
- ret = send_policy();
+ ret = send_policy(&policy);
}
if (ret != 1)
cmdline_printf(cl, "Error sending message: %s\n",
diff --git a/examples/vm_power_manager/guest_cli/vm_power_cli_guest.h b/examples/vm_power_manager/guest_cli/vm_power_cli_guest.h
index 75a26296..fd77f6a6 100644
--- a/examples/vm_power_manager/guest_cli/vm_power_cli_guest.h
+++ b/examples/vm_power_manager/guest_cli/vm_power_cli_guest.h
@@ -11,6 +11,12 @@ extern "C" {
#include "channel_commands.h"
+struct channel_packet *get_policy(void);
+
+int set_policy_mac(int port, int idx);
+
+void set_policy_defaults(struct channel_packet *pkt);
+
void run_cli(__attribute__((unused)) void *arg);
#ifdef __cplusplus
diff --git a/examples/vm_power_manager/main.c b/examples/vm_power_manager/main.c
index c9805a46..58c5fa45 100644
--- a/examples/vm_power_manager/main.c
+++ b/examples/vm_power_manager/main.c
@@ -29,6 +29,8 @@
#include "channel_monitor.h"
#include "power_manager.h"
#include "vm_power_cli.h"
+#include "oob_monitor.h"
+#include "parse.h"
#include <rte_pmd_ixgbe.h>
#include <rte_pmd_i40e.h>
#include <rte_pmd_bnxt.h>
@@ -47,7 +49,6 @@ static volatile bool force_quit;
static const struct rte_eth_conf port_conf_default = {
.rxmode = {
.max_rx_pkt_len = ETHER_MAX_LEN,
- .ignore_offload_bitfield = 1,
},
};
@@ -83,7 +84,6 @@ port_init(uint16_t port, struct rte_mempool *mbuf_pool)
}
txq_conf = dev_info.default_txconf;
- txq_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
txq_conf.offloads = port_conf.txmode.offloads;
/* Allocate and set up 1 TX queue per Ethernet port. */
for (q = 0; q < tx_rings; q++) {
@@ -135,18 +135,25 @@ parse_portmask(const char *portmask)
static int
parse_args(int argc, char **argv)
{
- int opt, ret;
+ int opt, ret, cnt, i;
char **argvopt;
+ uint16_t *oob_enable;
int option_index;
char *prgname = argv[0];
+ struct core_info *ci;
+ float branch_ratio;
static struct option lgopts[] = {
{ "mac-updating", no_argument, 0, 1},
{ "no-mac-updating", no_argument, 0, 0},
+ { "core-list", optional_argument, 0, 'l'},
+ { "port-list", optional_argument, 0, 'p'},
+ { "branch-ratio", optional_argument, 0, 'b'},
{NULL, 0, 0, 0}
};
argvopt = argv;
+ ci = get_core_info();
- while ((opt = getopt_long(argc, argvopt, "p:q:T:",
+ while ((opt = getopt_long(argc, argvopt, "l:p:q:T:b:",
lgopts, &option_index)) != EOF) {
switch (opt) {
@@ -158,6 +165,39 @@ parse_args(int argc, char **argv)
return -1;
}
break;
+ case 'l':
+ oob_enable = malloc(ci->core_count * sizeof(uint16_t));
+ if (oob_enable == NULL) {
+ printf("Error - Unable to allocate memory\n");
+ return -1;
+ }
+ cnt = parse_set(optarg, oob_enable, ci->core_count);
+ if (cnt < 0) {
+ printf("Invalid core-list - [%s]\n",
+ optarg);
+ break;
+ }
+ for (i = 0; i < ci->core_count; i++) {
+ if (oob_enable[i]) {
+ printf("***Using core %d\n", i);
+ ci->cd[i].oob_enabled = 1;
+ ci->cd[i].global_enabled_cpus = 1;
+ }
+ }
+ free(oob_enable);
+ break;
+ case 'b':
+ branch_ratio = 0.0;
+ if (strlen(optarg))
+ branch_ratio = atof(optarg);
+ if (branch_ratio <= 0.0) {
+ printf("invalid branch ratio specified\n");
+ return -1;
+ }
+ ci->branch_ratio_threshold = branch_ratio;
+ printf("***Setting branch ratio to %f\n",
+ branch_ratio);
+ break;
/* long options */
case 0:
break;
@@ -243,6 +283,17 @@ run_monitor(__attribute__((unused)) void *arg)
return 0;
}
+static int
+run_core_monitor(__attribute__((unused)) void *arg)
+{
+ if (branch_monitor_init() < 0) {
+ printf("Unable to initialize core monitor\n");
+ return -1;
+ }
+ run_branch_monitor();
+ return 0;
+}
+
static void
sig_handler(int signo)
{
@@ -261,8 +312,15 @@ main(int argc, char **argv)
unsigned int nb_ports;
struct rte_mempool *mbuf_pool;
uint16_t portid;
+ struct core_info *ci;
+ ret = core_info_init();
+ if (ret < 0)
+ rte_panic("Cannot allocate core info\n");
+
+ ci = get_core_info();
+
ret = rte_eal_init(argc, argv);
if (ret < 0)
rte_panic("Cannot init EAL\n");
@@ -280,51 +338,56 @@ main(int argc, char **argv)
nb_ports = rte_eth_dev_count_avail();
- mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
- MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
+ if (nb_ports > 0) {
+ mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
+ NUM_MBUFS * nb_ports, MBUF_CACHE_SIZE, 0,
+ RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
- if (mbuf_pool == NULL)
- rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
+ if (mbuf_pool == NULL)
+ rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
- /* Initialize ports. */
- RTE_ETH_FOREACH_DEV(portid) {
- struct ether_addr eth;
- int w, j;
- int ret;
+ /* Initialize ports. */
+ RTE_ETH_FOREACH_DEV(portid) {
+ struct ether_addr eth;
+ int w, j;
+ int ret;
- if ((enabled_port_mask & (1 << portid)) == 0)
- continue;
+ if ((enabled_port_mask & (1 << portid)) == 0)
+ continue;
- eth.addr_bytes[0] = 0xe0;
- eth.addr_bytes[1] = 0xe0;
- eth.addr_bytes[2] = 0xe0;
- eth.addr_bytes[3] = 0xe0;
- eth.addr_bytes[4] = portid + 0xf0;
+ eth.addr_bytes[0] = 0xe0;
+ eth.addr_bytes[1] = 0xe0;
+ eth.addr_bytes[2] = 0xe0;
+ eth.addr_bytes[3] = 0xe0;
+ eth.addr_bytes[4] = portid + 0xf0;
- if (port_init(portid, mbuf_pool) != 0)
- rte_exit(EXIT_FAILURE, "Cannot init port %"PRIu8 "\n",
+ if (port_init(portid, mbuf_pool) != 0)
+ rte_exit(EXIT_FAILURE,
+ "Cannot init port %"PRIu8 "\n",
portid);
- for (w = 0; w < MAX_VFS; w++) {
- eth.addr_bytes[5] = w + 0xf0;
-
- ret = rte_pmd_ixgbe_set_vf_mac_addr(portid,
- w, &eth);
- if (ret == -ENOTSUP)
- ret = rte_pmd_i40e_set_vf_mac_addr(portid,
- w, &eth);
- if (ret == -ENOTSUP)
- ret = rte_pmd_bnxt_set_vf_mac_addr(portid,
- w, &eth);
-
- switch (ret) {
- case 0:
- printf("Port %d VF %d MAC: ",
- portid, w);
- for (j = 0; j < 6; j++) {
- printf("%02x", eth.addr_bytes[j]);
- if (j < 5)
- printf(":");
+ for (w = 0; w < MAX_VFS; w++) {
+ eth.addr_bytes[5] = w + 0xf0;
+
+ ret = rte_pmd_ixgbe_set_vf_mac_addr(portid,
+ w, &eth);
+ if (ret == -ENOTSUP)
+ ret = rte_pmd_i40e_set_vf_mac_addr(
+ portid, w, &eth);
+ if (ret == -ENOTSUP)
+ ret = rte_pmd_bnxt_set_vf_mac_addr(
+ portid, w, &eth);
+
+ switch (ret) {
+ case 0:
+ printf("Port %d VF %d MAC: ",
+ portid, w);
+ for (j = 0; j < 5; j++) {
+ printf("%02x:",
+ eth.addr_bytes[j]);
+ }
+ printf("%02x\n", eth.addr_bytes[5]);
+ break;
}
printf("\n");
break;
@@ -332,16 +395,23 @@ main(int argc, char **argv)
}
}
+ check_all_ports_link_status(enabled_port_mask);
+
lcore_id = rte_get_next_lcore(-1, 1, 0);
if (lcore_id == RTE_MAX_LCORE) {
- RTE_LOG(ERR, EAL, "A minimum of two cores are required to run "
+ RTE_LOG(ERR, EAL, "A minimum of three cores are required to run "
"application\n");
return 0;
}
-
- check_all_ports_link_status(enabled_port_mask);
+ printf("Running channel monitor on lcore id %d\n", lcore_id);
rte_eal_remote_launch(run_monitor, NULL, lcore_id);
+ lcore_id = rte_get_next_lcore(lcore_id, 1, 0);
+ if (lcore_id == RTE_MAX_LCORE) {
+ RTE_LOG(ERR, EAL, "A minimum of three cores are required to run "
+ "application\n");
+ return 0;
+ }
if (power_manager_init() < 0) {
printf("Unable to initialize power manager\n");
return -1;
@@ -350,8 +420,17 @@ main(int argc, char **argv)
printf("Unable to initialize channel manager\n");
return -1;
}
+
+ printf("Running core monitor on lcore id %d\n", lcore_id);
+ rte_eal_remote_launch(run_core_monitor, NULL, lcore_id);
+
run_cli(NULL);
+ branch_monitor_exit();
+
rte_eal_mp_wait_lcore();
+
+ free(ci->cd);
+
return 0;
}
diff --git a/examples/vm_power_manager/oob_monitor.h b/examples/vm_power_manager/oob_monitor.h
new file mode 100644
index 00000000..b96e08df
--- /dev/null
+++ b/examples/vm_power_manager/oob_monitor.h
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#ifndef OOB_MONITOR_H_
+#define OOB_MONITOR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Setup the Branch Monitor resources required to initialize epoll.
+ * Must be called first before calling other functions.
+ *
+ * @return
+ * - 0 on success.
+ * - Negative on error.
+ */
+int branch_monitor_init(void);
+
+/**
+ * Run the OOB branch monitor, loops forever on on epoll_wait.
+ *
+ *
+ * @return
+ * None
+ */
+void run_branch_monitor(void);
+
+/**
+ * Exit the OOB Branch Monitor.
+ *
+ * @return
+ * None
+ */
+void branch_monitor_exit(void);
+
+/**
+ * Add a core to the list of cores to monitor.
+ *
+ * @param core
+ * Core Number
+ *
+ * @return
+ * - 0 on success.
+ * - Negative on error.
+ */
+int add_core_to_monitor(int core);
+
+/**
+ * Remove a previously added core from core list.
+ *
+ * @param core
+ * Core Number
+ *
+ * @return
+ * - 0 on success.
+ * - Negative on error.
+ */
+int remove_core_from_monitor(int core);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* OOB_MONITOR_H_ */
diff --git a/examples/vm_power_manager/oob_monitor_nop.c b/examples/vm_power_manager/oob_monitor_nop.c
new file mode 100644
index 00000000..7e7b8bc1
--- /dev/null
+++ b/examples/vm_power_manager/oob_monitor_nop.c
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2014 Intel Corporation
+ */
+
+#include "oob_monitor.h"
+
+void branch_monitor_exit(void)
+{
+}
+
+__attribute__((unused)) static float
+apply_policy(__attribute__((unused)) int core)
+{
+ return 0.0;
+}
+
+int
+add_core_to_monitor(__attribute__((unused)) int core)
+{
+ return 0;
+}
+
+int
+remove_core_from_monitor(__attribute__((unused)) int core)
+{
+ return 0;
+}
+
+int
+branch_monitor_init(void)
+{
+ return 0;
+}
+
+void
+run_branch_monitor(void)
+{
+}
diff --git a/examples/vm_power_manager/oob_monitor_x86.c b/examples/vm_power_manager/oob_monitor_x86.c
new file mode 100644
index 00000000..589c604e
--- /dev/null
+++ b/examples/vm_power_manager/oob_monitor_x86.c
@@ -0,0 +1,258 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <rte_log.h>
+
+#include "oob_monitor.h"
+#include "power_manager.h"
+#include "channel_manager.h"
+
+static volatile unsigned run_loop = 1;
+static uint64_t g_branches, g_branch_misses;
+static int g_active;
+
+void branch_monitor_exit(void)
+{
+ run_loop = 0;
+}
+
+/* Number of microseconds between each poll */
+#define INTERVAL 100
+#define PRINT_LOOP_COUNT (1000000/INTERVAL)
+#define IA32_PERFEVTSEL0 0x186
+#define IA32_PERFEVTSEL1 0x187
+#define IA32_PERFCTR0 0xc1
+#define IA32_PERFCTR1 0xc2
+#define IA32_PERFEVT_BRANCH_HITS 0x05300c4
+#define IA32_PERFEVT_BRANCH_MISS 0x05300c5
+
+static float
+apply_policy(int core)
+{
+ struct core_info *ci;
+ uint64_t counter;
+ uint64_t branches, branch_misses;
+ uint32_t last_branches, last_branch_misses;
+ int hits_diff, miss_diff;
+ float ratio;
+ int ret;
+
+ g_active = 0;
+ ci = get_core_info();
+
+ last_branches = ci->cd[core].last_branches;
+ last_branch_misses = ci->cd[core].last_branch_misses;
+
+ ret = pread(ci->cd[core].msr_fd, &counter,
+ sizeof(counter), IA32_PERFCTR0);
+ if (ret < 0)
+ RTE_LOG(ERR, POWER_MANAGER,
+ "unable to read counter for core %u\n",
+ core);
+ branches = counter;
+
+ ret = pread(ci->cd[core].msr_fd, &counter,
+ sizeof(counter), IA32_PERFCTR1);
+ if (ret < 0)
+ RTE_LOG(ERR, POWER_MANAGER,
+ "unable to read counter for core %u\n",
+ core);
+ branch_misses = counter;
+
+
+ ci->cd[core].last_branches = branches;
+ ci->cd[core].last_branch_misses = branch_misses;
+
+ hits_diff = (int)branches - (int)last_branches;
+ if (hits_diff <= 0) {
+ /* Likely a counter overflow condition, skip this round */
+ return -1.0;
+ }
+
+ miss_diff = (int)branch_misses - (int)last_branch_misses;
+ if (miss_diff <= 0) {
+ /* Likely a counter overflow condition, skip this round */
+ return -1.0;
+ }
+
+ g_branches = hits_diff;
+ g_branch_misses = miss_diff;
+
+ if (hits_diff < (INTERVAL*100)) {
+ /* Likely no workload running on this core. Skip. */
+ return -1.0;
+ }
+
+ ratio = (float)miss_diff * (float)100 / (float)hits_diff;
+
+ if (ratio < ci->branch_ratio_threshold)
+ power_manager_scale_core_min(core);
+ else
+ power_manager_scale_core_max(core);
+
+ g_active = 1;
+ return ratio;
+}
+
+int
+add_core_to_monitor(int core)
+{
+ struct core_info *ci;
+ char proc_file[UNIX_PATH_MAX];
+ int ret;
+
+ ci = get_core_info();
+
+ if (core < ci->core_count) {
+ long setup;
+
+ snprintf(proc_file, UNIX_PATH_MAX, "/dev/cpu/%d/msr", core);
+ ci->cd[core].msr_fd = open(proc_file, O_RDWR | O_SYNC);
+ if (ci->cd[core].msr_fd < 0) {
+ RTE_LOG(ERR, POWER_MANAGER,
+ "Error opening MSR file for core %d "
+ "(is msr kernel module loaded?)\n",
+ core);
+ return -1;
+ }
+ /*
+ * Set up branch counters
+ */
+ setup = IA32_PERFEVT_BRANCH_HITS;
+ ret = pwrite(ci->cd[core].msr_fd, &setup,
+ sizeof(setup), IA32_PERFEVTSEL0);
+ if (ret < 0) {
+ RTE_LOG(ERR, POWER_MANAGER,
+ "unable to set counter for core %u\n",
+ core);
+ return ret;
+ }
+ setup = IA32_PERFEVT_BRANCH_MISS;
+ ret = pwrite(ci->cd[core].msr_fd, &setup,
+ sizeof(setup), IA32_PERFEVTSEL1);
+ if (ret < 0) {
+ RTE_LOG(ERR, POWER_MANAGER,
+ "unable to set counter for core %u\n",
+ core);
+ return ret;
+ }
+ /*
+ * Close the file and re-open as read only so
+ * as not to hog the resource
+ */
+ close(ci->cd[core].msr_fd);
+ ci->cd[core].msr_fd = open(proc_file, O_RDONLY);
+ if (ci->cd[core].msr_fd < 0) {
+ RTE_LOG(ERR, POWER_MANAGER,
+ "Error opening MSR file for core %d "
+ "(is msr kernel module loaded?)\n",
+ core);
+ return -1;
+ }
+ ci->cd[core].oob_enabled = 1;
+ }
+ return 0;
+}
+
+int
+remove_core_from_monitor(int core)
+{
+ struct core_info *ci;
+ char proc_file[UNIX_PATH_MAX];
+ int ret;
+
+ ci = get_core_info();
+
+ if (ci->cd[core].oob_enabled) {
+ long setup;
+
+ /*
+ * close the msr file, then reopen rw so we can
+ * disable the counters
+ */
+ if (ci->cd[core].msr_fd != 0)
+ close(ci->cd[core].msr_fd);
+ snprintf(proc_file, UNIX_PATH_MAX, "/dev/cpu/%d/msr", core);
+ ci->cd[core].msr_fd = open(proc_file, O_RDWR | O_SYNC);
+ if (ci->cd[core].msr_fd < 0) {
+ RTE_LOG(ERR, POWER_MANAGER,
+ "Error opening MSR file for core %d "
+ "(is msr kernel module loaded?)\n",
+ core);
+ return -1;
+ }
+ setup = 0x0; /* clear event */
+ ret = pwrite(ci->cd[core].msr_fd, &setup,
+ sizeof(setup), IA32_PERFEVTSEL0);
+ if (ret < 0) {
+ RTE_LOG(ERR, POWER_MANAGER,
+ "unable to set counter for core %u\n",
+ core);
+ return ret;
+ }
+ setup = 0x0; /* clear event */
+ ret = pwrite(ci->cd[core].msr_fd, &setup,
+ sizeof(setup), IA32_PERFEVTSEL1);
+ if (ret < 0) {
+ RTE_LOG(ERR, POWER_MANAGER,
+ "unable to set counter for core %u\n",
+ core);
+ return ret;
+ }
+
+ close(ci->cd[core].msr_fd);
+ ci->cd[core].msr_fd = 0;
+ ci->cd[core].oob_enabled = 0;
+ }
+ return 0;
+}
+
+int
+branch_monitor_init(void)
+{
+ return 0;
+}
+
+void
+run_branch_monitor(void)
+{
+ struct core_info *ci;
+ int print = 0;
+ float ratio;
+ int printed;
+ int reads = 0;
+
+ ci = get_core_info();
+
+ while (run_loop) {
+
+ if (!run_loop)
+ break;
+ usleep(INTERVAL);
+ int j;
+ print++;
+ printed = 0;
+ for (j = 0; j < ci->core_count; j++) {
+ if (ci->cd[j].oob_enabled) {
+ ratio = apply_policy(j);
+ if ((print > PRINT_LOOP_COUNT) && (g_active)) {
+ printf(" %d: %.4f {%lu} {%d}", j,
+ ratio, g_branches,
+ reads);
+ printed = 1;
+ reads = 0;
+ } else {
+ reads++;
+ }
+ }
+ }
+ if (print > PRINT_LOOP_COUNT) {
+ if (printed)
+ printf("\n");
+ print = 0;
+ }
+ }
+}
diff --git a/examples/vm_power_manager/parse.c b/examples/vm_power_manager/parse.c
new file mode 100644
index 00000000..8231533b
--- /dev/null
+++ b/examples/vm_power_manager/parse.c
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2014 Intel Corporation.
+ * Copyright(c) 2014 6WIND S.A.
+ */
+
+#include <string.h>
+#include <rte_log.h>
+#include "parse.h"
+
+/*
+ * Parse elem, the elem could be single number/range or group
+ * 1) A single number elem, it's just a simple digit. e.g. 9
+ * 2) A single range elem, two digits with a '-' between. e.g. 2-6
+ * 3) A group elem, combines multiple 1) or 2) e.g 0,2-4,6
+ * Within group, '-' used for a range separator;
+ * ',' used for a single number.
+ */
+int
+parse_set(const char *input, uint16_t set[], unsigned int num)
+{
+ unsigned int idx;
+ const char *str = input;
+ char *end = NULL;
+ unsigned int min, max;
+
+ memset(set, 0, num * sizeof(uint16_t));
+
+ while (isblank(*str))
+ str++;
+
+ /* only digit or left bracket is qualify for start point */
+ if (!isdigit(*str) || *str == '\0')
+ return -1;
+
+ while (isblank(*str))
+ str++;
+ if (*str == '\0')
+ return -1;
+
+ min = num;
+ do {
+
+ /* go ahead to the first digit */
+ while (isblank(*str))
+ str++;
+ if (!isdigit(*str))
+ return -1;
+
+ /* get the digit value */
+ errno = 0;
+ idx = strtoul(str, &end, 10);
+ if (errno || end == NULL || idx >= num)
+ return -1;
+
+ /* go ahead to separator '-' and ',' */
+ while (isblank(*end))
+ end++;
+ if (*end == '-') {
+ if (min == num)
+ min = idx;
+ else /* avoid continuous '-' */
+ return -1;
+ } else if ((*end == ',') || (*end == '\0')) {
+ max = idx;
+
+ if (min == num)
+ min = idx;
+
+ for (idx = RTE_MIN(min, max);
+ idx <= RTE_MAX(min, max); idx++) {
+ set[idx] = 1;
+ }
+ min = num;
+ } else
+ return -1;
+
+ str = end + 1;
+ } while (*end != '\0');
+
+ return str - input;
+}
diff --git a/examples/vm_power_manager/parse.h b/examples/vm_power_manager/parse.h
new file mode 100644
index 00000000..a5971e9a
--- /dev/null
+++ b/examples/vm_power_manager/parse.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#ifndef PARSE_H_
+#define PARSE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int
+parse_set(const char *, uint16_t [], unsigned int);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* PARSE_H_ */
diff --git a/examples/vm_power_manager/power_manager.c b/examples/vm_power_manager/power_manager.c
index 35db2559..b7769c3c 100644
--- a/examples/vm_power_manager/power_manager.c
+++ b/examples/vm_power_manager/power_manager.c
@@ -12,20 +12,21 @@
#include <dirent.h>
#include <errno.h>
+#include <sys/sysinfo.h>
#include <sys/types.h>
#include <rte_log.h>
#include <rte_power.h>
#include <rte_spinlock.h>
+#include "channel_manager.h"
#include "power_manager.h"
-
-#define RTE_LOGTYPE_POWER_MANAGER RTE_LOGTYPE_USER1
+#include "oob_monitor.h"
#define POWER_SCALE_CORE(DIRECTION, core_num , ret) do { \
- if (core_num >= POWER_MGR_MAX_CPUS) \
+ if (core_num >= ci.core_count) \
return -1; \
- if (!(global_enabled_cpus & (1ULL << core_num))) \
+ if (!(ci.cd[core_num].global_enabled_cpus)) \
return -1; \
rte_spinlock_lock(&global_core_freq_info[core_num].power_sl); \
ret = rte_power_freq_##DIRECTION(core_num); \
@@ -36,7 +37,7 @@
int i; \
for (i = 0; core_mask; core_mask &= ~(1 << i++)) { \
if ((core_mask >> i) & 1) { \
- if (!(global_enabled_cpus & (1ULL << i))) \
+ if (!(ci.cd[i].global_enabled_cpus)) \
continue; \
rte_spinlock_lock(&global_core_freq_info[i].power_sl); \
if (rte_power_freq_##DIRECTION(i) != 1) \
@@ -54,63 +55,82 @@ struct freq_info {
static struct freq_info global_core_freq_info[POWER_MGR_MAX_CPUS];
-static uint64_t global_enabled_cpus;
+struct core_info ci;
#define SYSFS_CPU_PATH "/sys/devices/system/cpu/cpu%u/topology/core_id"
-static unsigned
-set_host_cpus_mask(void)
+struct core_info *
+get_core_info(void)
{
- char path[PATH_MAX];
- unsigned i;
- unsigned num_cpus = 0;
-
- for (i = 0; i < POWER_MGR_MAX_CPUS; i++) {
- snprintf(path, sizeof(path), SYSFS_CPU_PATH, i);
- if (access(path, F_OK) == 0) {
- global_enabled_cpus |= 1ULL << i;
- num_cpus++;
- } else
- return num_cpus;
+ return &ci;
+}
+
+int
+core_info_init(void)
+{
+ struct core_info *ci;
+ int i;
+
+ ci = get_core_info();
+
+ ci->core_count = get_nprocs_conf();
+ ci->branch_ratio_threshold = BRANCH_RATIO_THRESHOLD;
+ ci->cd = malloc(ci->core_count * sizeof(struct core_details));
+ if (!ci->cd) {
+ RTE_LOG(ERR, POWER_MANAGER, "Failed to allocate memory for core info.");
+ return -1;
}
- return num_cpus;
+ for (i = 0; i < ci->core_count; i++) {
+ ci->cd[i].global_enabled_cpus = 1;
+ ci->cd[i].oob_enabled = 0;
+ ci->cd[i].msr_fd = 0;
+ }
+ printf("%d cores in system\n", ci->core_count);
+ return 0;
}
int
power_manager_init(void)
{
- unsigned int i, num_cpus, num_freqs;
- uint64_t cpu_mask;
+ unsigned int i, num_cpus = 0, num_freqs = 0;
int ret = 0;
+ struct core_info *ci;
+
+ rte_power_set_env(PM_ENV_ACPI_CPUFREQ);
- num_cpus = set_host_cpus_mask();
- if (num_cpus == 0) {
- RTE_LOG(ERR, POWER_MANAGER, "Unable to detected host CPUs, please "
- "ensure that sufficient privileges exist to inspect sysfs\n");
+ ci = get_core_info();
+ if (!ci) {
+ RTE_LOG(ERR, POWER_MANAGER,
+ "Failed to get core info!\n");
return -1;
}
- rte_power_set_env(PM_ENV_ACPI_CPUFREQ);
- cpu_mask = global_enabled_cpus;
- for (i = 0; cpu_mask; cpu_mask &= ~(1 << i++)) {
- if (rte_power_init(i) < 0)
- RTE_LOG(ERR, POWER_MANAGER,
- "Unable to initialize power manager "
- "for core %u\n", i);
- num_freqs = rte_power_freqs(i, global_core_freq_info[i].freqs,
+
+ for (i = 0; i < ci->core_count; i++) {
+ if (ci->cd[i].global_enabled_cpus) {
+ if (rte_power_init(i) < 0)
+ RTE_LOG(ERR, POWER_MANAGER,
+ "Unable to initialize power manager "
+ "for core %u\n", i);
+ num_cpus++;
+ num_freqs = rte_power_freqs(i,
+ global_core_freq_info[i].freqs,
RTE_MAX_LCORE_FREQS);
- if (num_freqs == 0) {
- RTE_LOG(ERR, POWER_MANAGER,
- "Unable to get frequency list for core %u\n",
- i);
- global_enabled_cpus &= ~(1 << i);
- num_cpus--;
- ret = -1;
+ if (num_freqs == 0) {
+ RTE_LOG(ERR, POWER_MANAGER,
+ "Unable to get frequency list for core %u\n",
+ i);
+ ci->cd[i].oob_enabled = 0;
+ ret = -1;
+ }
+ global_core_freq_info[i].num_freqs = num_freqs;
+
+ rte_spinlock_init(&global_core_freq_info[i].power_sl);
}
- global_core_freq_info[i].num_freqs = num_freqs;
- rte_spinlock_init(&global_core_freq_info[i].power_sl);
+ if (ci->cd[i].oob_enabled)
+ add_core_to_monitor(i);
}
- RTE_LOG(INFO, POWER_MANAGER, "Detected %u host CPUs , enabled core mask:"
- " 0x%"PRIx64"\n", num_cpus, global_enabled_cpus);
+ RTE_LOG(INFO, POWER_MANAGER, "Managing %u cores out of %u available host cores\n",
+ num_cpus, ci->core_count);
return ret;
}
@@ -125,7 +145,7 @@ power_manager_get_current_frequency(unsigned core_num)
core_num, POWER_MGR_MAX_CPUS-1);
return -1;
}
- if (!(global_enabled_cpus & (1ULL << core_num)))
+ if (!(ci.cd[core_num].global_enabled_cpus))
return 0;
rte_spinlock_lock(&global_core_freq_info[core_num].power_sl);
@@ -144,15 +164,26 @@ power_manager_exit(void)
{
unsigned int i;
int ret = 0;
+ struct core_info *ci;
+
+ ci = get_core_info();
+ if (!ci) {
+ RTE_LOG(ERR, POWER_MANAGER,
+ "Failed to get core info!\n");
+ return -1;
+ }
- for (i = 0; global_enabled_cpus; global_enabled_cpus &= ~(1 << i++)) {
- if (rte_power_exit(i) < 0) {
- RTE_LOG(ERR, POWER_MANAGER, "Unable to shutdown power manager "
- "for core %u\n", i);
- ret = -1;
+ for (i = 0; i < ci->core_count; i++) {
+ if (ci->cd[i].global_enabled_cpus) {
+ if (rte_power_exit(i) < 0) {
+ RTE_LOG(ERR, POWER_MANAGER, "Unable to shutdown power manager "
+ "for core %u\n", i);
+ ret = -1;
+ }
+ ci->cd[i].global_enabled_cpus = 0;
}
+ remove_core_from_monitor(i);
}
- global_enabled_cpus = 0;
return ret;
}
@@ -268,10 +299,12 @@ int
power_manager_scale_core_med(unsigned int core_num)
{
int ret = 0;
+ struct core_info *ci;
+ ci = get_core_info();
if (core_num >= POWER_MGR_MAX_CPUS)
return -1;
- if (!(global_enabled_cpus & (1ULL << core_num)))
+ if (!(ci->cd[core_num].global_enabled_cpus))
return -1;
rte_spinlock_lock(&global_core_freq_info[core_num].power_sl);
ret = rte_power_set_freq(core_num,
diff --git a/examples/vm_power_manager/power_manager.h b/examples/vm_power_manager/power_manager.h
index 8a8a84aa..605b3c8f 100644
--- a/examples/vm_power_manager/power_manager.h
+++ b/examples/vm_power_manager/power_manager.h
@@ -8,6 +8,29 @@
#ifdef __cplusplus
extern "C" {
#endif
+struct core_details {
+ uint64_t last_branches;
+ uint64_t last_branch_misses;
+ uint16_t global_enabled_cpus;
+ uint16_t oob_enabled;
+ int msr_fd;
+};
+
+struct core_info {
+ uint16_t core_count;
+ struct core_details *cd;
+ float branch_ratio_threshold;
+};
+
+#define BRANCH_RATIO_THRESHOLD 0.1
+
+struct core_info *
+get_core_info(void);
+
+int
+core_info_init(void);
+
+#define RTE_LOGTYPE_POWER_MANAGER RTE_LOGTYPE_USER1
/* Maximum number of CPUS to manage */
#define POWER_MGR_MAX_CPUS 64
diff --git a/examples/vmdq/main.c b/examples/vmdq/main.c
index 52596dd5..627a5da4 100644
--- a/examples/vmdq/main.c
+++ b/examples/vmdq/main.c
@@ -65,7 +65,6 @@ static const struct rte_eth_conf vmdq_conf_default = {
.rxmode = {
.mq_mode = ETH_MQ_RX_VMDQ_ONLY,
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
},
.txmode = {
@@ -237,7 +236,6 @@ port_init(uint16_t port, struct rte_mempool *mbuf_pool)
rxconf = &dev_info.default_rxconf;
rxconf->rx_drop_en = 1;
txconf = &dev_info.default_txconf;
- txconf->txq_flags = ETH_TXQ_FLAGS_IGNORE;
txconf->offloads = port_conf.txmode.offloads;
for (q = 0; q < rxRings; q++) {
retval = rte_eth_rx_queue_setup(port, q, rxRingSize,
diff --git a/examples/vmdq_dcb/main.c b/examples/vmdq_dcb/main.c
index 2626a2f1..64636839 100644
--- a/examples/vmdq_dcb/main.c
+++ b/examples/vmdq_dcb/main.c
@@ -71,7 +71,6 @@ static const struct rte_eth_conf vmdq_dcb_conf_default = {
.rxmode = {
.mq_mode = ETH_MQ_RX_VMDQ_DCB,
.split_hdr_size = 0,
- .ignore_offload_bitfield = 1,
},
.txmode = {
.mq_mode = ETH_MQ_TX_VMDQ_DCB,
@@ -197,6 +196,7 @@ port_init(uint16_t port, struct rte_mempool *mbuf_pool)
uint16_t queues_per_pool;
uint32_t max_nb_pools;
struct rte_eth_txconf txq_conf;
+ uint64_t rss_hf_tmp;
/*
* The max pool number from dev_info will be used to validate the pool
@@ -257,6 +257,18 @@ port_init(uint16_t port, struct rte_mempool *mbuf_pool)
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
port_conf.txmode.offloads |=
DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+
+ rss_hf_tmp = port_conf.rx_adv_conf.rss_conf.rss_hf;
+ port_conf.rx_adv_conf.rss_conf.rss_hf &=
+ dev_info.flow_type_rss_offloads;
+ if (port_conf.rx_adv_conf.rss_conf.rss_hf != rss_hf_tmp) {
+ printf("Port %u modified RSS hash function based on hardware support,"
+ "requested:%#"PRIx64" configured:%#"PRIx64"\n",
+ port,
+ rss_hf_tmp,
+ port_conf.rx_adv_conf.rss_conf.rss_hf);
+ }
+
/*
* Though in this example, all queues including pf queues are setup.
* This is because VMDQ queues doesn't always start from zero, and the
@@ -290,7 +302,6 @@ port_init(uint16_t port, struct rte_mempool *mbuf_pool)
}
txq_conf = dev_info.default_txconf;
- txq_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE;
txq_conf.offloads = port_conf.txmode.offloads;
for (q = 0; q < num_queues; q++) {
retval = rte_eth_tx_queue_setup(port, q, txRingSize,