Merge pull request #1797 from lishuang1986/lishuang/rc_pingpong-ipv6
rc_pingpong: Prefer IPv6 wildcard when binding control channel
diff --git a/providers/bnxt_re/main.h b/providers/bnxt_re/main.h
index bf8b2de..b699f9b 100644
--- a/providers/bnxt_re/main.h
+++ b/providers/bnxt_re/main.h
@@ -192,6 +192,7 @@
struct bnxt_re_send *cur_sqe;
uint32_t cur_wqe_cnt;
uint32_t cur_slot_cnt;
+ uint32_t used_slot_cnt;
uint32_t cur_swq_idx;
uint8_t cur_opcode;
bool cur_push_wqe;
diff --git a/providers/bnxt_re/memory.h b/providers/bnxt_re/memory.h
index 7412e73..a0089ee 100644
--- a/providers/bnxt_re/memory.h
+++ b/providers/bnxt_re/memory.h
@@ -130,7 +130,7 @@
return que->tail == que->head;
}
-static inline void bnxt_re_incr_tail(struct bnxt_re_queue *que, uint8_t cnt)
+static inline void bnxt_re_incr_tail(struct bnxt_re_queue *que, uint32_t cnt)
{
que->tail += cnt;
if (que->tail >= que->depth) {
diff --git a/providers/bnxt_re/verbs.c b/providers/bnxt_re/verbs.c
index 5fe67a8..a620c0b 100644
--- a/providers/bnxt_re/verbs.c
+++ b/providers/bnxt_re/verbs.c
@@ -1614,7 +1614,7 @@
if (send_flags & IBV_SEND_INLINE)
hdrval |= ((BNXT_RE_WR_FLAGS_INLINE & BNXT_RE_HDR_FLAGS_MASK)
<< BNXT_RE_HDR_FLAGS_SHIFT);
- hdrval |= ((qp->wr_sq.cur_slot_cnt) & BNXT_RE_HDR_WS_MASK) << BNXT_RE_HDR_WS_SHIFT;
+ hdrval |= ((qp->wr_sq.used_slot_cnt) & BNXT_RE_HDR_WS_MASK) << BNXT_RE_HDR_WS_SHIFT;
opcd = bnxt_re_ibv_to_bnxt_wr_opcd(qp->wr_sq.cur_opcode);
hdrval |= (opcd & BNXT_RE_HDR_WT_MASK);
qp->wr_sq.cur_hdr->rsv_ws_fl_wt = htole32(hdrval);
@@ -1693,7 +1693,7 @@
wrid->wrid = ibvqp->wr_id;
wrid->bytes = length;
wrid->slots = (qp->qpmode == BNXT_RE_WQE_MODE_STATIC) ?
- STATIC_WQE_NUM_SLOTS : qp->wr_sq.cur_slot_cnt;
+ STATIC_WQE_NUM_SLOTS : qp->wr_sq.used_slot_cnt;
wrid->sig = (ibvqp->wr_flags & IBV_SEND_SIGNALED || qp->cap.sqsig) ?
IBV_SEND_SIGNALED : 0;
wrid->wc_opcd = bnxt_re_ibv_wr_to_wc_opcd(qp->wr_sq.cur_opcode);
@@ -1708,6 +1708,7 @@
qp->wr_sq.cur_hdr = NULL;
qp->wr_sq.cur_sqe = NULL;
qp->wr_sq.cur_slot_cnt = 0;
+ qp->wr_sq.used_slot_cnt = 0;
qp->wr_sq.cur_wqe_cnt = 0;
qp->wr_sq.cur_opcode = 0xff;
qp->wr_sq.cur_push_wqe = false;
@@ -1720,11 +1721,10 @@
struct bnxt_re_qp *qp = to_bnxt_re_qp((struct ibv_qp *)ibvqp);
struct bnxt_re_queue *sq = qp->jsqq->hwque;
int err = qp->wr_sq.error;
- uint8_t slots;
+ uint32_t slots;
if (unlikely(err))
goto exit;
- bnxt_re_set_wr_hdr_flags(qp, ibvqp->wr_flags);
qp->wqe_cnt += qp->wr_sq.cur_wqe_cnt;
slots = (qp->qpmode == BNXT_RE_WQE_MODE_STATIC) ?
STATIC_WQE_NUM_SLOTS : qp->wr_sq.cur_slot_cnt;
@@ -1775,8 +1775,10 @@
else
bnxt_re_fill_psns(qp, length, *sq->dbtail, qp->wr_sq.cur_opcode);
+ qp->wr_sq.used_slot_cnt = 3;
bnxt_re_update_swqe(ibvqp, qp, length);
qp->wr_sq.cur_wqe_cnt++;
+ bnxt_re_set_wr_hdr_flags(qp, ibvqp->wr_flags);
}
static void bnxt_re_send_wr_set_sge_list(struct ibv_qp_ex *ibvqp, size_t nsge,
@@ -1816,8 +1818,10 @@
else
bnxt_re_fill_psns(qp, len, *sq->dbtail, qp->wr_sq.cur_opcode);
+ qp->wr_sq.used_slot_cnt = nsge + 2;
bnxt_re_update_swqe(ibvqp, qp, len);
qp->wr_sq.cur_wqe_cnt++;
+ bnxt_re_set_wr_hdr_flags(qp, ibvqp->wr_flags);
}
static void bnxt_re_send_wr_set_inline_data(struct ibv_qp_ex *ibvqp,
@@ -1827,6 +1831,7 @@
struct bnxt_re_queue *sq = qp->jsqq->hwque;
struct bnxt_re_push_buffer *pushb = NULL;
struct ibv_data_buf ibv_buf;
+ uint32_t wrd_slot_cnt;
uint32_t len = 0;
if (unlikely(qp->wr_sq.error))
@@ -1839,6 +1844,7 @@
}
ibv_buf.addr = addr;
ibv_buf.length = length;
+ wrd_slot_cnt = (length + MSG_LEN_ADJ_TO_BYTES) >> SLOTS_RSH_TO_NUM_WQE;
len = bnxt_re_put_wr_inline(sq, &qp->wr_sq.cur_slot_cnt, pushb, 1, &ibv_buf, &length);
if (qp->qptyp == IBV_QPT_UD) {
qp->wr_sq.cur_hdr->lhdr.qkey_len |= htole64(len);
@@ -1851,9 +1857,11 @@
bnxt_re_fill_psns_for_msntbl(qp, len, *sq->dbtail, qp->wr_sq.cur_wqe_cnt);
else
bnxt_re_fill_psns(qp, len, *sq->dbtail, qp->wr_sq.cur_opcode);
+ qp->wr_sq.used_slot_cnt = wrd_slot_cnt + 2;
bnxt_re_update_swqe(ibvqp, qp, len);
qp->wr_sq.cur_wqe_cnt++;
qp->wr_sq.cur_push_size += length;
+ bnxt_re_set_wr_hdr_flags(qp, ibvqp->wr_flags);
}
static void bnxt_re_send_wr_set_inline_data_list(struct ibv_qp_ex *ibvqp, size_t num_buf,
@@ -1894,9 +1902,11 @@
bnxt_re_fill_psns_for_msntbl(qp, len, *sq->dbtail, qp->wr_sq.cur_opcode);
else
bnxt_re_fill_psns(qp, len, *sq->dbtail, qp->wr_sq.cur_opcode);
+ qp->wr_sq.used_slot_cnt = num + 2;
bnxt_re_update_swqe(ibvqp, qp, len);
qp->wr_sq.cur_wqe_cnt++;
qp->wr_sq.cur_push_size += msg_len;
+ bnxt_re_set_wr_hdr_flags(qp, ibvqp->wr_flags);
}
static void bnxt_re_send_wr_set_ud_addr(struct ibv_qp_ex *ibvqp, struct ibv_ah *ibah,
diff --git a/pyverbs/providers/mlx5/mlx5dv.pyx b/pyverbs/providers/mlx5/mlx5dv.pyx
index 00dd977..7f726ec 100644
--- a/pyverbs/providers/mlx5/mlx5dv.pyx
+++ b/pyverbs/providers/mlx5/mlx5dv.pyx
@@ -1998,6 +1998,12 @@
if self.addr:
return <uintptr_t><void*>self.addr
+ @umem_addr.setter
+ def umem_addr(self, addr):
+ if not self.is_user_addr and self.addr != NULL:
+ raise PyverbsUserError('Cannot override the address of an internally allocated UMEM')
+ self.addr = <void*><uintptr_t>addr
+ self.is_user_addr = True
cdef class Mlx5Cqe64(PyverbsObject):
def __init__(self, addr):
diff --git a/tests/test_mlx5_devx.py b/tests/test_mlx5_devx.py
index 7999a9f..cc0e420 100644
--- a/tests/test_mlx5_devx.py
+++ b/tests/test_mlx5_devx.py
@@ -8,8 +8,11 @@
import resource
import unittest
import errno
+import os
from tests.mlx5_base import Mlx5DevxRcResources, Mlx5DevxTrafficBase
+from tests.test_buf import alloc_buf, device_has_cc_dma_bounce, \
+ make_cc_pd, register_buf_mr
from pyverbs.providers.mlx5.mlx5dv import Mlx5Context, Mlx5DVContextAttr, \
Mlx5DevxCmdComp, Mlx5DevxObj, Mlx5UMEM
from pyverbs.providers.mlx5.mlx5_enums import mlx5dv_context_attr_flags
@@ -20,6 +23,72 @@
import tests.utils as u
+class BufDevxRcResources(Mlx5DevxRcResources):
+ """
+ DevX RC resources for a Confidential Computing (CoCo) guest: every DevX
+ UMEM and the data MR live in shared/unprotected memory allocated with
+ Buf on a CC parent domain. Each UMEM is registered through the
+ DevX dmabuf path using an FD exported from its Buf, so all NIC-DMA'd memory
+ is shared as a DMA-bounce device requires.
+ """
+ def __init__(self, dev_name, ib_port, gid_index, msg_size=1024,
+ activate_port_state=False, send_dbr_mode=0):
+ self.bufs = []
+ self.dmabuf_fds = []
+ self.base_pd = None
+ super().__init__(dev_name, ib_port, gid_index, msg_size,
+ activate_port_state, send_dbr_mode)
+
+ def create_pd(self):
+ """Build a CC parent domain and derive the DevX pdn from it."""
+ from pyverbs.providers.mlx5.mlx5dv_objects import Mlx5DvObj
+ from pyverbs.providers.mlx5.mlx5_enums import mlx5dv_obj_type
+ if not device_has_cc_dma_bounce(self.ctx):
+ raise unittest.SkipTest('Device is not a CC DMA-bounce device')
+ self.base_pd, self.pd = make_cc_pd(self.ctx)
+ self.dv_pd = Mlx5DvObj(mlx5dv_obj_type.MLX5DV_OBJ_PD, pd=self.pd).dvpd
+
+ def create_mr(self):
+ """Register the data buffer as a shared Buf MR on the CC PD."""
+ access = ibv_access_flags.IBV_ACCESS_REMOTE_WRITE | \
+ ibv_access_flags.IBV_ACCESS_LOCAL_WRITE | \
+ ibv_access_flags.IBV_ACCESS_REMOTE_READ
+ buf = alloc_buf(self.pd, self.msg_size)
+ self.mr = register_buf_mr(self.pd, buf, self.msg_size, access)
+
+ def create_umem(self, size, access=ibv_access_flags.IBV_ACCESS_LOCAL_WRITE,
+ alignment=resource.getpagesize()):
+ """Return a DevX UMEM backed by a Buf exported as a dmabuf FD."""
+ from pyverbs.providers.mlx5.mlx5_enums import MLX5DV_UMEM_MASK_DMABUF
+ page_size = resource.getpagesize()
+ alloc_size = max(size, page_size)
+ buf = alloc_buf(self.pd, alloc_size)
+ mem.write(buf.addr, bytes(alloc_size), alloc_size) # Zero-fill the buffer
+ fd = self.export_buf_dmabuf_fd(buf)
+ umem = Mlx5UMEM(self.ctx, alloc_size, addr=0, alignment=alignment, access=access,
+ pgsz_bitmap=page_size, comp_mask=MLX5DV_UMEM_MASK_DMABUF, dmabuf_fd=fd)
+ umem.umem_addr = buf.addr
+ self.bufs.append(buf)
+ self.dmabuf_fds.append(fd)
+ return umem
+
+ def export_buf_dmabuf_fd(self, buf):
+ """Export the Buf's dmabuf FD, skipping when it is not dmabuf-backed."""
+ try:
+ return buf.export_dmabuf_fd()
+ except PyverbsRDMAError as ex:
+ if ex.error_code == errno.ENODATA:
+ raise unittest.SkipTest('Buf is not dmabuf-backed')
+ raise
+
+ def close_resources(self):
+ """Close the exported dmabuf FDs"""
+ super().close_resources()
+ for fd in self.dmabuf_fds:
+ os.close(fd)
+ self.dmabuf_fds = []
+
+
class Mlx5DevxRcOdpRes(Mlx5DevxRcResources):
@u.requires_odpv2
def create_mr(self):
@@ -45,6 +114,15 @@
# Send traffic
self.send_imm_traffic()
+ def test_devx_rc_qp_send_imm_buf_umem_traffic(self):
+ """
+ Run DevX RC SEND_IMM traffic where all NIC memory (QP, CQ, doorbell
+ UMEMs and the data MR) is shared CoCo memory: buffers on a CC parent
+ domain, registered as UMEMs via their dmabuf FD.
+ """
+ self.create_players(BufDevxRcResources)
+ self.send_imm_traffic()
+
def test_devx_rc_qp_send_imm_doorbell_less_traffic(self):
"""
Creates two DevX RC QPs with dbr less ext and modifies them to RTS state.
diff --git a/util/udma_barrier.h b/util/udma_barrier.h
index c0cd5f0..bfad001 100644
--- a/util/udma_barrier.h
+++ b/util/udma_barrier.h
@@ -102,6 +102,9 @@
#define udma_to_device_barrier() asm volatile("fence ow,ow" ::: "memory")
#elif defined(__mips__)
#define udma_to_device_barrier() asm volatile("sync" ::: "memory")
+#elif defined(__e2k__)
+#include <e2kbuiltin.h>
+#define udma_to_device_barrier() __builtin_ia32_mfence()
#else
#error No architecture specific memory barrier defines found!
#endif
@@ -140,6 +143,8 @@
#define udma_from_device_barrier() asm volatile("fence ir,ir" ::: "memory")
#elif defined(__mips__)
#define udma_from_device_barrier() asm volatile("sync" ::: "memory")
+#elif defined(__e2k__)
+#define udma_from_device_barrier() __builtin_ia32_lfence()
#else
#error No architecture specific memory barrier defines found!
#endif
@@ -213,6 +218,8 @@
#define mmio_flush_writes() s390_pciwb()
#elif defined(__mips__)
#define mmio_flush_writes() asm volatile("sync" ::: "memory")
+#elif defined(__e2k__)
+#define mmio_flush_writes() __builtin_ia32_sfence()
#else
#error No architecture specific memory barrier defines found!
#endif