diff options
Diffstat (limited to 'src/plugins/dpdk/device/device.c')
-rw-r--r-- | src/plugins/dpdk/device/device.c | 109 |
1 files changed, 38 insertions, 71 deletions
diff --git a/src/plugins/dpdk/device/device.c b/src/plugins/dpdk/device/device.c index 095036fcb5c..0ba59562838 100644 --- a/src/plugins/dpdk/device/device.c +++ b/src/plugins/dpdk/device/device.c @@ -25,7 +25,6 @@ #include <vlib/unix/unix.h> #define foreach_dpdk_tx_func_error \ - _(BAD_RETVAL, "DPDK tx function returned an error") \ _(PKT_DROP, "Tx packet drops (dpdk tx failure)") typedef enum @@ -153,52 +152,30 @@ dpdk_validate_rte_mbuf (vlib_main_t * vm, vlib_buffer_t * b, * support multiple queues. It returns the number of packets untransmitted * If all packets are transmitted (the normal case), the function returns 0. */ -static_always_inline - u32 tx_burst_vector_internal (vlib_main_t * vm, - dpdk_device_t * xd, - struct rte_mbuf **mb, u32 n_left) +static_always_inline u32 +tx_burst_vector_internal (vlib_main_t *vm, dpdk_device_t *xd, + struct rte_mbuf **mb, u32 n_left, int queue_id, + u8 is_shared) { - dpdk_main_t *dm = &dpdk_main; dpdk_tx_queue_t *txq; u32 n_retry; int n_sent = 0; - int queue_id; n_retry = 16; - queue_id = vm->thread_index % xd->tx_q_used; txq = vec_elt_at_index (xd->tx_queues, queue_id); do { - clib_spinlock_lock_if_init (&txq->lock); + if (is_shared) + clib_spinlock_lock (&txq->lock); - if (PREDICT_TRUE (xd->flags & DPDK_DEVICE_FLAG_PMD)) - { - /* no wrap, transmit in one burst */ - n_sent = rte_eth_tx_burst (xd->port_id, queue_id, mb, n_left); - n_retry--; - } - else - { - ASSERT (0); - n_sent = 0; - } + /* no wrap, transmit in one burst */ + n_sent = rte_eth_tx_burst (xd->port_id, queue_id, mb, n_left); - clib_spinlock_unlock_if_init (&txq->lock); + if (is_shared) + clib_spinlock_unlock (&txq->lock); - if (PREDICT_FALSE (n_sent < 0)) - { - // emit non-fatal message, bump counter - vnet_main_t *vnm = dm->vnet_main; - vnet_interface_main_t *im = &vnm->interface_main; - u32 node_index; - - node_index = vec_elt_at_index (im->hw_interfaces, - xd->hw_if_index)->tx_node_index; - - vlib_error_count (vm, node_index, DPDK_TX_FUNC_ERROR_BAD_RETVAL, 1); - return n_left; // untransmitted packets - } + n_retry--; n_left -= n_sent; mb += n_sent; } @@ -237,16 +214,17 @@ dpdk_buffer_tx_offload (dpdk_device_t * xd, vlib_buffer_t * b, outer_ip_cksum = oflags & VNET_BUFFER_OFFLOAD_F_OUTER_IP_CKSUM; vxlan_tunnel = oflags & VNET_BUFFER_OFFLOAD_F_TNL_VXLAN; - ol_flags = is_ip4 ? PKT_TX_IPV4 : PKT_TX_IPV6; - ol_flags |= ip_cksum ? PKT_TX_IP_CKSUM : 0; - ol_flags |= tcp_cksum ? PKT_TX_TCP_CKSUM : 0; - ol_flags |= udp_cksum ? PKT_TX_UDP_CKSUM : 0; + ol_flags = is_ip4 ? RTE_MBUF_F_TX_IPV4 : RTE_MBUF_F_TX_IPV6; + ol_flags |= ip_cksum ? RTE_MBUF_F_TX_IP_CKSUM : 0; + ol_flags |= tcp_cksum ? RTE_MBUF_F_TX_TCP_CKSUM : 0; + ol_flags |= udp_cksum ? RTE_MBUF_F_TX_UDP_CKSUM : 0; if (vxlan_tunnel) { - ol_flags |= outer_ip_cksum ? PKT_TX_OUTER_IPV4 | PKT_TX_OUTER_IP_CKSUM : - PKT_TX_OUTER_IPV6; - ol_flags |= PKT_TX_TUNNEL_VXLAN; + ol_flags |= outer_ip_cksum ? + RTE_MBUF_F_TX_OUTER_IPV4 | RTE_MBUF_F_TX_OUTER_IP_CKSUM : + RTE_MBUF_F_TX_OUTER_IPV6; + ol_flags |= RTE_MBUF_F_TX_TUNNEL_VXLAN; mb->l2_len = vnet_buffer (b)->l3_hdr_offset - vnet_buffer2 (b)->outer_l4_hdr_offset; mb->l3_len = @@ -259,8 +237,7 @@ dpdk_buffer_tx_offload (dpdk_device_t * xd, vlib_buffer_t * b, } else { - mb->l2_len = - vnet_buffer (b)->l3_hdr_offset - vnet_buffer (b)->l2_hdr_offset; + mb->l2_len = vnet_buffer (b)->l3_hdr_offset - b->current_data; mb->l3_len = vnet_buffer (b)->l4_hdr_offset - vnet_buffer (b)->l3_hdr_offset; mb->outer_l2_len = 0; @@ -275,7 +252,8 @@ dpdk_buffer_tx_offload (dpdk_device_t * xd, vlib_buffer_t * b, max_pkt_len = outer_hdr_len + mb->l2_len + mb->l3_len + mb->l4_len + mb->tso_segsz; if (mb->tso_segsz != 0 && mb->pkt_len > max_pkt_len) - ol_flags |= (tcp_cksum ? PKT_TX_TCP_SEG : PKT_TX_UDP_SEG); + ol_flags |= + (tcp_cksum ? RTE_MBUF_F_TX_TCP_SEG : RTE_MBUF_F_TX_UDP_SEG); } mb->ol_flags |= ol_flags; @@ -298,11 +276,13 @@ VNET_DEVICE_CLASS_TX_FN (dpdk_device_class) (vlib_main_t * vm, dpdk_main_t *dm = &dpdk_main; vnet_interface_output_runtime_t *rd = (void *) node->runtime_data; dpdk_device_t *xd = vec_elt_at_index (dm->devices, rd->dev_instance); + vnet_hw_if_tx_frame_t *tf = vlib_frame_scalar_args (f); u32 n_packets = f->n_vectors; u32 n_left; u32 thread_index = vm->thread_index; - int queue_id = thread_index; - u32 tx_pkts = 0, all_or_flags = 0; + int queue_id = tf->queue_id; + u8 is_shared = tf->shared_queue; + u32 tx_pkts = 0; dpdk_per_thread_data_t *ptd = vec_elt_at_index (dm->per_thread_data, thread_index); struct rte_mbuf **mb; @@ -334,7 +314,6 @@ VNET_DEVICE_CLASS_TX_FN (dpdk_device_class) (vlib_main_t * vm, b[3] = vlib_buffer_from_rte_mbuf (mb[3]); or_flags = b[0]->flags | b[1]->flags | b[2]->flags | b[3]->flags; - all_or_flags |= or_flags; if (or_flags & VLIB_BUFFER_NEXT_PRESENT) { @@ -392,7 +371,6 @@ VNET_DEVICE_CLASS_TX_FN (dpdk_device_class) (vlib_main_t * vm, b[1] = vlib_buffer_from_rte_mbuf (mb[1]); or_flags = b[0]->flags | b[1]->flags; - all_or_flags |= or_flags; if (or_flags & VLIB_BUFFER_NEXT_PRESENT) { @@ -428,7 +406,6 @@ VNET_DEVICE_CLASS_TX_FN (dpdk_device_class) (vlib_main_t * vm, while (n_left > 0) { b[0] = vlib_buffer_from_rte_mbuf (mb[0]); - all_or_flags |= b[0]->flags; dpdk_validate_rte_mbuf (vm, b[0], 1); dpdk_buffer_tx_offload (xd, b[0], mb[0]); @@ -443,7 +420,8 @@ VNET_DEVICE_CLASS_TX_FN (dpdk_device_class) (vlib_main_t * vm, /* transmit as many packets as possible */ tx_pkts = n_packets = mb - ptd->mbufs; - n_left = tx_burst_vector_internal (vm, xd, ptd->mbufs, n_packets); + n_left = tx_burst_vector_internal (vm, xd, ptd->mbufs, n_packets, queue_id, + is_shared); { /* If there is no callback then drop any non-transmitted packets */ @@ -499,7 +477,7 @@ dpdk_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags) if (vec_len (xd->errors)) return clib_error_create ("Interface start failed"); xd->flags |= DPDK_DEVICE_FLAG_ADMIN_UP; - f64 now = vlib_time_now (dm->vlib_main); + f64 now = vlib_time_now (vlib_get_main ()); dpdk_update_counters (xd, now); dpdk_update_link_state (xd, now); } @@ -535,7 +513,7 @@ dpdk_set_interface_next_node (vnet_main_t * vnm, u32 hw_if_index, } xd->per_interface_next_index = - vlib_node_add_next (xm->vlib_main, dpdk_input_node.index, node_index); + vlib_node_add_next (vlib_get_main (), dpdk_input_node.index, node_index); } @@ -557,11 +535,8 @@ dpdk_subif_add_del_function (vnet_main_t * vnm, else if (xd->num_subifs) xd->num_subifs--; - if ((xd->flags & DPDK_DEVICE_FLAG_PMD) == 0) - goto done; - /* currently we program VLANS only for IXGBE VF */ - if (xd->pmd != VNET_DPDK_PMD_IXGBEVF) + if (xd->driver->program_vlans == 0) goto done; if (t->sub.eth.flags.no_tags == 1) @@ -575,7 +550,7 @@ dpdk_subif_add_del_function (vnet_main_t * vnm, } vlan_offload = rte_eth_dev_get_vlan_offload (xd->port_id); - vlan_offload |= ETH_VLAN_FILTER_OFFLOAD; + vlan_offload |= RTE_ETH_VLAN_FILTER_OFFLOAD; if ((r = rte_eth_dev_set_vlan_offload (xd->port_id, vlan_offload))) { @@ -649,7 +624,6 @@ dpdk_interface_set_rss_queues (struct vnet_main_t *vnm, clib_memset (reta, 0, dev_info.reta_size * sizeof (*reta)); valid_queue_count = 0; - /* *INDENT-OFF* */ clib_bitmap_foreach (i, bitmap) { if (i >= dev_info.nb_rx_queues) { @@ -658,7 +632,6 @@ dpdk_interface_set_rss_queues (struct vnet_main_t *vnm, } reta[valid_queue_count++] = i; } - /* *INDENT-ON* */ /* check valid_queue_count not zero, make coverity happy */ if (valid_queue_count == 0) @@ -675,10 +648,8 @@ dpdk_interface_set_rss_queues (struct vnet_main_t *vnm, } /* update reta table */ - reta_conf = - (struct rte_eth_rss_reta_entry64 *) clib_mem_alloc (dev_info.reta_size / - RTE_RETA_GROUP_SIZE * - sizeof (*reta_conf)); + reta_conf = (struct rte_eth_rss_reta_entry64 *) clib_mem_alloc ( + dev_info.reta_size / RTE_ETH_RETA_GROUP_SIZE * sizeof (*reta_conf)); if (reta_conf == NULL) { err = clib_error_return (0, "clib_mem_alloc failed"); @@ -686,13 +657,13 @@ dpdk_interface_set_rss_queues (struct vnet_main_t *vnm, } clib_memset (reta_conf, 0, - dev_info.reta_size / RTE_RETA_GROUP_SIZE * - sizeof (*reta_conf)); + dev_info.reta_size / RTE_ETH_RETA_GROUP_SIZE * + sizeof (*reta_conf)); for (i = 0; i < dev_info.reta_size; i++) { - uint32_t reta_id = i / RTE_RETA_GROUP_SIZE; - uint32_t reta_pos = i % RTE_RETA_GROUP_SIZE; + uint32_t reta_id = i / RTE_ETH_RETA_GROUP_SIZE; + uint32_t reta_pos = i % RTE_ETH_RETA_GROUP_SIZE; reta_conf[reta_id].mask = UINT64_MAX; reta_conf[reta_id].reta[reta_pos] = reta[i]; @@ -750,7 +721,6 @@ dpdk_interface_rx_mode_change (vnet_main_t *vnm, u32 hw_if_index, u32 qid, return 0; } -/* *INDENT-OFF* */ VNET_DEVICE_CLASS (dpdk_device_class) = { .name = "dpdk", .tx_function_n_errors = DPDK_TX_FUNC_N_ERROR, @@ -769,7 +739,6 @@ VNET_DEVICE_CLASS (dpdk_device_class) = { .set_rss_queues_function = dpdk_interface_set_rss_queues, .rx_mode_change_function = dpdk_interface_rx_mode_change, }; -/* *INDENT-ON* */ #define UP_DOWN_FLAG_EVENT 1 @@ -816,14 +785,12 @@ admin_up_down_process (vlib_main_t * vm, return 0; /* or not */ } -/* *INDENT-OFF* */ VLIB_REGISTER_NODE (admin_up_down_process_node) = { .function = admin_up_down_process, .type = VLIB_NODE_TYPE_PROCESS, .name = "admin-up-down-process", .process_log2_n_stack_bytes = 17, // 256KB }; -/* *INDENT-ON* */ /* * fd.io coding-style-patch-verification: ON |