static clib_error_t *
dpdk_lib_init (dpdk_main_t * dm)
{
+ vnet_main_t *vnm = vnet_get_main ();
u32 nports;
u32 mtu, max_rx_frame;
int i;
if (CLIB_DEBUG > 0)
dpdk_log_notice ("DPDK drivers found %d ports...", nports);
- if (dm->conf->enable_tcp_udp_checksum)
- dm->buffer_flags_template &= ~(VNET_BUFFER_F_L4_CHECKSUM_CORRECT
- | VNET_BUFFER_F_L4_CHECKSUM_COMPUTED);
-
/* vlib_buffer_t template */
vec_validate_aligned (dm->per_thread_data, tm->n_vlib_mains - 1,
CLIB_CACHE_LINE_BYTES);
{
dpdk_per_thread_data_t *ptd = vec_elt_at_index (dm->per_thread_data, i);
clib_memset (&ptd->buffer_template, 0, sizeof (vlib_buffer_t));
- ptd->buffer_template.flags = dm->buffer_flags_template;
vnet_buffer (&ptd->buffer_template)->sw_if_index[VLIB_TX] = (u32) ~ 0;
}
RTE_ETH_FOREACH_DEV(i)
{
u8 addr[6];
- int vlan_off;
struct rte_eth_dev_info dev_info;
struct rte_pci_device *pci_dev;
struct rte_vmbus_device *vmbus_dev;
if (vmbus_dev)
{
unformat_input_t input_vmbus;
-
- unformat_init_vector (&input_vmbus, (u8 *) dev_info.device->name);
+ unformat_init_string (&input_vmbus, dev_info.device->name,
+ strlen (dev_info.device->name));
if (unformat (&input_vmbus, "%U", unformat_vlib_vmbus_addr,
&vmbus_addr))
{
p = mhash_get (&dm->conf->device_config_index_by_vmbus_addr,
&vmbus_addr);
}
+ unformat_free (&input_vmbus);
}
if (p)
xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_UDP_CKSUM;
if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_CKSUM)
xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_TCP_CKSUM;
+ if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM)
+ xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_IPV4_CKSUM;
+
+ if (dm->conf->enable_outer_checksum_offload)
+ {
+ if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM)
+ xd->port_conf.txmode.offloads |=
+ DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM;
+ if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_OUTER_UDP_CKSUM)
+ xd->port_conf.txmode.offloads |=
+ DEV_TX_OFFLOAD_OUTER_UDP_CKSUM;
+ }
}
+ if (dm->conf->enable_lro)
+ {
+ if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_LRO)
+ {
+ xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_TCP_LRO;
+ if (devconf->max_lro_pkt_size)
+ xd->port_conf.rxmode.max_lro_pkt_size =
+ devconf->max_lro_pkt_size;
+ else
+ xd->port_conf.rxmode.max_lro_pkt_size =
+ DPDK_MAX_LRO_SIZE_DEFAULT;
+ }
+ }
if (dm->conf->no_multi_seg)
{
xd->port_conf.txmode.offloads &= ~DEV_TX_OFFLOAD_MULTI_SEGS;
vec_validate_aligned (xd->rx_queues, xd->rx_q_used - 1,
CLIB_CACHE_LINE_BYTES);
- xd->flags |= DPDK_DEVICE_FLAG_PMD;
-
/* workaround for drivers not setting driver_name */
if ((!dev_info.driver_name) && (pci_dev))
dev_info.driver_name = pci_dev->driver->driver.name;
/* Drivers with valid speed_capa set */
case VNET_DPDK_PMD_I40E:
xd->flags |= DPDK_DEVICE_FLAG_INT_UNMASKABLE;
+ /* fall through */
case VNET_DPDK_PMD_E1000EM:
case VNET_DPDK_PMD_IGB:
case VNET_DPDK_PMD_IGC:
{
xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_CKSUM;
xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_UDP_CKSUM;
- xd->flags |=
- DPDK_DEVICE_FLAG_TX_OFFLOAD |
- DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM;
+ xd->flags |= DPDK_DEVICE_FLAG_TX_OFFLOAD |
+ DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM;
}
xd->port_conf.intr_conf.rxq = 1;
break;
+ case VNET_DPDK_PMD_MLX5:
+ if (dm->conf->no_tx_checksum_offload == 0)
+ {
+ xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_CKSUM;
+ xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_UDP_CKSUM;
+ xd->flags |= DPDK_DEVICE_FLAG_TX_OFFLOAD |
+ DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM;
+ }
+ xd->port_type = port_type_from_speed_capa (&dev_info);
+ break;
case VNET_DPDK_PMD_CXGBE:
case VNET_DPDK_PMD_MLX4:
- case VNET_DPDK_PMD_MLX5:
case VNET_DPDK_PMD_QEDE:
case VNET_DPDK_PMD_BNXT:
xd->port_type = port_type_from_speed_capa (&dev_info);
/* SR-IOV VFs */
case VNET_DPDK_PMD_I40EVF:
xd->flags |= DPDK_DEVICE_FLAG_INT_UNMASKABLE;
+ /* fall through */
case VNET_DPDK_PMD_IGBVF:
case VNET_DPDK_PMD_IXGBEVF:
xd->port_type = VNET_DPDK_PORT_TYPE_ETH_VF;
xd->port_type = VNET_DPDK_PORT_TYPE_ETH_VF;
xd->port_conf.rxmode.offloads &= ~DEV_RX_OFFLOAD_SCATTER;
xd->port_conf.intr_conf.rxq = 1;
+ if (dm->conf->no_tx_checksum_offload == 0)
+ {
+ xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_IPV4_CKSUM;
+ xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_CKSUM;
+ xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_UDP_CKSUM;
+ xd->flags |= DPDK_DEVICE_FLAG_TX_OFFLOAD;
+ }
break;
case VNET_DPDK_PMD_DPAA2:
case VNET_DPDK_PMD_VMXNET3:
xd->port_type = VNET_DPDK_PORT_TYPE_ETH_1G;
xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_MULTI_SEGS;
+ /* TCP csum offload not working although udp might work. Left
+ * disabled for now */
+ if (0 && (dm->conf->no_tx_checksum_offload == 0))
+ {
+ xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_IPV4_CKSUM;
+ xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_CKSUM;
+ xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_UDP_CKSUM;
+ xd->flags |= DPDK_DEVICE_FLAG_TX_OFFLOAD;
+ }
break;
case VNET_DPDK_PMD_AF_PACKET:
/* assign interface to input thread */
int q;
- error = ethernet_register_interface
- (dm->vnet_main, dpdk_device_class.index, xd->device_index,
- /* ethernet address */ addr,
- &xd->hw_if_index, dpdk_flag_change);
+ error = ethernet_register_interface (
+ vnm, dpdk_device_class.index, xd->device_index,
+ /* ethernet address */ addr, &xd->hw_if_index, dpdk_flag_change);
if (error)
return error;
/*Set port rxmode config */
xd->port_conf.rxmode.max_rx_pkt_len = max_rx_frame;
- sw = vnet_get_hw_sw_interface (dm->vnet_main, xd->hw_if_index);
+ sw = vnet_get_hw_sw_interface (vnm, xd->hw_if_index);
xd->sw_if_index = sw->sw_if_index;
- vnet_hw_if_set_input_node (dm->vnet_main, xd->hw_if_index,
- dpdk_input_node.index);
+ vnet_hw_if_set_input_node (vnm, xd->hw_if_index, dpdk_input_node.index);
if (devconf->workers)
{
- int i;
+ int j;
q = 0;
- clib_bitmap_foreach (i, devconf->workers) {
+ clib_bitmap_foreach (j, devconf->workers)
+ {
dpdk_rx_queue_t *rxq = vec_elt_at_index (xd->rx_queues, q);
rxq->queue_index = vnet_hw_if_register_rx_queue (
- dm->vnet_main, xd->hw_if_index, q++,
- vdm->first_worker_thread_index + i);
- }
+ vnm, xd->hw_if_index, q++, vdm->first_worker_thread_index + j);
+ }
}
else
for (q = 0; q < xd->rx_q_used; q++)
{
dpdk_rx_queue_t *rxq = vec_elt_at_index (xd->rx_queues, q);
rxq->queue_index = vnet_hw_if_register_rx_queue (
- dm->vnet_main, xd->hw_if_index, q, VNET_HW_IF_RXQ_THREAD_ANY);
+ vnm, xd->hw_if_index, q, VNET_HW_IF_RXQ_THREAD_ANY);
}
- vnet_hw_if_update_runtime_data (dm->vnet_main, xd->hw_if_index);
+ vnet_hw_if_update_runtime_data (vnm, xd->hw_if_index);
/*Get vnet hardware interface */
- hi = vnet_get_hw_interface (dm->vnet_main, xd->hw_if_index);
+ hi = vnet_get_hw_interface (vnm, xd->hw_if_index);
/*Override default max_packet_bytes and max_supported_bytes set in
* ethernet_register_interface() above*/
/* Indicate ability to support L3 DMAC filtering and
* initialize interface to L3 non-promisc mode */
hi->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_MAC_FILTER;
- ethernet_set_flags (dm->vnet_main, xd->hw_if_index,
- ETHERNET_INTERFACE_FLAG_DEFAULT_L3);
+ ethernet_set_flags (vnm, xd->hw_if_index,
+ ETHERNET_INTERFACE_FLAG_DEFAULT_L3);
}
if (dm->conf->no_tx_checksum_offload == 0)
hi->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_TX_IP4_CKSUM |
VNET_HW_INTERFACE_CAP_SUPPORTS_TX_TCP_CKSUM |
VNET_HW_INTERFACE_CAP_SUPPORTS_TX_UDP_CKSUM;
+ if (dm->conf->enable_outer_checksum_offload)
+ {
+ hi->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_TX_IP4_OUTER_CKSUM |
+ VNET_HW_INTERFACE_CAP_SUPPORTS_TX_UDP_OUTER_CKSUM;
+ }
}
if (devconf->tso == DPDK_DEVICE_TSO_ON && hi != NULL)
{
if ((dm->conf->enable_tcp_udp_checksum) &&
(hi->caps & VNET_HW_INTERFACE_CAP_SUPPORTS_TX_CKSUM))
{
- hi->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO |
- VNET_HW_INTERFACE_CAP_SUPPORTS_UDP_GSO;
- xd->port_conf.txmode.offloads |=
- DEV_TX_OFFLOAD_TCP_TSO | DEV_TX_OFFLOAD_UDP_TSO;
+ hi->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO;
+ xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_TSO;
+
+ if (dm->conf->enable_outer_checksum_offload &&
+ (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_VXLAN_TNL_TSO))
+ {
+ xd->port_conf.txmode.offloads |=
+ DEV_TX_OFFLOAD_VXLAN_TNL_TSO;
+ hi->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_VXLAN_TNL_GSO;
+ }
}
else
clib_warning ("%s: TCP/UDP checksum offload must be enabled",
format_dpdk_device_name, i,
format_dpdk_device_errors, xd);
- /*
- * A note on Cisco VIC (PMD_ENIC) and VLAN:
- *
- * With Cisco VIC vNIC, every ingress packet is tagged. On a
- * trunk vNIC (C series "standalone" server), packets on no VLAN
- * are tagged with vlan 0. On an access vNIC (standalone or B
- * series "blade" server), packets on the default/native VLAN
- * are tagged with that vNIC's VLAN. VPP expects these packets
- * to be untagged, and previously enabled VLAN strip on VIC by
- * default. But it also broke vlan sub-interfaces.
- *
- * The VIC adapter has "untag default vlan" ingress VLAN rewrite
- * mode, which removes tags from these packets. VPP now includes
- * a local patch for the enic driver to use this untag mode, so
- * enabling vlan stripping is no longer needed. In future, the
- * driver + dpdk will have an API to set the mode after
- * rte_eal_init. Then, this note and local patch will be
- * removed.
- */
-
- /*
- * VLAN stripping: default to VLAN strip disabled, unless specified
- * otherwise in the startup config.
- */
-
- vlan_off = rte_eth_dev_get_vlan_offload (xd->port_id);
- if (devconf->vlan_strip_offload == DPDK_DEVICE_VLAN_STRIP_ON)
- {
- vlan_off |= ETH_VLAN_STRIP_OFFLOAD;
- if (rte_eth_dev_set_vlan_offload (xd->port_id, vlan_off) >= 0)
- dpdk_log_info ("VLAN strip enabled for interface\n");
- else
- dpdk_log_warn ("VLAN strip cannot be supported by interface\n");
- xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_STRIP;
- }
- else
- {
- if (vlan_off & ETH_VLAN_STRIP_OFFLOAD)
- {
- vlan_off &= ~ETH_VLAN_STRIP_OFFLOAD;
- if (rte_eth_dev_set_vlan_offload (xd->port_id, vlan_off) >= 0)
- dpdk_log_warn ("set VLAN offload failed\n");
- }
- xd->port_conf.rxmode.offloads &= ~DEV_RX_OFFLOAD_VLAN_STRIP;
- }
-
if (hi)
hi->max_packet_bytes = xd->port_conf.rxmode.max_rx_pkt_len
- sizeof (ethernet_header_t);
if (error)
break;
}
- else if (unformat (input, "vlan-strip-offload off"))
- devconf->vlan_strip_offload = DPDK_DEVICE_VLAN_STRIP_OFF;
- else if (unformat (input, "vlan-strip-offload on"))
- devconf->vlan_strip_offload = DPDK_DEVICE_VLAN_STRIP_ON;
else if (unformat (input, "tso on"))
{
devconf->tso = DPDK_DEVICE_TSO_ON;
else if (unformat (input, "rss-queues %U",
unformat_bitmap_list, &devconf->rss_queues))
;
+ else if (unformat (input, "max-lro-pkt-size %u",
+ &devconf->max_lro_pkt_size))
+ ;
else
{
error = clib_error_return (0, "unknown input `%U'",
conf->enable_telemetry = 1;
else if (unformat (input, "enable-tcp-udp-checksum"))
- conf->enable_tcp_udp_checksum = 1;
-
+ {
+ conf->enable_tcp_udp_checksum = 1;
+ if (unformat (input, "enable-outer-checksum-offload"))
+ conf->enable_outer_checksum_offload = 1;
+ }
else if (unformat (input, "no-tx-checksum-offload"))
conf->no_tx_checksum_offload = 1;
else if (unformat (input, "no-multi-seg"))
conf->no_multi_seg = 1;
+ else if (unformat (input, "enable-lro"))
+ conf->enable_lro = 1;
else if (unformat (input, "max-simd-bitwidth %U",
unformat_max_simd_bitwidth, &conf->max_simd_bitwidth))
;
num_whitelisted++;
}
- else if (unformat (input, "num-mem-channels %d", &conf->nchannels))
- conf->nchannels_set_manually = 0;
- else if (unformat (input, "num-crypto-mbufs %d",
- &conf->num_crypto_mbufs))
- ;
else if (unformat (input, "uio-driver %s", &conf->uio_driver_name))
;
else if (unformat (input, "socket-mem %s", &socket_mem))
vec_add1 (conf->eal_init_args, s); \
}
foreach_eal_single_hyphen_arg
-#undef _
-#define _(a,b) \
- else if (unformat(input, #a " %s", &s)) \
- { \
- tmp = format (0, "-%s%c", #b, 0); \
- vec_add1 (conf->eal_init_args, tmp); \
- vec_add1 (s, 0); \
- vec_add1 (conf->eal_init_args, s); \
- conf->a##_set_manually = 1; \
- }
- foreach_eal_single_hyphen_mandatory_arg
#undef _
else if (unformat (input, "default"))
;
if (error)
return error;
- /* I'll bet that -c and -n must be the first and second args... */
- if (!conf->coremask_set_manually)
- {
- vlib_thread_registration_t *tr;
- uword *coremask = 0;
- int i;
-
- /* main thread core */
- coremask = clib_bitmap_set (coremask, tm->main_lcore, 1);
-
- for (i = 0; i < vec_len (tm->registrations); i++)
- {
- tr = tm->registrations[i];
- coremask = clib_bitmap_or (coremask, tr->coremask);
- }
-
- vec_insert (conf->eal_init_args, 2, 1);
- conf->eal_init_args[1] = (u8 *) "-c";
- tmp = format (0, "%U%c", format_bitmap_hex, coremask, 0);
- conf->eal_init_args[2] = tmp;
- clib_bitmap_free (coremask);
- }
-
- if (!conf->nchannels_set_manually)
- {
- vec_insert (conf->eal_init_args, 2, 3);
- conf->eal_init_args[3] = (u8 *) "-n";
- tmp = format (0, "%d", conf->nchannels);
- vec_terminate_c_string (tmp);
- conf->eal_init_args[4] = tmp;
- }
-
if (no_pci == 0 && geteuid () == 0)
dpdk_bind_devices_to_uio (conf);
if (devconf->x == 0 && conf->default_devconf.x > 0) \
devconf->x = conf->default_devconf.x ;
- /* *INDENT-OFF* */
pool_foreach (devconf, conf->dev_confs) {
/* default per-device config items */
foreach_dpdk_device_config_item
- /* copy vlan_strip config from default device */
- _ (vlan_strip_offload)
-
/* copy tso config from default device */
_ (tso)
vec_add1 (conf->eal_init_args, tmp);
}
}
- /* *INDENT-ON* */
#undef _
- /* set master-lcore */
- tmp = format (0, "--main-lcore%c", 0);
- vec_add1 (conf->eal_init_args, tmp);
- tmp = format (0, "%u%c", tm->main_lcore, 0);
- vec_add1 (conf->eal_init_args, tmp);
-
-
if (socket_mem)
clib_warning ("socket-mem argument is deprecated");
u32 hw_flags = 0;
u8 hw_flags_chg = 0;
- /* only update link state for PMD interfaces */
- if ((xd->flags & DPDK_DEVICE_FLAG_PMD) == 0)
- return;
-
xd->time_last_link_update = now ? now : xd->time_last_link_update;
clib_memset (&xd->link, 0, sizeof (xd->link));
rte_eth_link_get_nowait (xd->port_id, &xd->link);
"Data in cache line 0 is bigger than cache line size");
STATIC_ASSERT (offsetof (frame_queue_trace_t, cacheline0) == 0,
"Cache line marker must be 1st element in frame_queue_trace_t");
- STATIC_ASSERT (RTE_CACHE_LINE_SIZE == 1 << CLIB_LOG2_CACHE_LINE_BYTES,
- "DPDK RTE CACHE LINE SIZE does not match with 1<<CLIB_LOG2_CACHE_LINE_BYTES");
dpdk_cli_reference ();
- dm->vlib_main = vm;
- dm->vnet_main = vnet_get_main ();
dm->conf = &dpdk_config_main;
- dm->conf->nchannels = 4;
vec_add1 (dm->conf->eal_init_args, (u8 *) "vnet");
- /* Default vlib_buffer_t flags, DISABLES tcp/udp checksumming... */
- dm->buffer_flags_template = (VLIB_BUFFER_TOTAL_LENGTH_VALID |
- VLIB_BUFFER_EXT_HDR_VALID |
- VNET_BUFFER_F_L4_CHECKSUM_COMPUTED |
- VNET_BUFFER_F_L4_CHECKSUM_CORRECT);
-
dm->stat_poll_interval = DPDK_STATS_POLL_INTERVAL;
dm->link_state_poll_interval = DPDK_LINK_POLL_INTERVAL;
dm->log_default = vlib_log_register_class ("dpdk", 0);
dm->log_cryptodev = vlib_log_register_class ("dpdk", "cryptodev");
- dm->log_ipsec = vlib_log_register_class ("dpdk", "ipsec");
return error;
}
VLIB_INIT_FUNCTION (dpdk_init);
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
+static clib_error_t *
+dpdk_worker_thread_init (vlib_main_t *vm)
+{
+ if (rte_thread_register () < 0)
+ clib_panic ("dpdk: cannot register thread %u - %s", vm->thread_index,
+ rte_strerror (rte_errno));
+ return 0;
+}
+
+VLIB_WORKER_INIT_FUNCTION (dpdk_worker_thread_init);