summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Simonart <xavier.simonart@intel.com>2018-04-14 17:19:41 +0200
committerXavier Simonart <xavier.simonart@intel.com>2018-04-15 15:41:16 +0200
commite9da2a14ec116912033a88f08261bc193a9c445d (patch)
tree20760f8b999789778c37c9d738ca73ed785bb275
parent3981ce6fed44db09af235100526ab8bc1666e38e (diff)
Add support for reception of jumbo frames
Jumbo frames are now supported through the addition of a "mtu" parameter of the port in the config file. Setting the mtu to a value higher than 1500 bytes will enable the reception of jumbo frames. In addition, the rte_eth_dev_set_mtu is now set for all pmds. Finally, setting mbuf_size does not set MEMPOOL_F_NO_SPREAD anymore. This option was only used for pure debugging. Big packets can be received using two ways - Using multiple "small" mbufs, i.e. around 2K. This is the default. - Using one big mbuf holding the whole packet. This can be enabled by setting a parameter mbuf_size in the receiving core configuration Change-Id: Idd60ad31f41c89f9522dff4d894af2696b7a2ea1 Signed-off-by: Xavier Simonart <xavier.simonart@intel.com>
-rw-r--r--VNFs/DPPD-PROX/main.c96
-rw-r--r--VNFs/DPPD-PROX/prox_args.c14
-rw-r--r--VNFs/DPPD-PROX/prox_port_cfg.c10
3 files changed, 81 insertions, 39 deletions
diff --git a/VNFs/DPPD-PROX/main.c b/VNFs/DPPD-PROX/main.c
index 2c8517f0..931b30c5 100644
--- a/VNFs/DPPD-PROX/main.c
+++ b/VNFs/DPPD-PROX/main.c
@@ -285,6 +285,7 @@ static void configure_if_tx_queues(struct task_args *targ, uint8_t socket)
static void configure_if_rx_queues(struct task_args *targ, uint8_t socket)
{
+ struct prox_port_cfg *port;
for (int i = 0; i < targ->nb_rxports; i++) {
uint8_t if_port = targ->rx_port_queue[i].port;
@@ -293,15 +294,23 @@ static void configure_if_rx_queues(struct task_args *targ, uint8_t socket)
}
PROX_PANIC(!prox_port_cfg[if_port].active, "Port %u not used, aborting...\n", if_port);
+ port = &prox_port_cfg[if_port];
- if(prox_port_cfg[if_port].rx_ring[0] != '\0') {
- prox_port_cfg[if_port].n_rxq = 0;
+ if(port->rx_ring[0] != '\0') {
+ port->n_rxq = 0;
}
+ // Force multi segment support if mbuf size is not big enough.
+ // This is usually the case when setting a big mtu size i.e. enabling jumbo frames.
+ uint16_t max_frame_size = port->mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + 2 * PROX_VLAN_TAG_SIZE;
+ if (max_frame_size + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM > targ->mbuf_size) {
+ targ->task_init->flag_features &= ~TASK_FEATURE_TXQ_FLAGS_NOMULTSEGS;
+ plog_info("\t\tDisabling No MultSegs on port %u as %lu > %u\n", if_port, max_frame_size + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM, targ->mbuf_size);
+ }
targ->rx_port_queue[i].queue = prox_port_cfg[if_port].n_rxq;
- prox_port_cfg[if_port].pool[targ->rx_port_queue[i].queue] = targ->pool;
- prox_port_cfg[if_port].pool_size[targ->rx_port_queue[i].queue] = targ->nb_mbuf - 1;
- prox_port_cfg[if_port].n_rxq++;
+ port->pool[targ->rx_port_queue[i].queue] = targ->pool;
+ port->pool_size[targ->rx_port_queue[i].queue] = targ->nb_mbuf - 1;
+ port->n_rxq++;
int dsocket = prox_port_cfg[if_port].socket;
if (dsocket != -1 && dsocket != socket) {
@@ -319,8 +328,8 @@ static void configure_if_queues(void)
while (core_targ_next(&lconf, &targ, 0) == 0) {
socket = rte_lcore_to_socket_id(lconf->id);
- configure_if_tx_queues(targ, socket);
configure_if_rx_queues(targ, socket);
+ configure_if_tx_queues(targ, socket);
}
}
@@ -578,6 +587,52 @@ static void shuffle_mempool(struct rte_mempool* mempool, uint32_t nb_mbuf)
prox_free(pkts);
}
+static void set_mbuf_size(struct task_args *targ)
+{
+ /* mbuf size can be set
+ * - from config file (highest priority, overwriting any other config) - should only be used as workaround
+ * - through each 'mode', overwriting the default mbuf_size
+ * - defaulted to MBUF_SIZE i.e. 1518 Bytes
+ * Except if set explicitely, ensure that size is big enough for vmxnet3 driver
+ */
+ if (targ->mbuf_size_set_explicitely)
+ return;
+
+ if (targ->task_init->mbuf_size != 0) {
+ /* mbuf_size not set through config file but set through mode */
+ targ->mbuf_size = targ->task_init->mbuf_size;
+ }
+
+ struct prox_port_cfg *port;
+ uint16_t max_frame_size = 0;
+ for (int i = 0; i < targ->nb_rxports; i++) {
+ uint8_t if_port = targ->rx_port_queue[i].port;
+
+ if (if_port == OUT_DISCARD) {
+ continue;
+ }
+ port = &prox_port_cfg[if_port];
+ if (max_frame_size < port->mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + 2 * PROX_VLAN_TAG_SIZE)
+ max_frame_size = port->mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + 2 * PROX_VLAN_TAG_SIZE;
+
+ if (strcmp(port->short_name, "vmxnet3") == 0) {
+ if (targ->mbuf_size < MBUF_SIZE + RTE_PKTMBUF_HEADROOM)
+ targ->mbuf_size = MBUF_SIZE + RTE_PKTMBUF_HEADROOM;
+ if (targ->mbuf_size < max_frame_size)
+ targ->mbuf_size = max_frame_size + RTE_PKTMBUF_HEADROOM;
+ }
+ }
+ if (max_frame_size) {
+ // i40e supports a maximum of 5 descriptors chained
+ uint16_t required_mbuf_size = RTE_ALIGN(max_frame_size / 5, 128) + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM;
+ if (required_mbuf_size > targ->mbuf_size) {
+ targ->mbuf_size = required_mbuf_size;
+ plog_info("\t\tSetting mbuf_size to %u to support frame_size %u (mtu %u)\n", targ->mbuf_size, max_frame_size, port->mtu);
+ }
+ }
+
+}
+
static void setup_mempools_unique_per_socket(void)
{
uint32_t flags = 0;
@@ -595,11 +650,7 @@ static void setup_mempools_unique_per_socket(void)
uint8_t socket = rte_lcore_to_socket_id(lconf->id);
PROX_ASSERT(socket < MAX_SOCKETS);
- if (targ->mbuf_size_set_explicitely)
- flags = MEMPOOL_F_NO_SPREAD;
- if ((!targ->mbuf_size_set_explicitely) && (targ->task_init->mbuf_size != 0)) {
- targ->mbuf_size = targ->task_init->mbuf_size;
- }
+ set_mbuf_size(targ);
if (targ->rx_port_queue[0].port != OUT_DISCARD) {
struct prox_port_cfg* port_cfg = &prox_port_cfg[targ->rx_port_queue[0].port];
PROX_ASSERT(targ->nb_mbuf != 0);
@@ -616,10 +667,6 @@ static void setup_mempools_unique_per_socket(void)
PROX_PANIC(mbuf_size[socket] != targ->mbuf_size,
"all mbuf_size must have the same size if using a unique mempool per socket\n");
}
- if ((!targ->mbuf_size_set_explicitely) && (strcmp(port_cfg->short_name, "vmxnet3") == 0)) {
- if (mbuf_size[socket] < MBUF_SIZE + RTE_PKTMBUF_HEADROOM)
- mbuf_size[socket] = MBUF_SIZE + RTE_PKTMBUF_HEADROOM;
- }
}
}
for (int i = 0 ; i < MAX_SOCKETS; i++) {
@@ -668,24 +715,7 @@ static void setup_mempool_for_rx_task(struct lcore_cfg *lconf, struct task_args
char memzone_name[64];
char name[64];
- /* mbuf size can be set
- * - from config file (highest priority, overwriting any other config) - should only be used as workaround
- * - through each 'mode', overwriting the default mbuf_size
- * - defaulted to MBUF_SIZE i.e. 1518 Bytes
- * Except is set expliciteky, ensure that size is big enough for vmxnet3 driver
- */
- if (targ->mbuf_size_set_explicitely) {
- flags = MEMPOOL_F_NO_SPREAD;
- /* targ->mbuf_size already set */
- }
- else if (targ->task_init->mbuf_size != 0) {
- /* mbuf_size not set through config file but set through mode */
- targ->mbuf_size = targ->task_init->mbuf_size;
- }
- else if (strcmp(port_cfg->short_name, "vmxnet3") == 0) {
- if (targ->mbuf_size < MBUF_SIZE + RTE_PKTMBUF_HEADROOM)
- targ->mbuf_size = MBUF_SIZE + RTE_PKTMBUF_HEADROOM;
- }
+ set_mbuf_size(targ);
/* allocate memory pool for packets */
PROX_ASSERT(targ->nb_mbuf != 0);
diff --git a/VNFs/DPPD-PROX/prox_args.c b/VNFs/DPPD-PROX/prox_args.c
index 08f27e9e..53223cad 100644
--- a/VNFs/DPPD-PROX/prox_args.c
+++ b/VNFs/DPPD-PROX/prox_args.c
@@ -546,6 +546,20 @@ static int get_port_cfg(unsigned sindex, char *str, void *data)
}
cfg->port_conf.rxmode.hw_strip_crc = val;
}
+ else if (STR_EQ(str, "mtu size")) {
+ uint32_t val;
+ if (parse_int(&val, pkey)) {
+ return -1;
+ }
+ if (val) {
+ cfg->mtu = val;
+ if (cfg->mtu + ETHER_HDR_LEN + ETHER_CRC_LEN > ETHER_MAX_LEN) {
+ cfg->port_conf.rxmode.max_rx_pkt_len = cfg->mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + 2 * PROX_VLAN_TAG_SIZE;
+ cfg->port_conf.rxmode.jumbo_frame = 1;
+ }
+ }
+ }
+
else if (STR_EQ(str, "rss")) {
uint32_t val;
if (parse_bool(&val, pkey)) {
diff --git a/VNFs/DPPD-PROX/prox_port_cfg.c b/VNFs/DPPD-PROX/prox_port_cfg.c
index c4787b1e..c00948ad 100644
--- a/VNFs/DPPD-PROX/prox_port_cfg.c
+++ b/VNFs/DPPD-PROX/prox_port_cfg.c
@@ -294,12 +294,10 @@ static void init_port(struct prox_port_cfg *port_cfg)
port_cfg->socket, port_cfg->n_rxd);
dummy_pool_name[0]++;
} else {
- // Most pmd do not support setting mtu yet...
- if (!strcmp(port_cfg->short_name, "ixgbe")) {
- plog_info("\t\tSetting MTU size to %u for port %u ...\n", port_cfg->mtu, port_id);
- ret = rte_eth_dev_set_mtu(port_id, port_cfg->mtu);
- PROX_PANIC(ret < 0, "\n\t\t\trte_eth_dev_set_mtu() failed on port %u: error %d\n", port_id, ret);
- }
+ // Most pmd should now support setting mtu
+ plog_info("\t\tSetting MTU size to %u for port %u ...\n", port_cfg->mtu, port_id);
+ ret = rte_eth_dev_set_mtu(port_id, port_cfg->mtu);
+ PROX_PANIC(ret < 0, "\n\t\t\trte_eth_dev_set_mtu() failed on port %u: error %d\n", port_id, ret);
if (port_cfg->n_txq == 0) {
/* not sending on this port */