27 #define foreach_dpdk_tx_func_error \ 28 _(BAD_RETVAL, "DPDK tx function returned an error") \ 29 _(RING_FULL, "Tx packet drops (ring full)") \ 30 _(PKT_DROP, "Tx packet drops (dpdk tx failure)") \ 31 _(REPL_FAIL, "Tx packet drops (replication failure)") 35 #define _(f,s) DPDK_TX_FUNC_ERROR_##f, 54 error = rte_eth_dev_default_mac_addr_set (xd->
device_index,
55 (
struct ether_addr *) address);
69 struct ether_addr mc_addr_vec[],
int naddr)
75 error = rte_eth_dev_set_mc_addr_list (xd->
device_index, mc_addr_vec, naddr);
92 struct rte_mbuf *first_mb = 0, *new_mb, *pkt_mb, **prev_mb_next = 0;
93 u8 nb_segs, nb_segs_left;
99 nb_segs = pkt_mb->nb_segs;
100 for (nb_segs_left = nb_segs; nb_segs_left; nb_segs_left--)
105 "(nb_segs = %d, nb_segs_left = %d)!",
106 nb_segs - nb_segs_left, nb_segs, nb_segs_left);
108 rte_pktmbuf_free (first_mb);
115 rte_pktmbuf_free (first_mb);
125 rte_pktmbuf_pkt_len (first_mb) = pkt_mb->pkt_len;
126 first_mb->nb_segs = pkt_mb->nb_segs;
127 first_mb->port = pkt_mb->port;
128 #ifdef DAW_FIXME // TX Offload support TBD 129 first_mb->vlan_macip = pkt_mb->vlan_macip;
130 first_mb->hash = pkt_mb->hash;
131 first_mb->ol_flags = pkt_mb->ol_flags
136 ASSERT (prev_mb_next != 0);
137 *prev_mb_next = new_mb;
143 rte_pktmbuf_data_len (new_mb) = pkt_mb->data_len;
144 copy_bytes = pkt_mb->data_len + RTE_PKTMBUF_HEADROOM;
145 ASSERT (copy_bytes <= pkt_mb->buf_len);
146 clib_memcpy (new_mb->buf_addr, pkt_mb->buf_addr, copy_bytes);
148 prev_mb_next = &new_mb->next;
149 pkt_mb = pkt_mb->next;
153 __rte_mbuf_sanity_check (first_mb, 1);
163 struct rte_mbuf *first_mb = 0, *new_mb, *pkt_mb, **prev_mb_next = 0;
164 u8 nb_segs, nb_segs_left;
169 nb_segs = pkt_mb->nb_segs;
170 for (nb_segs_left = nb_segs; nb_segs_left; nb_segs_left--)
175 "(nb_segs = %d, nb_segs_left = %d)!",
176 nb_segs - nb_segs_left, nb_segs, nb_segs_left);
178 rte_pktmbuf_free (first_mb);
181 new_mb = rte_pktmbuf_clone (pkt_mb, bm->
pktmbuf_pools[socket_id]);
185 rte_pktmbuf_free (first_mb);
195 rte_pktmbuf_pkt_len (first_mb) = pkt_mb->pkt_len;
196 first_mb->nb_segs = pkt_mb->nb_segs;
197 first_mb->port = pkt_mb->port;
198 #ifdef DAW_FIXME // TX Offload support TBD 199 first_mb->vlan_macip = pkt_mb->vlan_macip;
200 first_mb->hash = pkt_mb->hash;
201 first_mb->ol_flags = pkt_mb->ol_flags
206 ASSERT (prev_mb_next != 0);
207 *prev_mb_next = new_mb;
213 rte_pktmbuf_data_len (new_mb) = pkt_mb->data_len;
215 prev_mb_next = &new_mb->next;
216 pkt_mb = pkt_mb->next;
220 __rte_mbuf_sanity_check (first_mb, 1);
245 sizeof (buffer[0]) -
sizeof (buffer->
pre_data));
269 struct rte_mbuf **tx_vector)
280 ring =
vec_header (tx_vector,
sizeof (*ring));
299 ASSERT (n_packets < xd->nb_tx_desc);
329 while (__sync_lock_test_and_set (xd->
lockp[queue_id], 1))
331 queue_id = (queue_id + 1) % xd->
tx_q_used;
343 &tx_vector[tx_tail], tx_head - tx_tail);
344 rv = rte_ring_sp_enqueue_burst (hqos->
swq,
345 (
void **) &tx_vector[tx_tail],
346 (uint16_t) (tx_head - tx_tail));
363 rv = rte_ring_sp_enqueue_burst (hqos->
swq,
364 (
void **) &tx_vector[tx_tail],
372 n_retry = (rv == xd->
nb_tx_desc - tx_tail) ? 1 : 0;
383 (uint16_t) (tx_head - tx_tail));
404 n_retry = (rv == xd->
nb_tx_desc - tx_tail) ? 1 : 0;
414 *xd->
lockp[queue_id] = 0;
432 n_packets -= (uint16_t) rv;
434 while (rv && n_packets && (n_retry > 0));
454 struct rte_mbuf **tx_vector;
464 ring =
vec_header (tx_vector,
sizeof (*ring));
502 struct rte_mbuf **tx_vector;
514 tx_vector = xd->tx_vectors[queue_id];
515 ring =
vec_header (tx_vector,
sizeof (*ring));
533 u32 bi0 = from[n_packets];
536 rte_pktmbuf_free (mb0);
558 i = ring->
tx_head % xd->nb_tx_desc;
564 struct rte_mbuf *mb0, *mb1;
565 struct rte_mbuf *prefmb0, *prefmb1;
569 u16 new_data_len0, new_data_len1;
570 u16 new_pkt_len0, new_pkt_len1;
606 DPDK_TX_FUNC_ERROR_REPL_FAIL, 1);
619 DPDK_TX_FUNC_ERROR_REPL_FAIL, 1);
633 new_data_len0 = (
u16) ((
i16) mb0->data_len + delta0);
634 new_data_len1 = (
u16) ((
i16) mb1->data_len + delta1);
635 new_pkt_len0 = (
u16) ((
i16) mb0->pkt_len + delta0);
636 new_pkt_len1 = (
u16) ((
i16) mb1->pkt_len + delta1);
640 mb0->data_len = new_data_len0;
641 mb1->data_len = new_data_len1;
642 mb0->pkt_len = new_pkt_len0;
643 mb1->pkt_len = new_pkt_len1;
660 tx_vector[i % xd->nb_tx_desc] = mb0;
662 tx_vector[i % xd->nb_tx_desc] = mb1;
670 tx_vector[i % xd->nb_tx_desc] = mb0;
675 tx_vector[i % xd->nb_tx_desc] = mb1;
685 struct rte_mbuf *mb0;
703 DPDK_TX_FUNC_ERROR_REPL_FAIL, 1);
714 new_data_len0 = (
u16) ((
i16) mb0->data_len + delta0);
715 new_pkt_len0 = (
u16) ((
i16) mb0->pkt_len + delta0);
718 mb0->data_len = new_data_len0;
719 mb0->pkt_len = new_pkt_len0;
729 tx_vector[i % xd->nb_tx_desc] = mb0;
746 tx_pkts = n_on_ring - n_packets;
781 rte_pktmbuf_free (tx_vector[ring->
tx_tail + n_packets]);
794 _vec_len (dm->
recycle[my_cpu]) = 0;
856 if (xd->
pmd == VNET_DPDK_PMD_BOND)
859 int nlink = rte_eth_bond_slaves_get (xd->
device_index, slink, 16);
862 u8 dpdk_port = slink[--nlink];
863 rte_eth_dev_stop (dpdk_port);
869 clib_warning (
"rte_eth_dev_%s error: %d", is_up ?
"start" :
"stop", rv);
887 if (node_index == ~0)
920 if ((xd->
pmd != VNET_DPDK_PMD_IXGBEVF) && (xd->
pmd != VNET_DPDK_PMD_I40EVF))
933 vlan_offload = rte_eth_dev_get_vlan_offload (xd->
device_index);
934 vlan_offload |= ETH_VLAN_FILTER_OFFLOAD;
936 if ((r = rte_eth_dev_set_vlan_offload (xd->
device_index, vlan_offload)))
977 .no_flatten_output_chains = 1,
991 #define UP_DOWN_FLAG_EVENT 1 1006 uword *event_data = 0;
1022 if (
vec_len (event_data) == 2)
1024 sw_if_index = event_data[0];
1025 flags = event_data[1];
1047 .name =
"admin-up-down-process",
1048 .process_log2_n_stack_bytes = 17,
1089 "Unable to get DPDK device from HW interface");
void(* dpdk_flowcontrol_callback_t)(vlib_main_t *vm, u32 hw_if_index, u32 n_packets)
#define DPDK_DEVICE_FLAG_PROMISC
static void vlib_increment_simple_counter(vlib_simple_counter_main_t *cm, u32 cpu_index, u32 index, u32 increment)
Increment a simple counter.
i8 dpdk_get_cpu_socket(vnet_hw_interface_t *hi)
sll srl srl sll sra u16x4 i
#define rte_mbuf_from_vlib_buffer(x)
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
#define UP_DOWN_FLAG_EVENT
static uword * vlib_process_wait_for_event(vlib_main_t *vm)
static vlib_main_t * vlib_get_main(void)
vnet_interface_main_t interface_main
clib_error_t * dpdk_set_mac_address(vnet_hw_interface_t *hi, char *address)
vnet_device_class_t dpdk_device_class
static void vlib_error_count(vlib_main_t *vm, uword node_index, uword counter, uword increment)
static f64 vlib_time_now(vlib_main_t *vm)
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
#define DPDK_DEVICE_FLAG_HQOS
vlib_buffer_main_t * buffer_main
u32 per_interface_next_index
#define clib_error_report(e)
struct rte_eth_xstat * last_cleared_xstats
struct rte_mbuf * dpdk_zerocopy_replicate_packet_mb(vlib_buffer_t *b)
static uword vlib_buffer_length_in_chain(vlib_main_t *vm, vlib_buffer_t *b)
Get length in bytes of the buffer chain.
format_function_t format_dpdk_tx_dma_trace
uword admin_up_down_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
static clib_error_t * dpdk_interface_admin_up_down(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
#define DPDK_DEVICE_FLAG_PMD
struct rte_eth_stats stats
VNET_DEVICE_CLASS(af_packet_device_class)
vnet_main_t * vnet_get_main(void)
struct rte_mbuf *** tx_vectors
static_always_inline u32 tx_burst_vector_internal(vlib_main_t *vm, dpdk_device_t *xd, struct rte_mbuf **tx_vector)
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
#define static_always_inline
static uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Return the first event type which has occurred and a vector of per-event data of that type...
vlib_node_registration_t dpdk_input_node
(constructor) VLIB_REGISTER_NODE (dpdk_input_node)
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
u8 pre_data[VLIB_BUFFER_PRE_DATA_SIZE]
Space for inserting data before buffer start.
#define clib_warning(format, args...)
A collection of simple counters.
dpdk_device_hqos_per_worker_thread_t * hqos_wt
struct rte_mbuf * dpdk_replicate_packet_mb(vlib_buffer_t *b)
vnet_hw_interface_t * hw_interfaces
static clib_error_t * dpdk_subif_add_del_function(vnet_main_t *vnm, u32 hw_if_index, struct vnet_sw_interface_t *st, int is_add)
u16 current_length
Nbytes between current data and the end of this buffer.
dpdk_flowcontrol_callback_t flowcontrol_callback
static char * dpdk_tx_func_error_strings[]
void dpdk_hqos_metadata_set(dpdk_device_hqos_per_worker_thread_t *hqos, struct rte_mbuf **pkts, u32 n_pkts)
static void * vlib_process_signal_event_data(vlib_main_t *vm, uword node_index, uword type_opaque, uword n_data_elts, uword n_data_elt_bytes)
struct vnet_sub_interface_t::@143::@144::@146 flags
static void pcap_add_buffer(pcap_main_t *pm, vlib_main_t *vm, u32 buffer_index, u32 n_bytes_in_trace)
Add buffer (vlib_buffer_t) to the trace.
static void dpdk_set_interface_next_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
vlib_simple_counter_main_t * sw_if_counters
void dpdk_set_flowcontrol_callback(vlib_main_t *vm, dpdk_flowcontrol_callback_t callback)
#define DPDK_DEVICE_FLAG_ADMIN_UP
static uword dpdk_interface_tx(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *f)
struct rte_mempool ** pktmbuf_pools
#define CLIB_PREFETCH(addr, size, type)
static void dpdk_update_counters(dpdk_device_t *xd, f64 now)
#define clib_memcpy(a, b, c)
struct vnet_sub_interface_t::@143 eth
#define VLIB_BUFFER_RECYCLE
format_function_t format_dpdk_device
struct rte_eth_xstat * xstats
#define VNET_SW_INTERFACE_FLAG_ADMIN_UP
format_function_t format_dpdk_device_name
#define VLIB_BUFFER_REPL_FAIL
void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
#define DPDK_DEVICE_FLAG_HAVE_SUBIF
#define VLIB_NODE_FLAG_TRACE
void dpdk_update_link_state(dpdk_device_t *xd, f64 now)
#define VLIB_BUFFER_IS_TRACED
dpdk_pmd_t dpdk_get_pmd_type(vnet_hw_interface_t *hi)
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
static void dpdk_clear_hw_interface_counters(u32 instance)
static vlib_node_registration_t admin_up_down_process_node
(constructor) VLIB_REGISTER_NODE (admin_up_down_process_node)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define foreach_dpdk_tx_func_error
u8 admin_up_down_in_progress
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
static void dpdk_tx_trace_buffer(dpdk_main_t *dm, vlib_node_runtime_t *node, dpdk_device_t *xd, u16 queue_id, u32 buffer_index, vlib_buffer_t *buffer)
u32 dpdk_interface_tx_vector(vlib_main_t *vm, u32 dev_instance)
void post_sw_interface_set_flags(vlib_main_t *vm, u32 sw_if_index, u32 flags)
#define VLIB_REGISTER_NODE(x,...)
u32 dpdk_get_admin_up_down_in_progress(void)
static void * vec_header(void *v, uword header_bytes)
Find a user vector header.
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, u32 flags)
struct rte_eth_stats last_cleared_stats
#define clib_error_return(e, args...)
#define CLIB_CACHE_LINE_BYTES
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
clib_error_t * dpdk_get_hw_interface_stats(u32 hw_if_index, struct rte_eth_stats *dest)
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
#define VLIB_DEVICE_TX_FUNCTION_MULTIARCH(dev, fn)
clib_error_t * dpdk_set_mc_filter(vnet_hw_interface_t *hi, struct ether_addr mc_addr_vec[], int naddr)
CLIB vectors are ubiquitous dynamically resized arrays with by user defined "headers".
dpdk_config_main_t * conf