From 0ad479f2732fe3e9d942a13948365f0f07a26986 Mon Sep 17 00:00:00 2001 From: Michael Margolin Date: Thu, 11 Jan 2024 12:15:18 +0000 Subject: [PATCH 1/4] Update kernel headers To commit: 2307157c8509 ("RDMA/efa: Add EFA query MR support"). Signed-off-by: Michael Margolin --- kernel-headers/rdma/efa-abi.h | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/kernel-headers/rdma/efa-abi.h b/kernel-headers/rdma/efa-abi.h index d94c32f28..701e2d567 100644 --- a/kernel-headers/rdma/efa-abi.h +++ b/kernel-headers/rdma/efa-abi.h @@ -1,12 +1,13 @@ /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */ /* - * Copyright 2018-2023 Amazon.com, Inc. or its affiliates. All rights reserved. + * Copyright 2018-2024 Amazon.com, Inc. or its affiliates. All rights reserved. */ #ifndef EFA_ABI_USER_H #define EFA_ABI_USER_H #include +#include /* * Increment this value if any changes that break userspace ABI @@ -134,4 +135,22 @@ struct efa_ibv_ex_query_device_resp { __u32 device_caps; }; +enum { + EFA_QUERY_MR_VALIDITY_RECV_IC_ID = 1 << 0, + EFA_QUERY_MR_VALIDITY_RDMA_READ_IC_ID = 1 << 1, + EFA_QUERY_MR_VALIDITY_RDMA_RECV_IC_ID = 1 << 2, +}; + +enum efa_query_mr_attrs { + EFA_IB_ATTR_QUERY_MR_HANDLE = (1U << UVERBS_ID_NS_SHIFT), + EFA_IB_ATTR_QUERY_MR_RESP_IC_ID_VALIDITY, + EFA_IB_ATTR_QUERY_MR_RESP_RECV_IC_ID, + EFA_IB_ATTR_QUERY_MR_RESP_RDMA_READ_IC_ID, + EFA_IB_ATTR_QUERY_MR_RESP_RDMA_RECV_IC_ID, +}; + +enum efa_mr_methods { + EFA_IB_METHOD_MR_QUERY = (1U << UVERBS_ID_NS_SHIFT), +}; + #endif /* EFA_ABI_USER_H */ From 63e2a422b6226d7da186217d0b937d92ac16e819 Mon Sep 17 00:00:00 2001 From: Michael Margolin Date: Thu, 11 Jan 2024 12:16:04 +0000 Subject: [PATCH 2/4] providers/efa: Add query MR to EFA direct verbs Add a new EFA DV interface to query for MR attributes. Initial implementation returns interconnects used by the device to reach the MR to write data for receive, RDMA read, and RDMA write receive operations. Update documentation accordingly. Signed-off-by: Michael Margolin --- debian/ibverbs-providers.symbols | 2 + providers/efa/CMakeLists.txt | 2 +- providers/efa/efadv.h | 18 +++++- providers/efa/libefa.map | 5 ++ providers/efa/man/CMakeLists.txt | 1 + providers/efa/man/efadv_query_mr.3.md | 81 +++++++++++++++++++++++++++ providers/efa/verbs.c | 58 ++++++++++++++++++- 7 files changed, 164 insertions(+), 3 deletions(-) create mode 100644 providers/efa/man/efadv_query_mr.3.md diff --git a/debian/ibverbs-providers.symbols b/debian/ibverbs-providers.symbols index cacf6442f..72361bd10 100644 --- a/debian/ibverbs-providers.symbols +++ b/debian/ibverbs-providers.symbols @@ -166,12 +166,14 @@ libefa.so.1 ibverbs-providers #MINVER# EFA_1.0@EFA_1.0 24 EFA_1.1@EFA_1.1 26 EFA_1.2@EFA_1.2 43 + EFA_1.3@EFA_1.3 50 efadv_create_driver_qp@EFA_1.0 24 efadv_create_qp_ex@EFA_1.1 26 efadv_query_device@EFA_1.1 26 efadv_query_ah@EFA_1.1 26 efadv_cq_from_ibv_cq_ex@EFA_1.2 43 efadv_create_cq@EFA_1.2 43 + efadv_query_mr@EFA_1.3 50 libmana.so.1 ibverbs-providers #MINVER# * Build-Depends-Package: libibverbs-dev MANA_1.0@MANA_1.0 41 diff --git a/providers/efa/CMakeLists.txt b/providers/efa/CMakeLists.txt index 618c8b7af..e999f3b77 100644 --- a/providers/efa/CMakeLists.txt +++ b/providers/efa/CMakeLists.txt @@ -3,7 +3,7 @@ if (ENABLE_LTTNG AND LTTNGUST_FOUND) endif() rdma_shared_provider(efa libefa.map - 1 1.2.${PACKAGE_VERSION} + 1 1.3.${PACKAGE_VERSION} ${TRACE_FILE} efa.c verbs.c diff --git a/providers/efa/efadv.h b/providers/efa/efadv.h index 845822a37..f7f9d43db 100644 --- a/providers/efa/efadv.h +++ b/providers/efa/efadv.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ /* - * Copyright 2019-2023 Amazon.com, Inc. or its affiliates. All rights reserved. + * Copyright 2019-2024 Amazon.com, Inc. or its affiliates. All rights reserved. */ #ifndef __EFADV_H__ @@ -94,6 +94,22 @@ static inline int efadv_wc_read_sgid(struct efadv_cq *efadv_cq, return efadv_cq->wc_read_sgid(efadv_cq, sgid); } +enum { + EFADV_MR_ATTR_VALIDITY_RECV_IC_ID = 1 << 0, + EFADV_MR_ATTR_VALIDITY_RDMA_READ_IC_ID = 1 << 1, + EFADV_MR_ATTR_VALIDITY_RDMA_RECV_IC_ID = 1 << 2, +}; + +struct efadv_mr_attr { + uint64_t comp_mask; + uint16_t ic_id_validity; + uint16_t recv_ic_id; + uint16_t rdma_read_ic_id; + uint16_t rdma_recv_ic_id; +}; + +int efadv_query_mr(struct ibv_mr *ibvmr, struct efadv_mr_attr *attr, uint32_t inlen); + #ifdef __cplusplus } #endif diff --git a/providers/efa/libefa.map b/providers/efa/libefa.map index 0e7f96f27..eff647d18 100644 --- a/providers/efa/libefa.map +++ b/providers/efa/libefa.map @@ -19,3 +19,8 @@ EFA_1.2 { efadv_create_cq; efadv_wc_read_sgid; } EFA_1.1; + +EFA_1.3 { + global: + efadv_query_mr; +} EFA_1.2; diff --git a/providers/efa/man/CMakeLists.txt b/providers/efa/man/CMakeLists.txt index 335b6e9ef..e7ad126ed 100644 --- a/providers/efa/man/CMakeLists.txt +++ b/providers/efa/man/CMakeLists.txt @@ -4,4 +4,5 @@ rdma_man_pages( efadv_create_qp_ex.3.md efadv_query_ah.3.md efadv_query_device.3.md + efadv_query_mr.3.md ) diff --git a/providers/efa/man/efadv_query_mr.3.md b/providers/efa/man/efadv_query_mr.3.md new file mode 100644 index 000000000..24da994b8 --- /dev/null +++ b/providers/efa/man/efadv_query_mr.3.md @@ -0,0 +1,81 @@ +--- +layout: page +title: EFADV_QUERY_MR +section: 3 +tagline: Verbs +date: 2023-11-13 +header: "EFA Direct Verbs Manual" +footer: efa +--- + +# NAME + +efadv_query_mr - Query EFA specific Memory Region attributes + +# SYNOPSIS + +```c +#include + +int efadv_query_mr(struct ibv_mr *ibvmr, struct efadv_mr_attr *attr, uint32_t inlen); +``` + +# DESCRIPTION + +**efadv_query_mr()** queries device-specific Memory Region attributes. + +Compatibility is handled using the comp_mask and inlen fields. + +```c +struct efadv_mr_attr { + uint64_t comp_mask; + uint16_t ic_id_validity; + uint16_t recv_ic_id; + uint16_t rdma_read_ic_id; + uint16_t rdma_recv_ic_id; +}; +``` + +*inlen* +: In: Size of struct efadv_mr_attr. + +*comp_mask* +: Compatibility mask. + +*ic_id_validity* +: Validity mask of interconnect id fields: + + EFADV_MR_ATTR_VALIDITY_RECV_IC_ID: + recv_ic_id has a valid value. + + EFADV_MR_ATTR_VALIDITY_RDMA_READ_IC_ID: + rdma_read_ic_id has a valid value. + + EFADV_MR_ATTR_VALIDITY_RDMA_RECV_IC_ID: + rdma_recv_ic_id has a valid value. + +*recv_ic_id* +: Physical interconnect used by the device to reach the MR for receive operation. + +*rdma_read_ic_id* +: Physical interconnect used by the device to reach the MR for RDMA read operation. + +*rdma_recv_ic_id* +: Physical interconnect used by the device to reach the MR for RDMA write receive. + +# RETURN VALUE + +**efadv_query_mr()** returns 0 on success, or the value of errno on failure +(which indicates the failure reason). + +# SEE ALSO + +**efadv**(7) + +# NOTES + +* Compatibility mask (comp_mask) is an out field and currently has no values. + +# AUTHORS + +Michael Margolin diff --git a/providers/efa/verbs.c b/providers/efa/verbs.c index 093e9eb21..dc7a3431c 100644 --- a/providers/efa/verbs.c +++ b/providers/efa/verbs.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause /* - * Copyright 2019-2023 Amazon.com, Inc. or its affiliates. All rights reserved. + * Copyright 2019-2024 Amazon.com, Inc. or its affiliates. All rights reserved. */ #include @@ -279,6 +279,62 @@ struct ibv_mr *efa_reg_mr(struct ibv_pd *ibvpd, void *sva, size_t len, return &mr->vmr.ibv_mr; } +int efadv_query_mr(struct ibv_mr *ibvmr, struct efadv_mr_attr *attr, uint32_t inlen) +{ + uint16_t rdma_read_ic_id = 0; + uint16_t rdma_recv_ic_id = 0; + uint16_t ic_id_validity = 0; + uint16_t recv_ic_id = 0; + int err; + + DECLARE_COMMAND_BUFFER(cmd, + UVERBS_OBJECT_MR, + EFA_IB_METHOD_MR_QUERY, + 5); + + if (!is_efa_dev(ibvmr->context->device)) { + verbs_err(verbs_get_ctx(ibvmr->context), "Not an EFA device\n"); + return EOPNOTSUPP; + } + + if (!vext_field_avail(typeof(*attr), rdma_recv_ic_id, inlen)) { + verbs_err(verbs_get_ctx(ibvmr->context), "Compatibility issues\n"); + return EINVAL; + } + + memset(attr, 0, inlen); + fill_attr_in_obj(cmd, EFA_IB_ATTR_QUERY_MR_HANDLE, ibvmr->handle); + fill_attr_out(cmd, EFA_IB_ATTR_QUERY_MR_RESP_IC_ID_VALIDITY, + &ic_id_validity, sizeof(ic_id_validity)); + fill_attr_out(cmd, EFA_IB_ATTR_QUERY_MR_RESP_RECV_IC_ID, + &recv_ic_id, sizeof(recv_ic_id)); + fill_attr_out(cmd, EFA_IB_ATTR_QUERY_MR_RESP_RDMA_READ_IC_ID, + &rdma_read_ic_id, sizeof(rdma_read_ic_id)); + fill_attr_out(cmd, EFA_IB_ATTR_QUERY_MR_RESP_RDMA_RECV_IC_ID, + &rdma_recv_ic_id, sizeof(rdma_recv_ic_id)); + + err = execute_ioctl(ibvmr->context, cmd); + if (err) { + verbs_err(verbs_get_ctx(ibvmr->context), "Failed to query MR\n"); + return err; + } + + if (ic_id_validity & EFA_QUERY_MR_VALIDITY_RECV_IC_ID) { + attr->recv_ic_id = recv_ic_id; + attr->ic_id_validity |= EFADV_MR_ATTR_VALIDITY_RECV_IC_ID; + } + if (ic_id_validity & EFA_QUERY_MR_VALIDITY_RDMA_READ_IC_ID) { + attr->rdma_read_ic_id = rdma_read_ic_id; + attr->ic_id_validity |= EFADV_MR_ATTR_VALIDITY_RDMA_READ_IC_ID; + } + if (ic_id_validity & EFA_QUERY_MR_VALIDITY_RDMA_RECV_IC_ID) { + attr->rdma_recv_ic_id = rdma_recv_ic_id; + attr->ic_id_validity |= EFADV_MR_ATTR_VALIDITY_RDMA_RECV_IC_ID; + } + + return 0; +} + int efa_dereg_mr(struct verbs_mr *vmr) { struct efa_mr *mr = container_of(vmr, struct efa_mr, vmr); From 620ae50a35838b70d659032f96714887834159d1 Mon Sep 17 00:00:00 2001 From: Michael Margolin Date: Thu, 11 Jan 2024 12:16:04 +0000 Subject: [PATCH 3/4] pyverbs/efa: Add EFA direct verbs query MR Expose efadv_query_mr verb and the related types in pyverbs. Signed-off-by: Michael Margolin --- pyverbs/providers/efa/efa_enums.pyx | 7 +++- pyverbs/providers/efa/efadv.pxd | 6 ++- pyverbs/providers/efa/efadv.pyx | 54 ++++++++++++++++++++++++++- pyverbs/providers/efa/efadv_enums.pxd | 5 +++ pyverbs/providers/efa/libefa.pxd | 10 ++++- 5 files changed, 78 insertions(+), 4 deletions(-) diff --git a/pyverbs/providers/efa/efa_enums.pyx b/pyverbs/providers/efa/efa_enums.pyx index 9fe32a95f..b3432f146 100644 --- a/pyverbs/providers/efa/efa_enums.pyx +++ b/pyverbs/providers/efa/efa_enums.pyx @@ -1,5 +1,5 @@ # SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) -# Copyright 2020-2023 Amazon.com, Inc. or its affiliates. All rights reserved. +# Copyright 2020-2024 Amazon.com, Inc. or its affiliates. All rights reserved. #cython: language_level=3 @@ -15,3 +15,8 @@ cdef extern from 'infiniband/efadv.h': cpdef enum: EFADV_WC_EX_WITH_SGID + + cpdef enum: + EFADV_MR_ATTR_VALIDITY_RECV_IC_ID + EFADV_MR_ATTR_VALIDITY_RDMA_READ_IC_ID + EFADV_MR_ATTR_VALIDITY_RDMA_RECV_IC_ID diff --git a/pyverbs/providers/efa/efadv.pxd b/pyverbs/providers/efa/efadv.pxd index 9fa488ac0..12e11f8ce 100644 --- a/pyverbs/providers/efa/efadv.pxd +++ b/pyverbs/providers/efa/efadv.pxd @@ -1,5 +1,5 @@ # SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) -# Copyright 2020-2022 Amazon.com, Inc. or its affiliates. All rights reserved. +# Copyright 2020-2024 Amazon.com, Inc. or its affiliates. All rights reserved. #cython: language_level=3 @@ -46,3 +46,7 @@ cdef class EfaCQ(CQEX): cdef class EfaDVCQInitAttr(PyverbsObject): cdef dv.efadv_cq_init_attr cq_init_attr + + +cdef class EfaDVMRAttr(PyverbsObject): + cdef dv.efadv_mr_attr mr_attr diff --git a/pyverbs/providers/efa/efadv.pyx b/pyverbs/providers/efa/efadv.pyx index 1cd8c6ced..bf8cdba4e 100644 --- a/pyverbs/providers/efa/efadv.pyx +++ b/pyverbs/providers/efa/efadv.pyx @@ -1,5 +1,5 @@ # SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) -# Copyright 2020-2023 Amazon.com, Inc. or its affiliates. All rights reserved. +# Copyright 2020-2024 Amazon.com, Inc. or its affiliates. All rights reserved. cimport pyverbs.providers.efa.efadv_enums as dve cimport pyverbs.providers.efa.libefa as dv @@ -11,6 +11,7 @@ import pyverbs.enums as e cimport pyverbs.libibverbs as v from pyverbs.pd cimport PD from pyverbs.qp cimport QP, QPEx, QPInitAttr, QPInitAttrEx +from pyverbs.mr cimport MR def dev_cap_to_str(flags): @@ -250,3 +251,54 @@ cdef class EfaCQ(CQEX): if err: return None return sgid + + +cdef class EfaDVMRAttr(PyverbsObject): + """ + Represents efadv_mr_attr struct, which exposes efa-specific MR attributes, + reported by efadv_query_mr. + """ + @property + def comp_mask(self): + return self.mr_attr.comp_mask + + @property + def ic_id_validity(self): + return self.mr_attr.ic_id_validity + + @property + def recv_ic_id(self): + return self.mr_attr.recv_ic_id + + @property + def rdma_read_ic_id(self): + return self.mr_attr.rdma_read_ic_id + + @property + def rdma_recv_ic_id(self): + return self.mr_attr.rdma_recv_ic_id + + def __str__(self): + print_format = '{:28}: {:<20}\n' + return print_format.format('comp_mask', self.mr_attr.comp_mask) + \ + print_format.format('Interconnect id validity', self.mr_attr.ic_id_validity) + \ + print_format.format('Receive interconnect id', self.mr_attr.recv_ic_id) + \ + print_format.format('RDMA read interconnect id', self.mr_attr.rdma_read_ic_id) + \ + print_format.format('RDMA receive interconnect id', self.mr_attr.rdma_recv_ic_id) + + +cdef class EfaMR(MR): + """ + Represents an MR with EFA specific properties + """ + def query(self): + """ + Queries the MR for device-specific attributes. + :return: An EfaDVMRAttr containing the attributes. + """ + mr_attr = EfaDVMRAttr() + rc = dv.efadv_query_mr(self.mr, &mr_attr.mr_attr, sizeof(mr_attr.mr_attr)) + if rc: + raise PyverbsRDMAError(f'Failed to query EFA MR', rc) + + return mr_attr diff --git a/pyverbs/providers/efa/efadv_enums.pxd b/pyverbs/providers/efa/efadv_enums.pxd index 9d65ade30..219f0db1d 100644 --- a/pyverbs/providers/efa/efadv_enums.pxd +++ b/pyverbs/providers/efa/efadv_enums.pxd @@ -16,3 +16,8 @@ cdef extern from 'infiniband/efadv.h': cpdef enum: EFADV_WC_EX_WITH_SGID + + cpdef enum: + EFADV_MR_ATTR_VALIDITY_RECV_IC_ID + EFADV_MR_ATTR_VALIDITY_RDMA_READ_IC_ID + EFADV_MR_ATTR_VALIDITY_RDMA_RECV_IC_ID diff --git a/pyverbs/providers/efa/libefa.pxd b/pyverbs/providers/efa/libefa.pxd index 8736e1889..ca6471a84 100644 --- a/pyverbs/providers/efa/libefa.pxd +++ b/pyverbs/providers/efa/libefa.pxd @@ -1,5 +1,5 @@ # SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) -# Copyright 2020-2022 Amazon.com, Inc. or its affiliates. All rights reserved. +# Copyright 2020-2024 Amazon.com, Inc. or its affiliates. All rights reserved. from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t cimport pyverbs.libibverbs as v @@ -35,6 +35,13 @@ cdef extern from 'infiniband/efadv.h': cdef struct efadv_cq: uint64_t comp_mask; + cdef struct efadv_mr_attr: + uint64_t comp_mask; + uint16_t ic_id_validity; + uint16_t recv_ic_id; + uint16_t rdma_read_ic_id; + uint16_t rdma_recv_ic_id; + int efadv_query_device(v.ibv_context *ibvctx, efadv_device_attr *attrs, uint32_t inlen) int efadv_query_ah(v.ibv_ah *ibvah, efadv_ah_attr *attr, @@ -51,3 +58,4 @@ cdef extern from 'infiniband/efadv.h': uint32_t inlen) efadv_cq *efadv_cq_from_ibv_cq_ex(v.ibv_cq_ex *ibvcqx) int efadv_wc_read_sgid(efadv_cq *efadv_cq, v.ibv_gid *sgid) + int efadv_query_mr(v.ibv_mr *ibvmr, efadv_mr_attr *attr, uint32_t inlen) From 6d136f36cfc03c9ce7a381895797612b22d9bcb4 Mon Sep 17 00:00:00 2001 From: Michael Margolin Date: Thu, 11 Jan 2024 12:16:04 +0000 Subject: [PATCH 4/4] tests: Add EFA direct verbs query MR test Add basic coverage for EFA direct verbs query MR function. Signed-off-by: Michael Margolin --- tests/test_efadv.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/tests/test_efadv.py b/tests/test_efadv.py index 7a74a0773..901ddefe1 100644 --- a/tests/test_efadv.py +++ b/tests/test_efadv.py @@ -1,5 +1,5 @@ # SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) -# Copyright 2020-2023 Amazon.com, Inc. or its affiliates. All rights reserved. +# Copyright 2020-2024 Amazon.com, Inc. or its affiliates. All rights reserved. """ Test module for efa direct-verbs. """ @@ -152,3 +152,24 @@ def test_dv_cq_ex_with_sgid(self): u.send(self.client, sg, e.IBV_WR_SEND, new_send=True, qp_idx=0, ah=ah_client) u.poll_cq_ex(self.client.cq) u.poll_cq_ex(self.server.cq, sgid=self.server.remote_gid) + + +class EfaMRTest(EfaAPITestCase): + """ + Test various functionalities of the EfaMR class. + """ + def test_efadv_query_mr(self): + with PD(self.ctx) as pd: + try: + mr = efa.EfaMR(pd, 16, e.IBV_ACCESS_LOCAL_WRITE) + mr_attrs = mr.query() + if self.config['verbosity']: + print(f'\n{mr_attrs}') + + assert(mr_attrs.ic_id_validity & ~(efa_e.EFADV_MR_ATTR_VALIDITY_RECV_IC_ID | + efa_e.EFADV_MR_ATTR_VALIDITY_RDMA_READ_IC_ID | + efa_e.EFADV_MR_ATTR_VALIDITY_RDMA_RECV_IC_ID) == 0) + except PyverbsRDMAError as ex: + if ex.error_code in [errno.EOPNOTSUPP, errno.ENOTTY, errno.EPROTONOSUPPORT]: + raise unittest.SkipTest(f'Query MR not supported, errno={ex.error_code}') + raise ex