From 085f71306114ba220fd1a91f2c086ca54c618a2f Mon Sep 17 00:00:00 2001 From: Shi Jin Date: Tue, 7 Nov 2023 19:37:39 +0000 Subject: [PATCH] prov/efa: Introduce efa specific domain operations Make efa onboard the fi_open_ops API, which allows user to access efa specific domain ops. The usage of this API is documented in fi_efa.7.md. Also added a suite of efa unit test. Signed-off-by: Shi Jin --- man/fi_efa.7.md | 63 +++++++++++ prov/efa/Makefile.include | 9 ++ prov/efa/configure.m4 | 22 ++++ prov/efa/src/efa.h | 1 + prov/efa/src/efa_domain.c | 80 +++++++++++++- prov/efa/src/fi_ext_efa.h | 55 ++++++++++ prov/efa/test/efa_unit_test_domain.c | 150 +++++++++++++++++++++++++++ prov/efa/test/efa_unit_test_mocks.c | 47 ++++++++- prov/efa/test/efa_unit_test_mocks.h | 12 +++ prov/efa/test/efa_unit_tests.c | 5 + prov/efa/test/efa_unit_tests.h | 5 + 11 files changed, 447 insertions(+), 2 deletions(-) create mode 100644 prov/efa/src/fi_ext_efa.h create mode 100644 prov/efa/test/efa_unit_test_domain.c diff --git a/man/fi_efa.7.md b/man/fi_efa.7.md index f11fa318232..b2455122216 100644 --- a/man/fi_efa.7.md +++ b/man/fi_efa.7.md @@ -134,6 +134,69 @@ provider for AWS Neuron or Habana SynapseAI. delivered to the target buffer only once. If endpoint is not able to support this feature, it will return -FI_EOPNOTSUPP for the call to fi_setopt(). +# PROVIDER SPECIFIC DOMAIN OPS +The efa provider exports extensions for additional operations +that are not provided by the standard libfabric interface. These extensions +are available via the "`fi_ext_efa.h`" header file. + +## Domain Operation Extension + +Domain operation extension is obtained by calling `fi_open_ops` +(see [`fi_domain`(3)](fi_domain.3.html)) +```c +int fi_open_ops(struct fid *domain, const char *name, uint64_t flags, + void **ops, void *context); +``` +and requesting `FI_EFA_DOMAIN_OPS` in `name`. `fi_open_ops` returns `ops` as +the pointer to the function table `fi_efa_ops_domain` defined as follows: + +```c +struct fi_efa_ops_domain { + int (*query_mr)(struct fid_mr *mr, struct fi_efa_mr_attr *mr_attr); +}; +``` + +It contains the following operations + +### query_mr +This op query an existing memory registration (mr), and returns the efa +specific mr attribute which is defined as follows + +```c +struct fi_efa_mr_attr { + uint16_t pci_bus_id_validity; + uint16_t recv_pci_bus_id; + uint16_t rdma_read_pci_bus_id; + uint16_t rdma_recv_pci_bus_id; +}; +``` + +*pci_bus_id_validity* +: Validity mask of PCI bus id fields: + + FI_EFA_MR_ATTR_VALIDITY_RECV_PCI_BUS_ID: + recv_pci_bus_id has a valid value. + + FI_EFA_MR_ATTR_VALIDITY_RDMA_READ_PCI_BUS_ID: + rdma_read_pci_bus_id has a valid value. + + FI_EFA_MR_ATTR_VALIDITY_RDMA_RECV_PCI_BUS_ID: + rdma_recv_pci_bus_id has a valid value. + +*recv_pci_bus_id* +: Physical PCIe bus used by the device to reach the MR for receive operation. + +*rdma_read_pci_bus_id* +: Physical PCIe bus used by the device to reach the MR for RDMA read operation. + +*rdma_recv_pci_bus_id* +: Physical PCIe bus used by the device to reach the MR for RDMA write receive. + +#### Return value +**query_mr()** returns 0 on success, or the value of errno on failure +(which indicates the failure reason). + + # RUNTIME PARAMETERS *FI_EFA_TX_SIZE* diff --git a/prov/efa/Makefile.include b/prov/efa/Makefile.include index 538e778c81f..00fe6d54a0c 100644 --- a/prov/efa/Makefile.include +++ b/prov/efa/Makefile.include @@ -94,6 +94,7 @@ _efa_headers = \ prov/efa/src/efa_tp.h \ prov/efa/src/efa_prov.h \ prov/efa/src/efa_env.h \ + prov/efa/src/fi_ext_efa.h \ prov/efa/src/dgram/efa_dgram_ep.h \ prov/efa/src/dgram/efa_dgram_cq.h \ prov/efa/src/rdm/efa_rdm_peer.h \ @@ -132,6 +133,7 @@ nodist_prov_efa_test_efa_unit_test_SOURCES = \ prov/efa/test/efa_unit_tests.c \ prov/efa/test/efa_unit_test_mocks.c \ prov/efa/test/efa_unit_test_common.c \ + prov/efa/test/efa_unit_test_domain.c \ prov/efa/test/efa_unit_test_ep.c \ prov/efa/test/efa_unit_test_av.c \ prov/efa/test/efa_unit_test_cq.c \ @@ -164,6 +166,10 @@ if HAVE_NEURON prov_efa_test_efa_unit_test_LDFLAGS += -Wl,--wrap=neuron_alloc endif HAVE_NEURON +if HAVE_EFADV_QUERY_MR +prov_efa_test_efa_unit_test_LDFLAGS += -Wl,--wrap=efadv_query_mr +endif HAVE_EFADV_QUERY_MR + prov_efa_test_efa_unit_test_LIBS = $(efa_LIBS) $(linkback) endif ENABLE_EFA_UNIT_TEST @@ -173,6 +179,9 @@ efa_CPPFLAGS += \ -I$(top_srcdir)/prov/efa/src/dgram/ \ -I$(top_srcdir)/prov/efa/src/rdm/ +rdmainclude_HEADERS += \ + prov/efa/src/fi_ext_efa.h + if HAVE_EFA_DL pkglib_LTLIBRARIES += libefa-fi.la libefa_fi_la_SOURCES = $(_efa_files) $(_efa_headers) $(common_srcs) diff --git a/prov/efa/configure.m4 b/prov/efa/configure.m4 index 56bbfee0f12..0ae79852878 100644 --- a/prov/efa/configure.m4 +++ b/prov/efa/configure.m4 @@ -75,6 +75,7 @@ AC_DEFUN([FI_EFA_CONFIGURE],[ efa_support_data_in_order_aligned_128_byte=0 efadv_support_extended_cq=0 hav_efa_dmabuf_mr=0 + have_efadv_query_mr=0 dnl $have_neuron is defined at top-level configure.ac AM_CONDITIONAL([HAVE_NEURON], [ test x"$have_neuron" = x1 ]) @@ -135,6 +136,23 @@ AC_DEFUN([FI_EFA_CONFIGURE],[ [], [efadv_support_extended_cq=0], [[#include ]]) + + dnl For efadv_query_mr, we check several things, + dnl and if any of them fail, we disable it + have_efadv_query_mr=1 + AC_CHECK_DECL([efadv_query_mr], + [], + [have_efadv_query_mr=0], + [[#include ]]) + AC_CHECK_MEMBER([struct efadv_mr_attr.rdma_recv_pci_bus_id], + [], + [have_efadv_query_mr=0], + [[#include ]]) + dnl there is more symbols in the enum, only check one of them + AC_CHECK_DECL([EFADV_MR_ATTR_VALIDITY_RDMA_READ_PCI_BUS_ID], + [], + [have_efadv_query_mr=0], + [[#include ]]) ]) AC_DEFINE_UNQUOTED([HAVE_RDMA_SIZE], @@ -158,6 +176,9 @@ AC_DEFUN([FI_EFA_CONFIGURE],[ AC_DEFINE_UNQUOTED([HAVE_EFA_DMABUF_MR], [$have_efa_dmabuf_mr], [Indicates if ibv_reg_dmabuf_mr verbs is available]) + AC_DEFINE_UNQUOTED([HAVE_EFADV_QUERY_MR], + [$have_efadv_query_mr], + [Indicates if efadv_query_mr verbs is available]) CPPFLAGS=$save_CPPFLAGS @@ -202,6 +223,7 @@ AC_DEFUN([FI_EFA_CONFIGURE],[ AC_DEFINE_UNQUOTED([EFA_UNIT_TEST], [$efa_unit_test], [EFA unit testing]) AM_CONDITIONAL([HAVE_EFADV_CQ_EX], [ test $efadv_support_extended_cq = 1]) + AM_CONDITIONAL([HAVE_EFADV_QUERY_MR], [ test $have_efadv_query_mr = 1]) AM_CONDITIONAL([ENABLE_EFA_UNIT_TEST], [ test x"$enable_efa_unit_test" != xno]) AC_SUBST(efa_CPPFLAGS) diff --git a/prov/efa/src/efa.h b/prov/efa/src/efa.h index ae3756ca468..052e6b0f145 100644 --- a/prov/efa/src/efa.h +++ b/prov/efa/src/efa.h @@ -81,6 +81,7 @@ #include "rdm/efa_rdm_pke.h" #include "rdm/efa_rdm_peer.h" #include "rdm/efa_rdm_util.h" +#include "fi_ext_efa.h" #define EFA_ABI_VER_MAX_LEN 8 diff --git a/prov/efa/src/efa_domain.c b/prov/efa/src/efa_domain.c index 328fd932d5c..b54f7ea3192 100644 --- a/prov/efa/src/efa_domain.c +++ b/prov/efa/src/efa_domain.c @@ -41,18 +41,22 @@ #include "rdm/efa_rdm_atomic.h" #include "dgram/efa_dgram_ep.h" #include "dgram/efa_dgram_cq.h" +#include "infiniband/efadv.h" struct dlist_entry g_efa_domain_list; static int efa_domain_close(fid_t fid); +static int efa_domain_ops_open(struct fid *fid, const char *ops_name, + uint64_t flags, void **ops, void *context); + static struct fi_ops efa_ops_domain_fid = { .size = sizeof(struct fi_ops), .close = efa_domain_close, .bind = fi_no_bind, .control = fi_no_control, - .ops_open = fi_no_ops_open, + .ops_open = efa_domain_ops_open, }; static struct fi_ops_domain efa_ops_domain_dgram = { @@ -380,3 +384,77 @@ static int efa_domain_close(fid_t fid) return 0; } +/** + * @brief Query EFA specific Memory Region attributes + * + * @param mr ptr to fid_mr + * @param mr_attr ptr to fi_efa_mr_attr + * @return int 0 on success, negative integer on failure + */ +#if HAVE_EFADV_QUERY_MR + +static int +efa_domain_query_mr(struct fid_mr *mr_fid, struct fi_efa_mr_attr *mr_attr) +{ + struct efadv_mr_attr attr = {0}; + struct efa_mr *efa_mr; + int ret; + + memset(mr_attr, 0, sizeof(*mr_attr)); + + efa_mr = container_of(mr_fid, struct efa_mr, mr_fid); + ret = efadv_query_mr(efa_mr->ibv_mr, &attr, sizeof(attr)); + if (ret) { + EFA_WARN(FI_LOG_DOMAIN, "efadv_query_mr failed. err: %d\n", ret); + return ret; + } + + /* Translate the validity masks and bus_id from efadv_mr_attr to fi_efa_mr_attr */ + if (attr.pci_bus_id_validity & EFADV_MR_ATTR_VALIDITY_RECV_PCI_BUS_ID) { + mr_attr->recv_pci_bus_id = attr.recv_pci_bus_id; + mr_attr->pci_bus_id_validity |= FI_EFA_MR_ATTR_VALIDITY_RECV_PCI_BUS_ID; + } + + if (attr.pci_bus_id_validity & EFADV_MR_ATTR_VALIDITY_RDMA_READ_PCI_BUS_ID) { + mr_attr->rdma_read_pci_bus_id = attr.rdma_read_pci_bus_id; + mr_attr->pci_bus_id_validity |= FI_EFA_MR_ATTR_VALIDITY_RDMA_READ_PCI_BUS_ID; + } + + if (attr.pci_bus_id_validity & EFADV_MR_ATTR_VALIDITY_RDMA_RECV_PCI_BUS_ID) { + mr_attr->rdma_recv_pci_bus_id = attr.rdma_recv_pci_bus_id; + mr_attr->pci_bus_id_validity |= FI_EFA_MR_ATTR_VALIDITY_RDMA_RECV_PCI_BUS_ID; + } + + return FI_SUCCESS; +} + +#else + +static int +efa_domain_query_mr(struct fid_mr *mr, struct fi_efa_mr_attr *mr_attr) +{ + return -FI_ENOSYS; +} + +#endif /* HAVE_EFADV_QUERY_MR */ + +static struct fi_efa_ops_domain efa_ops_domain = { + .query_mr = efa_domain_query_mr, +}; + +static int +efa_domain_ops_open(struct fid *fid, const char *ops_name, uint64_t flags, + void **ops, void *context) +{ + int ret = FI_SUCCESS; + + if (strcmp(ops_name, FI_EFA_DOMAIN_OPS) == 0) { + *ops = &efa_ops_domain; + } else { + EFA_WARN(FI_LOG_DOMAIN, + "Unknown ops name: %s\n", ops_name); + ret = -FI_EINVAL; + } + + return ret; +} diff --git a/prov/efa/src/fi_ext_efa.h b/prov/efa/src/fi_ext_efa.h new file mode 100644 index 00000000000..d8ce18ea0b2 --- /dev/null +++ b/prov/efa/src/fi_ext_efa.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) Amazon.com, Inc. or its affiliates. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _FI_EXT_EFA_H_ +#define _FI_EXT_EFA_H_ + +#define FI_EFA_DOMAIN_OPS "efa domain ops" + +struct fi_efa_mr_attr { + uint16_t pci_bus_id_validity; + uint16_t recv_pci_bus_id; + uint16_t rdma_read_pci_bus_id; + uint16_t rdma_recv_pci_bus_id; +}; + +enum { + FI_EFA_MR_ATTR_VALIDITY_RECV_PCI_BUS_ID = 1 << 0, + FI_EFA_MR_ATTR_VALIDITY_RDMA_READ_PCI_BUS_ID = 1 << 1, + FI_EFA_MR_ATTR_VALIDITY_RDMA_RECV_PCI_BUS_ID = 1 << 2, +}; + +struct fi_efa_ops_domain { + int (*query_mr)(struct fid_mr *mr, struct fi_efa_mr_attr *mr_attr); +}; + +#endif /* _FI_EXT_EFA_H_ */ diff --git a/prov/efa/test/efa_unit_test_domain.c b/prov/efa/test/efa_unit_test_domain.c new file mode 100644 index 00000000000..9b169a7ce8e --- /dev/null +++ b/prov/efa/test/efa_unit_test_domain.c @@ -0,0 +1,150 @@ +#include "efa_unit_tests.h" + +/* test fi_open_ops with a wrong name */ +void test_efa_domain_open_ops_wrong_name(struct efa_resource **state) +{ + struct efa_resource *resource = *state; + int ret; + struct fi_efa_ops_domain *efa_domain_ops; + + efa_unit_test_resource_construct(resource, FI_EP_RDM); + + ret = fi_open_ops(&resource->domain->fid, "arbitrary name", 0, (void **)&efa_domain_ops, NULL); + assert_int_equal(ret, -FI_EINVAL); +} + +#if HAVE_EFADV_QUERY_MR + +static +void test_efa_domain_open_ops_mr_query_common( + struct efa_resource *resource, + uint16_t expected_pci_bus_id_validity, + uint16_t expected_recv_pci_bus_id, + uint16_t expected_rdma_read_pci_bus_id, + uint16_t expected_rdma_recv_pci_bus_id) +{ + int ret; + struct fi_efa_ops_domain *efa_domain_ops; + struct fi_efa_mr_attr efa_mr_attr = {0}; + struct efa_mr mr = {0}; + struct fid_mr mr_fid = {0}; + + mr.mr_fid = mr_fid; + mr.ibv_mr = NULL; + + ret = fi_open_ops(&resource->domain->fid, FI_EFA_DOMAIN_OPS, 0, (void **)&efa_domain_ops, NULL); + assert_int_equal(ret, 0); + + ret = efa_domain_ops->query_mr(&mr.mr_fid, &efa_mr_attr); + assert_int_equal(ret, 0); + + assert_true(efa_mr_attr.pci_bus_id_validity == expected_pci_bus_id_validity); + + if (efa_mr_attr.pci_bus_id_validity & FI_EFA_MR_ATTR_VALIDITY_RECV_PCI_BUS_ID) + assert_true(efa_mr_attr.recv_pci_bus_id == expected_recv_pci_bus_id); + + if (efa_mr_attr.pci_bus_id_validity & FI_EFA_MR_ATTR_VALIDITY_RDMA_READ_PCI_BUS_ID) + assert_true(efa_mr_attr.rdma_read_pci_bus_id == expected_rdma_read_pci_bus_id); + + if (efa_mr_attr.pci_bus_id_validity & FI_EFA_MR_ATTR_VALIDITY_RDMA_RECV_PCI_BUS_ID) + assert_true(efa_mr_attr.rdma_recv_pci_bus_id == expected_rdma_recv_pci_bus_id); +} + +/* run mr query for recv pci bus id */ +void test_efa_domain_open_ops_mr_query_recv(struct efa_resource **state) +{ + struct efa_resource *resource = *state; + + efa_unit_test_resource_construct(resource, FI_EP_RDM); + + /* set recv_pci_bus_id as 0 */ + g_efa_unit_test_mocks.efadv_query_mr = &efa_mock_efadv_query_mr_recv_pci_bus_id_0; + + test_efa_domain_open_ops_mr_query_common( + resource, + FI_EFA_MR_ATTR_VALIDITY_RECV_PCI_BUS_ID, + 0, + 0 /* ignored */, + 0 /* ignored */); +} + +/* run mr query for rdma read pci bus id */ +void test_efa_domain_open_ops_mr_query_rdma_read(struct efa_resource **state) +{ + struct efa_resource *resource = *state; + + efa_unit_test_resource_construct(resource, FI_EP_RDM); + + /* set rdma_read_pci_bus_id as 1 */ + g_efa_unit_test_mocks.efadv_query_mr = &efa_mock_efadv_query_mr_rdma_read_pci_bus_id_1; + + test_efa_domain_open_ops_mr_query_common( + resource, + FI_EFA_MR_ATTR_VALIDITY_RDMA_READ_PCI_BUS_ID, + 0 /* ignored */, + 1, + 0 /* ignored */); +} + +/* run mr query for rdma recv pci bus id */ +void test_efa_domain_open_ops_mr_query_rdma_recv(struct efa_resource **state) +{ + struct efa_resource *resource = *state; + + efa_unit_test_resource_construct(resource, FI_EP_RDM); + + /* set recv_pci_bus_id as 0 */ + g_efa_unit_test_mocks.efadv_query_mr = &efa_mock_efadv_query_mr_rdma_recv_pci_bus_id_2; + + test_efa_domain_open_ops_mr_query_common( + resource, + FI_EFA_MR_ATTR_VALIDITY_RDMA_RECV_PCI_BUS_ID, + 0 /* ignored */, + 0 /* ignored */, + 2); +} + +/* run mr query for both recv and rdma read's pci bus id */ +void test_efa_domain_open_ops_mr_query_recv_and_rdma_read(struct efa_resource **state) +{ + struct efa_resource *resource = *state; + + efa_unit_test_resource_construct(resource, FI_EP_RDM); + + /* set recv_pci_bus_id as 0 */ + g_efa_unit_test_mocks.efadv_query_mr = &efa_mock_efadv_query_mr_recv_and_rdma_read_pci_bus_id_0_1; + + test_efa_domain_open_ops_mr_query_common( + resource, + FI_EFA_MR_ATTR_VALIDITY_RECV_PCI_BUS_ID | FI_EFA_MR_ATTR_VALIDITY_RDMA_READ_PCI_BUS_ID, + 0, + 1, + 0 /* ignored */); +} + +#else + +void test_efa_domain_open_ops_mr_query_recv(struct efa_resource **state) +{ + skip(); +} + +/* run mr query for rdma read pci bus id */ +void test_efa_domain_open_ops_mr_query_rdma_read(struct efa_resource **state) +{ + skip(); +} + +/* run mr query for rdma recv pci bus id */ +void test_efa_domain_open_ops_mr_query_rdma_recv(struct efa_resource **state) +{ + skip(); +} + +/* run mr query for both recv and rdma read's pci bus id */ +void test_efa_domain_open_ops_mr_query_recv_and_rdma_read(struct efa_resource **state) +{ + skip(); +} + +#endif /* HAVE_EFADV_QUERY_MR */ diff --git a/prov/efa/test/efa_unit_test_mocks.c b/prov/efa/test/efa_unit_test_mocks.c index e4d4ec29ea1..2de156518b2 100644 --- a/prov/efa/test/efa_unit_test_mocks.c +++ b/prov/efa/test/efa_unit_test_mocks.c @@ -192,6 +192,9 @@ struct efa_unit_test_mocks g_efa_unit_test_mocks = { #endif .ofi_copy_from_hmem_iov = __real_ofi_copy_from_hmem_iov, .ibv_is_fork_initialized = __real_ibv_is_fork_initialized, +#if HAVE_EFADV_QUERY_MR + .efadv_query_mr = __real_efadv_query_mr, +#endif }; struct ibv_ah *__wrap_ibv_create_ah(struct ibv_pd *pd, struct ibv_ah_attr *attr) @@ -303,4 +306,46 @@ enum ibv_fork_status __wrap_ibv_is_fork_initialized(void) enum ibv_fork_status efa_mock_ibv_is_fork_initialized_return_mock(void) { return mock(); -} \ No newline at end of file +} + +#if HAVE_EFADV_QUERY_MR +int __wrap_efadv_query_mr(struct ibv_mr *ibv_mr, struct efadv_mr_attr *attr, uint32_t inlen) +{ + return g_efa_unit_test_mocks.efadv_query_mr(ibv_mr, attr, inlen); +} + +/* set recv_pci_bus_id as 0 */ +int efa_mock_efadv_query_mr_recv_pci_bus_id_0(struct ibv_mr *ibv_mr, struct efadv_mr_attr *attr, uint32_t inlen) +{ + attr->pci_bus_id_validity = EFADV_MR_ATTR_VALIDITY_RECV_PCI_BUS_ID; + attr->recv_pci_bus_id = 0; + return 0; +} + +/* set rdma_read_pci_bus_id id as 1 */ +int efa_mock_efadv_query_mr_rdma_read_pci_bus_id_1(struct ibv_mr *ibv_mr, struct efadv_mr_attr *attr, uint32_t inlen) +{ + attr->pci_bus_id_validity = EFADV_MR_ATTR_VALIDITY_RDMA_READ_PCI_BUS_ID; + attr->rdma_read_pci_bus_id = 1; + return 0; +} + +/* set rdma_recv_pci_bus_id id as 2 */ +int efa_mock_efadv_query_mr_rdma_recv_pci_bus_id_2(struct ibv_mr *ibv_mr, struct efadv_mr_attr *attr, uint32_t inlen) +{ + attr->pci_bus_id_validity = EFADV_MR_ATTR_VALIDITY_RDMA_RECV_PCI_BUS_ID; + attr->rdma_recv_pci_bus_id = 2; + return 0; +} + +/* set recv_pci_bus_id id as 0, rdma_read_pci_bus_id as 1 */ +int efa_mock_efadv_query_mr_recv_and_rdma_read_pci_bus_id_0_1(struct ibv_mr *ibv_mr, struct efadv_mr_attr *attr, uint32_t inlen) +{ + attr->pci_bus_id_validity = EFADV_MR_ATTR_VALIDITY_RECV_PCI_BUS_ID; + attr->recv_pci_bus_id = 0; + attr->pci_bus_id_validity |= EFADV_MR_ATTR_VALIDITY_RDMA_READ_PCI_BUS_ID; + attr->rdma_read_pci_bus_id = 1; + return 0; +} + +#endif /* HAVE_EFADV_QUERY_MR */ diff --git a/prov/efa/test/efa_unit_test_mocks.h b/prov/efa/test/efa_unit_test_mocks.h index d118a27ccb5..f8b0941855c 100644 --- a/prov/efa/test/efa_unit_test_mocks.h +++ b/prov/efa/test/efa_unit_test_mocks.h @@ -102,6 +102,10 @@ struct efa_unit_test_mocks size_t hmem_iov_count, uint64_t hmem_iov_offset); enum ibv_fork_status (*ibv_is_fork_initialized)(void); + +#if HAVE_EFADV_QUERY_MR + int (*efadv_query_mr)(struct ibv_mr *ibv_mr, struct efadv_mr_attr *attr, uint32_t inlen); +#endif }; struct ibv_cq_ex *efa_mock_create_cq_ex_return_null(struct ibv_context *context, struct ibv_cq_init_attr_ex *init_attr); @@ -134,6 +138,14 @@ void *__real_neuron_alloc(void **handle, size_t size); void *efa_mock_neuron_alloc_return_null(void **handle, size_t size); #endif +#if HAVE_EFADV_QUERY_MR +int __real_efadv_query_mr(struct ibv_mr *ibv_mr, struct efadv_mr_attr *attr, uint32_t inlen); +int efa_mock_efadv_query_mr_recv_pci_bus_id_0(struct ibv_mr *ibv_mr, struct efadv_mr_attr *attr, uint32_t inlen); +int efa_mock_efadv_query_mr_rdma_read_pci_bus_id_1(struct ibv_mr *ibv_mr, struct efadv_mr_attr *attr, uint32_t inlen); +int efa_mock_efadv_query_mr_rdma_recv_pci_bus_id_2(struct ibv_mr *ibv_mr, struct efadv_mr_attr *attr, uint32_t inlen); +int efa_mock_efadv_query_mr_recv_and_rdma_read_pci_bus_id_0_1(struct ibv_mr *ibv_mr, struct efadv_mr_attr *attr, uint32_t inlen); +#endif + enum ibv_fork_status __real_ibv_is_fork_initialized(void); enum ibv_fork_status efa_mock_ibv_is_fork_initialized_return_mock(void); diff --git a/prov/efa/test/efa_unit_tests.c b/prov/efa/test/efa_unit_tests.c index 97fadead2e6..89df34f1b43 100644 --- a/prov/efa/test/efa_unit_tests.c +++ b/prov/efa/test/efa_unit_tests.c @@ -141,6 +141,11 @@ int main(void) cmocka_unit_test_setup_teardown(test_efa_rdm_peer_get_runt_size_host_memory_normal, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown), cmocka_unit_test_setup_teardown(test_efa_rdm_peer_select_readbase_rtm_no_runt, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown), cmocka_unit_test_setup_teardown(test_efa_rdm_peer_select_readbase_rtm_do_runt, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown), + cmocka_unit_test_setup_teardown(test_efa_domain_open_ops_wrong_name, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown), + cmocka_unit_test_setup_teardown(test_efa_domain_open_ops_mr_query_recv, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown), + cmocka_unit_test_setup_teardown(test_efa_domain_open_ops_mr_query_rdma_read, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown), + cmocka_unit_test_setup_teardown(test_efa_domain_open_ops_mr_query_rdma_recv, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown), + cmocka_unit_test_setup_teardown(test_efa_domain_open_ops_mr_query_recv_and_rdma_read, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown), }; cmocka_set_message_output(CM_OUTPUT_XML); diff --git a/prov/efa/test/efa_unit_tests.h b/prov/efa/test/efa_unit_tests.h index c0f15f42729..c2ee3110867 100644 --- a/prov/efa/test/efa_unit_tests.h +++ b/prov/efa/test/efa_unit_tests.h @@ -150,5 +150,10 @@ void test_efa_rdm_peer_get_runt_size_host_memory_exceeding_total_len(); void test_efa_rdm_peer_get_runt_size_host_memory_normal(); void test_efa_rdm_peer_select_readbase_rtm_no_runt(); void test_efa_rdm_peer_select_readbase_rtm_do_runt(); +void test_efa_domain_open_ops_wrong_name(); +void test_efa_domain_open_ops_mr_query_recv(); +void test_efa_domain_open_ops_mr_query_rdma_read(); +void test_efa_domain_open_ops_mr_query_rdma_recv(); +void test_efa_domain_open_ops_mr_query_recv_and_rdma_read(); #endif