26 #define foreach_rdma_input_error \ 27 _(BUFFER_ALLOC, "buffer alloc error") 31 #define _(f,s) RDMA_INPUT_ERROR_##f, 49 s[0].length = data_size;
61 struct ibv_recv_wr wr[VLIB_FRAME_SIZE], *w = wr;
62 struct ibv_sge sge[VLIB_FRAME_SIZE], *s = sge;
106 u64 __clib_aligned (32) va[8];
113 #ifdef CLIB_HAVE_VEC256 117 for (
int i = 0;
i < 8;
i++)
118 va[
i] = clib_host_to_net_u64 (va[
i]);
134 rxq->
tail += n_alloc;
135 rxq->
wq_db[MLX5_RCV_DBR] = clib_host_to_net_u32 (rxq->
tail);
167 if (ibv_post_wq_recv (rxq->
wq, wr, &w) != 0)
180 u32 next_index,
u16 * cqe_flags,
int is_mlx5dv)
188 while (n_trace && n_left)
198 tr->
cqe_flags = is_mlx5dv ? clib_net_to_host_u16 (cqe_flags[0]) : 0;
242 while (n_left_from >= 4)
271 while (n_left_from >= 1)
289 u32 mcqe_array_index = (cq_ci + 1) & mask;
292 mcqe_array_index = cq_ci;
300 mcqe_array_index = (mcqe_array_index + n) & mask;
308 for (
int i = 0;
i < n;
i++)
309 byte_cnt[
i] = mcqe[skip +
i].byte_count;
310 mcqe_array_index = (mcqe_array_index + 8) & mask;
320 for (
int i = 0;
i < 8;
i++)
321 byte_cnt[
i] = mcqe[
i].byte_count;
325 mcqe_array_index = (mcqe_array_index + 8) & mask;
331 for (
int i = 0;
i < n_left;
i++)
332 byte_cnt[
i] = mcqe[
i].byte_count;
362 u32 mask,
u32 log2_cq_size)
372 offset = cq_ci & mask;
373 owner = 0xf0 | ((cq_ci >> log2_cq_size) & 1);
375 if (offset + n_mini_cqes < cq_size)
390 u32 * byte_cnt,
u16 * cqe_flags)
392 u32 n_rx_packets = 0;
403 n_mini_cqes_left, cq_ci, mask, byte_cnt);
407 n_rx_packets = n_mini_cqes_left;
408 byte_cnt += n_mini_cqes_left;
409 cqe_flags += n_mini_cqes_left;
411 rxq->
cq_ci = cq_ci = cq_ci + n_mini_cqes;
416 u8 cqe_last_byte, owner;
421 owner = (cq_ci >> log2_cq_size) & 1;
424 if ((cqe_last_byte & 0x1) != owner)
427 cqe_last_byte &= 0xfe;
429 if (cqe_last_byte == 0x2c)
435 if (n_left >= n_mini_cqes)
441 n_rx_packets += n_mini_cqes;
442 byte_cnt += n_mini_cqes;
443 cqe_flags += n_mini_cqes;
444 cq_ci += n_mini_cqes;
459 if (cqe_last_byte == 0x20)
462 cqe_flags[0] = cqe->
flags;
469 rd->
flags |= RDMA_DEVICE_F_ERROR;
490 struct ibv_wc wc[VLIB_FRAME_SIZE];
493 u32 next_index, *to_next, n_left_to_next, n_rx_bytes = 0;
494 int n_rx_packets, skip_ip4_cksum = 0;
501 n_rx_packets = ibv_poll_cq (rxq->
cq, VLIB_FRAME_SIZE, wc);
519 rxq->
size, n_rx_packets);
527 u32 n_left = n_rx_packets;
534 #if defined CLIB_HAVE_VEC256 535 u16x16 mask16 = u16x16_splat (mask);
536 u16x16 match16 = u16x16_splat (match);
539 for (
int i = 0;
i * 16 < n_rx_packets;
i++)
542 if (!u16x16_is_all_zero (r))
545 for (
int i = 0;
i < n_rx_packets;
i += 8)
547 #elif defined CLIB_HAVE_VEC128 548 u16x8 mask8 = u16x8_splat (mask);
549 u16x8 match8 = u16x8_splat (match);
552 for (
int i = 0;
i * 8 < n_rx_packets;
i++)
555 if (!u16x8_is_all_zero (r))
558 for (
int i = 0;
i < n_rx_packets;
i += 4)
561 for (
int i = 0;
i < n_rx_packets;
i++)
565 for (
int i = 0;
i < n_rx_packets;
i++)
566 bc[
i] = clib_net_to_host_u32 (bc[
i]);
607 rxq->
head += n_rx_packets;
656 .name =
"rdma-input",
658 .sibling_of =
"device-input",
661 .state = VLIB_NODE_STATE_DISABLED,
static_always_inline u32x4 u32x4_byte_swap(u32x4 v)
static u32 vlib_get_trace_count(vlib_main_t *vm, vlib_node_runtime_t *rt)
static void vlib_increment_combined_counter(vlib_combined_counter_main_t *cm, u32 thread_index, u32 index, u64 n_packets, u64 n_bytes)
Increment a combined counter.
static_always_inline void clib_prefetch_load(void *p)
vnet_main_t * vnet_get_main(void)
vnet_interface_main_t interface_main
#define CLIB_MEMORY_STORE_BARRIER()
#define VLIB_NODE_FLAG_TRACE_SUPPORTED
u8 opcode_cqefmt_se_owner
u16 current_length
Nbytes between current data and the end of this buffer.
static vlib_frame_t * vlib_get_frame(vlib_main_t *vm, vlib_frame_t *f)
u32 per_interface_next_index
format_function_t format_rdma_input_trace
static_always_inline void vlib_get_buffers_with_offset(vlib_main_t *vm, u32 *bi, void **b, int count, i32 offset)
Translate array of buffer indices into buffer pointers with offset.
#define VLIB_NODE_FN(node)
static u32 vlib_buffer_alloc_to_ring_from_pool(vlib_main_t *vm, u32 *ring, u32 start, u32 ring_size, u32 n_buffers, u8 buffer_pool_index)
Allocate buffers into ring from specific buffer pool.
u16 cqe_flags[VLIB_FRAME_SIZE]
u8 buffer_pool_index
index of buffer pool this buffer belongs.
static void vlib_trace_buffer(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, vlib_buffer_t *b, int follow_chain)
u16x8 cqe_flags8[VLIB_FRAME_SIZE/8]
rdma_per_thread_data_t * per_thread_data
#define static_always_inline
static uword pow2_mask(uword x)
#define ETH_INPUT_FRAME_F_SINGLE_SW_IF_IDX
vlib_combined_counter_main_t * combined_sw_if_counters
#define CQE_FLAG_L3_HDR_TYPE_SHIFT
#define CQE_FLAG_L3_HDR_TYPE_IP4
static_always_inline int vnet_device_input_have_features(u32 sw_if_index)
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
#define vlib_get_new_next_frame(vm, node, next_index, vectors, n_vectors_left)
epu16_epi64 epu8_epi64 epu8_epi64 epi16_epi64 epi8_epi64 epi8_epi64 static_always_inline u64x4 u64x4_byte_swap(u64x4 v)
static vlib_next_frame_t * vlib_node_runtime_get_next_frame(vlib_main_t *vm, vlib_node_runtime_t *n, u32 next_index)
static void vlib_buffer_free_from_ring(vlib_main_t *vm, u32 *ring, u32 start, u32 ring_size, u32 n_buffers)
Free buffers from ring.
static_always_inline void vlib_buffer_copy_template(vlib_buffer_t *b, vlib_buffer_t *bt)
#define ETH_INPUT_FRAME_F_IP4_CKSUM_OK
static_always_inline u32x8 u32x8_byte_swap(u32x8 v)
#define CQE_FLAG_L3_HDR_TYPE_MASK
static_always_inline u32 vlib_buffer_get_default_data_size(vlib_main_t *vm)
vlib_buffer_t buffer_template
#define VLIB_REGISTER_NODE(x,...)
#define CLIB_PREFETCH(addr, size, type)
sll srl srl sll sra u16x4 i
static void * vlib_frame_scalar_args(vlib_frame_t *f)
Get pointer to frame scalar data.
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
vlib_main_t vlib_node_runtime_t * node
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
static_always_inline void clib_memset_u16(void *p, u16 val, uword count)
#define foreach_device_and_queue(var, vec)
static_always_inline void clib_prefetch_store(void *p)
u16x16 cqe_flags16[VLIB_FRAME_SIZE/16]
VLIB buffer representation.
static void vlib_buffer_copy_indices_from_ring(u32 *dst, u32 *ring, u32 start, u32 ring_size, u32 n_buffers)
struct clib_bihash_value offset
template key/value backing page structure
static_always_inline void vnet_feature_start_device_input_x1(u32 sw_if_index, u32 *next0, vlib_buffer_t *b0)
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
static void vlib_set_trace_count(vlib_main_t *vm, vlib_node_runtime_t *rt, u32 count)
static_always_inline void vlib_get_buffers(vlib_main_t *vm, u32 *bi, vlib_buffer_t **b, int count)
Translate array of buffer indices into buffer pointers.
#define CLIB_CACHE_LINE_BYTES
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.