Skip to content

Commit 16f7186

Browse files
pasisAlexanderGrissik
authored andcommitted
issue: 4213201 Remove memset for the next hot WQE
XLIO does a prefetch with zeroing the next WQEBB after a doorbell. It also presets inline_hdr_sz as a legacy behavior. However, in a corner case when the producer fills the tail WQE and the consumer is still processing the head WQE, the prefetch code corrupts the head WQE. Remove the prefetch to avoid the SQ corruption. Clear each WQE before filling it. Signed-off-by: Dmytro Podgornyi <[email protected]>
1 parent a0619a9 commit 16f7186

File tree

1 file changed

+7
-15
lines changed

1 file changed

+7
-15
lines changed

src/core/dev/hw_queue_tx.cpp

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -488,13 +488,6 @@ void hw_queue_tx::init_queue()
488488
hwqtx_logfunc("m_tx_num_wr=%d max_inline_data: %d m_sq_wqe_idx_to_prop=%p", m_tx_num_wr,
489489
get_max_inline_data(), m_sq_wqe_idx_to_prop);
490490

491-
memset((void *)(uintptr_t)m_sq_wqe_hot, 0, sizeof(struct mlx5_eth_wqe));
492-
m_sq_wqe_hot->ctrl.data[0] = htonl(MLX5_OPCODE_SEND);
493-
m_sq_wqe_hot->ctrl.data[1] = htonl((m_mlx5_qp.qpn << 8) | 4);
494-
m_sq_wqe_hot->ctrl.data[2] = 0;
495-
m_sq_wqe_hot->eseg.inline_hdr_sz = htons(MLX5_ETH_INLINE_HEADER_SIZE);
496-
m_sq_wqe_hot->eseg.cs_flags = XLIO_TX_PACKET_L3_CSUM | XLIO_TX_PACKET_L4_CSUM;
497-
498491
hwqtx_logfunc("%p allocated for %d QPs sq_wqes:%p sq_wqes_end: %p and configured %d WRs "
499492
"BlueFlame: %p",
500493
m_mlx5_qp.qp, m_mlx5_qp.qpn, m_sq_wqes, m_sq_wqes_end, m_tx_num_wr,
@@ -515,15 +508,9 @@ void hw_queue_tx::init_device_memory()
515508

516509
void hw_queue_tx::update_next_wqe_hot()
517510
{
518-
// Preparing next WQE as Ethernet send WQE and index:
511+
// Preparing pointer to the next WQE after a doorbell
519512
m_sq_wqe_hot = &(*m_sq_wqes)[m_sq_wqe_counter & (m_tx_num_wr - 1)];
520513
m_sq_wqe_hot_index = m_sq_wqe_counter & (m_tx_num_wr - 1);
521-
memset(m_sq_wqe_hot, 0, sizeof(mlx5_eth_wqe));
522-
523-
// Fill Ethernet segment with header inline:
524-
struct mlx5_wqe_eth_seg *eth_seg =
525-
(struct mlx5_wqe_eth_seg *)((uint8_t *)m_sq_wqe_hot + sizeof(struct mlx5_wqe_ctrl_seg));
526-
eth_seg->inline_hdr_sz = htons(MLX5_ETH_INLINE_HEADER_SIZE);
527514
}
528515

529516
cq_mgr_tx *hw_queue_tx::init_tx_cq_mgr()
@@ -610,6 +597,10 @@ inline int hw_queue_tx::fill_wqe(xlio_ibv_send_wr *pswr)
610597
"wqe_hot:%p num_sge: %d data_addr: %p data_len: %d max_inline_len: %d inline_len: %d",
611598
m_sq_wqe_hot, pswr->num_sge, data_addr, data_len, max_inline_len, inline_len);
612599

600+
struct mlx5_wqe_eth_seg *eth_seg =
601+
(struct mlx5_wqe_eth_seg *)((uint8_t *)m_sq_wqe_hot + sizeof(struct mlx5_wqe_ctrl_seg));
602+
eth_seg->inline_hdr_sz = htons(MLX5_ETH_INLINE_HEADER_SIZE);
603+
613604
// Fill Ethernet segment with header inline, static data
614605
// were populated in preset after previous packet send
615606
memcpy(cur_seg + offsetof(struct mlx5_wqe_eth_seg, inline_hdr_start), data_addr,
@@ -851,6 +842,8 @@ void hw_queue_tx::send_to_wire(xlio_ibv_send_wr *p_send_wqe, xlio_wr_tx_packet_a
851842
ctrl = (struct xlio_mlx5_wqe_ctrl_seg *)m_sq_wqe_hot;
852843
eseg = (struct mlx5_wqe_eth_seg *)((uint8_t *)m_sq_wqe_hot + sizeof(*ctrl));
853844

845+
memset(m_sq_wqe_hot, 0, sizeof(mlx5_eth_wqe));
846+
854847
/* Configure ctrl segment
855848
* qpn_ds or ctrl.data[1] is set inside fill_wqe()
856849
*/
@@ -1261,7 +1254,6 @@ inline void hw_queue_tx::tls_post_static_params_wqe(xlio_ti *ti, const struct xl
12611254
* one WQEBB and will be posted before m_sq_wqes_end.
12621255
*/
12631256

1264-
// XXX: We set inline_hdr_sz for every new hot wqe. This corrupts UMR WQE without memset().
12651257
memset(m_sq_wqe_hot, 0, sizeof(*m_sq_wqe_hot));
12661258
cseg->opmod_idx_opcode =
12671259
htobe32(((m_sq_wqe_counter & 0xffff) << 8) | MLX5_OPCODE_UMR | (opmod << 24));

0 commit comments

Comments
 (0)