diff --git a/src/mr.c b/src/mr.c index 5345aa1e57..1da178af60 100644 --- a/src/mr.c +++ b/src/mr.c @@ -58,46 +58,6 @@ struct rpma_mr_remote { int usage; /* usage of the memory region */ }; -/* helper functions */ - -/* - * usage_to_access -- convert usage to access - * - * Note: APM type of flush requires the same access as RPMA_MR_USAGE_READ_SRC - */ -static int -usage_to_access(int usage) -{ - int access = 0; - - if (usage & (RPMA_MR_USAGE_READ_SRC |\ - RPMA_MR_USAGE_FLUSH_TYPE_VISIBILITY |\ - RPMA_MR_USAGE_FLUSH_TYPE_PERSISTENT)) - access |= IBV_ACCESS_REMOTE_READ; - - if (usage & RPMA_MR_USAGE_READ_DST) - access |= IBV_ACCESS_LOCAL_WRITE; - - if (usage & RPMA_MR_USAGE_WRITE_SRC) - access |= IBV_ACCESS_LOCAL_WRITE; - - if (usage & RPMA_MR_USAGE_WRITE_DST) - /* - * If IBV_ACCESS_REMOTE_WRITE is set, then - * IBV_ACCESS_LOCAL_WRITE must be set too. - */ - access |= IBV_ACCESS_REMOTE_WRITE | IBV_ACCESS_LOCAL_WRITE; - - if (usage & RPMA_MR_USAGE_RECV) - access |= IBV_ACCESS_LOCAL_WRITE; - - /* - * There is no IBV_ACCESS_* value to be set for RPMA_MR_USAGE_SEND. - */ - - return access; -} - /* internal librpma API */ /* @@ -324,6 +284,8 @@ int rpma_mr_reg(struct rpma_peer *peer, void *ptr, size_t size, int usage, struct rpma_mr_local **mr_ptr) { + int ret; + if (peer == NULL || ptr == NULL || size == 0 || mr_ptr == NULL) return RPMA_E_INVAL; @@ -336,9 +298,7 @@ rpma_mr_reg(struct rpma_peer *peer, void *ptr, size_t size, int usage, return RPMA_E_NOMEM; struct ibv_mr *ibv_mr; - int ret = rpma_peer_mr_reg(peer, &ibv_mr, ptr, size, - usage_to_access(usage)); - if (ret) { + if ((ret = rpma_peer_mr_reg(peer, &ibv_mr, ptr, size, usage))) { free(mr); return ret; } diff --git a/src/peer.c b/src/peer.c index 7ca4b4aafd..3f4a6486d8 100644 --- a/src/peer.c +++ b/src/peer.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -/* Copyright 2020, Intel Corporation */ +/* Copyright 2020-2021, Intel Corporation */ /* * peer.c -- librpma peer-related implementations @@ -29,6 +29,54 @@ struct rpma_peer { int is_odp_supported; /* is On-Demand Paging supported */ }; +/* + * usage_to_access -- convert usage to access + * + * Note: APM type of flush requires the same access as RPMA_MR_USAGE_READ_SRC + */ +static int +rpma_peer_usage_to_access(struct rpma_peer *peer, int usage) +{ + enum ibv_transport_type type = + peer->pd->context->device->transport_type; + int access = 0; + + if (usage & (RPMA_MR_USAGE_READ_SRC |\ + RPMA_MR_USAGE_FLUSH_TYPE_VISIBILITY |\ + RPMA_MR_USAGE_FLUSH_TYPE_PERSISTENT)) + access |= IBV_ACCESS_REMOTE_READ; + + if (usage & RPMA_MR_USAGE_READ_DST) { + access |= IBV_ACCESS_LOCAL_WRITE; + + /* + * iWARP implements the READ operation as the WRITE operation + * in the opposite direction. + */ + if (type == IBV_TRANSPORT_IWARP) + access |= IBV_ACCESS_REMOTE_WRITE; + } + + if (usage & RPMA_MR_USAGE_WRITE_SRC) + access |= IBV_ACCESS_LOCAL_WRITE; + + if (usage & RPMA_MR_USAGE_WRITE_DST) + /* + * If IBV_ACCESS_REMOTE_WRITE is set, then + * IBV_ACCESS_LOCAL_WRITE must be set too. + */ + access |= IBV_ACCESS_REMOTE_WRITE | IBV_ACCESS_LOCAL_WRITE; + + if (usage & RPMA_MR_USAGE_RECV) + access |= IBV_ACCESS_LOCAL_WRITE; + + /* + * There is no IBV_ACCESS_* value to be set for RPMA_MR_USAGE_SEND. + */ + + return access; +} + /* internal librpma API */ /* @@ -108,8 +156,10 @@ rpma_peer_create_qp(struct rpma_peer *peer, struct rdma_cm_id *id, */ int rpma_peer_mr_reg(struct rpma_peer *peer, struct ibv_mr **ibv_mr_ptr, - void *addr, size_t length, int access) + void *addr, size_t length, int usage) { + int access = rpma_peer_usage_to_access(peer, usage); + *ibv_mr_ptr = ibv_reg_mr(peer->pd, addr, length, RPMA_IBV_ACCESS(access)); if (*ibv_mr_ptr != NULL) diff --git a/src/peer.h b/src/peer.h index 50fb7d6c07..9273546a6a 100644 --- a/src/peer.h +++ b/src/peer.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause */ -/* Copyright 2020, Intel Corporation */ +/* Copyright 2020-2021, Intel Corporation */ /* * peer.h -- librpma peer-related internal definitions @@ -33,6 +33,6 @@ int rpma_peer_create_qp(struct rpma_peer *peer, struct rdma_cm_id *id, * - RPMA_E_PROVIDER - registering the memory region failed */ int rpma_peer_mr_reg(struct rpma_peer *peer, struct ibv_mr **ibv_mr_ptr, - void *addr, size_t length, int access); + void *addr, size_t length, int usage); #endif /* LIBRPMA_PEER_H */ diff --git a/tests/integration/common/mocks.c b/tests/integration/common/mocks.c index 89557ae8fd..41e7fa97d5 100644 --- a/tests/integration/common/mocks.c +++ b/tests/integration/common/mocks.c @@ -23,6 +23,10 @@ struct ibv_mr Ibv_mr_flush; /* mock IBV MR FLUSH */ struct rdma_cm_id Cm_id; /* mock CM ID */ struct ibv_qp Ibv_qp; /* mock IBV QP */ +struct ibv_device Ibv_device = {{0}, 0, IBV_TRANSPORT_IB}; +struct ibv_context Ibv_context = {&Ibv_device}; +struct ibv_pd Ibv_pd = {&Ibv_context, 0}; + #ifdef ON_DEMAND_PAGING_SUPPORTED /* predefined IBV On-demand Paging caps */ struct ibv_odp_caps Ibv_odp_capable_caps = { diff --git a/tests/integration/common/mocks.h b/tests/integration/common/mocks.h index 7fac29ad85..ba4f8ed44c 100644 --- a/tests/integration/common/mocks.h +++ b/tests/integration/common/mocks.h @@ -12,15 +12,15 @@ #define MOCK_PORT "1234" #define MOCK_MR (&Ibv_mr) #define MOCK_MR_RAW (&Ibv_mr_raw) -#define MOCK_MR_FLUSH (&Ibv_mr_flush) +#define MOCK_MR_FLUSH (&Ibv_mr_flush) #define MOCK_RAW_SIZE 8 /* memory region size */ #define MOCK_COMP_CHANNEL (&Ibv_comp_channel) +#define MOCK_IBV_PD (&Ibv_pd) #define MOCK_CQ (&Ibv_cq) #define MOCK_VERBS (&Verbs_context.context) #define MOCK_EVCH ((struct rdma_event_channel *)0xE4C4) #define MOCK_SRC_ADDR ((struct sockaddr *)0x0ADD) #define MOCK_DST_ADDR ((struct sockaddr *)0x0ADE) -#define MOCK_IBV_PD ((struct ibv_pd *)0x00D0) #define MOCK_QP ((struct ibv_qp *)0xD56A) #define MOCK_OP_CONTEXT ((void *)0xC417) #define MOCK_RKEY ((uint32_t)0x10111213) @@ -48,12 +48,15 @@ struct common_data { extern struct verbs_context Verbs_context; /* mock IBV completion channel */ extern struct ibv_comp_channel Ibv_comp_channel; +extern struct ibv_context Ibv_context; /* mock IBV context */ +extern struct ibv_device Ibv_device; /* mock IBV device */ extern struct ibv_cq Ibv_cq; /* mock IBV CQ */ extern struct ibv_mr Ibv_mr; /* mock IBV MR */ extern struct ibv_mr Ibv_mr_raw; /* mock IBV MR RAW */ extern struct ibv_mr Ibv_mr_flush; /* mock IBV MR FLUSH */ -extern struct rdma_cm_id Cm_id; /* mock CM ID */ +extern struct rdma_cm_id Cm_id; /* mock CM ID */ extern struct ibv_qp Ibv_qp; /* mock IBV QP */ +extern struct ibv_pd Ibv_pd; /* mock IBV PD */ /* predefined IBV On-demand Paging caps */ extern struct ibv_odp_caps Ibv_odp_capable_caps; diff --git a/tests/unit/common/mocks-ibverbs.c b/tests/unit/common/mocks-ibverbs.c index 31dc07f596..c7c9bf164d 100644 --- a/tests/unit/common/mocks-ibverbs.c +++ b/tests/unit/common/mocks-ibverbs.c @@ -15,6 +15,9 @@ /* mocked IBV entities */ struct verbs_context Verbs_context; struct ibv_comp_channel Ibv_comp_channel; +struct ibv_device Ibv_device = {{0}, 0, IBV_TRANSPORT_IWARP}; +struct ibv_context Ibv_context = {&Ibv_device}; +struct ibv_pd Ibv_pd = {&Ibv_context, 0}; struct ibv_cq Ibv_cq; struct ibv_qp Ibv_qp; struct ibv_mr Ibv_mr; diff --git a/tests/unit/common/mocks-ibverbs.h b/tests/unit/common/mocks-ibverbs.h index 11aeb994a5..c8706b0df9 100644 --- a/tests/unit/common/mocks-ibverbs.h +++ b/tests/unit/common/mocks-ibverbs.h @@ -13,6 +13,9 @@ /* mocked IBV entities */ extern struct verbs_context Verbs_context; extern struct ibv_comp_channel Ibv_comp_channel; +extern struct ibv_context Ibv_context; +extern struct ibv_device Ibv_device; +extern struct ibv_pd Ibv_pd; extern struct ibv_cq Ibv_cq; extern struct ibv_qp Ibv_qp; extern struct ibv_mr Ibv_mr; @@ -21,7 +24,7 @@ extern struct ibv_mr Ibv_mr; #define MOCK_VERBS (&Verbs_context.context) #define MOCK_COMP_CHANNEL (struct ibv_comp_channel *)&Ibv_comp_channel #define MOCK_IBV_CQ (struct ibv_cq *)&Ibv_cq -#define MOCK_IBV_PD (struct ibv_pd *)0x00D0 +#define MOCK_IBV_PD (struct ibv_pd *)&Ibv_pd #define MOCK_QP (struct ibv_qp *)&Ibv_qp #define MOCK_MR (struct ibv_mr *)&Ibv_mr diff --git a/tests/unit/common/mocks-rpma-peer.c b/tests/unit/common/mocks-rpma-peer.c index f1e8332f46..3076cdc4b7 100644 --- a/tests/unit/common/mocks-rpma-peer.c +++ b/tests/unit/common/mocks-rpma-peer.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -/* Copyright 2020, Intel Corporation */ +/* Copyright 2020-2021, Intel Corporation */ /* * mocks-rpma-peer.c -- librpma peer.c module mocks @@ -38,7 +38,7 @@ rpma_peer_create_qp(struct rpma_peer *peer, struct rdma_cm_id *id, */ int rpma_peer_mr_reg(struct rpma_peer *peer, struct ibv_mr **ibv_mr_ptr, - void *addr, size_t length, int access) + void *addr, size_t length, int usage) { /* * rpma_peer_mr_reg() and malloc() may be called in any order. @@ -51,7 +51,7 @@ rpma_peer_mr_reg(struct rpma_peer *peer, struct ibv_mr **ibv_mr_ptr, assert_ptr_equal(peer, MOCK_PEER); assert_ptr_equal(addr, MOCK_PTR); assert_int_equal(length, MOCK_SIZE); - assert_int_equal(access, args->access); + assert_int_equal(usage, args->usage); *ibv_mr_ptr = args->mr; if (*ibv_mr_ptr == NULL) { diff --git a/tests/unit/peer/peer-common.h b/tests/unit/peer/peer-common.h index 65d80fef1b..5e2257127c 100644 --- a/tests/unit/peer/peer-common.h +++ b/tests/unit/peer/peer-common.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause */ -/* Copyright 2020, Intel Corporation */ +/* Copyright 2020-2021, Intel Corporation */ /* * peer-common.h -- the header of the common part of the peer unit test @@ -19,7 +19,24 @@ * is added dynamically during the fall-back to using On-Demand Paging * registration type. */ -#define MOCK_ACCESS (unsigned)7 +#define MOCK_ACCESS (unsigned)(\ + IBV_ACCESS_LOCAL_WRITE |\ + IBV_ACCESS_REMOTE_WRITE |\ + IBV_ACCESS_REMOTE_READ) + +/* + * The test usage value is a combination of all possible + * RPMA_MR_USAGE_* values. + */ +#define MOCK_USAGE (unsigned)(\ + RPMA_MR_USAGE_READ_SRC |\ + RPMA_MR_USAGE_READ_DST |\ + RPMA_MR_USAGE_WRITE_SRC |\ + RPMA_MR_USAGE_WRITE_DST |\ + RPMA_MR_USAGE_FLUSH_TYPE_VISIBILITY |\ + RPMA_MR_USAGE_FLUSH_TYPE_PERSISTENT |\ + RPMA_MR_USAGE_SEND |\ + RPMA_MR_USAGE_RECV) extern int OdpCapable; extern int OdpIncapable; diff --git a/tests/unit/peer/peer-mr_reg.c b/tests/unit/peer/peer-mr_reg.c index 91105bf4c9..48ace67697 100644 --- a/tests/unit/peer/peer-mr_reg.c +++ b/tests/unit/peer/peer-mr_reg.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -/* Copyright 2020, Intel Corporation */ +/* Copyright 2020-2021, Intel Corporation */ /* * peer-mr_reg.c -- a peer unit test @@ -37,7 +37,7 @@ mr_reg__fail_ENOMEM(void **peer_ptr) /* run test */ struct ibv_mr *mr = NULL; int ret = rpma_peer_mr_reg(peer, &mr, MOCK_ADDR, - MOCK_LEN, MOCK_ACCESS); + MOCK_LEN, MOCK_USAGE); /* verify the results */ assert_int_equal(ret, RPMA_E_PROVIDER); @@ -63,7 +63,7 @@ mr_reg__fail_EOPNOTSUPP_no_odp(void **peer_ptr) /* run test */ struct ibv_mr *mr = NULL; int ret = rpma_peer_mr_reg(peer, &mr, MOCK_ADDR, - MOCK_LEN, MOCK_ACCESS); + MOCK_LEN, MOCK_USAGE); /* verify the results */ assert_int_equal(ret, RPMA_E_PROVIDER); @@ -99,7 +99,7 @@ mr_reg__fail_EOPNOTSUPP_EAGAIN(void **peer_ptr) /* run test */ struct ibv_mr *mr = NULL; int ret = rpma_peer_mr_reg(peer, &mr, MOCK_ADDR, - MOCK_LEN, MOCK_ACCESS); + MOCK_LEN, MOCK_USAGE); /* verify the results */ assert_int_equal(ret, RPMA_E_PROVIDER); @@ -124,7 +124,7 @@ mr_reg__success(void **peer_ptr) /* run test */ struct ibv_mr *mr; int ret = rpma_peer_mr_reg(peer, &mr, MOCK_ADDR, - MOCK_LEN, MOCK_ACCESS); + MOCK_LEN, MOCK_USAGE); /* verify the results */ assert_int_equal(ret, MOCK_OK); @@ -158,7 +158,7 @@ mr_reg__success_odp(void **peer_ptr) /* run test */ struct ibv_mr *mr; int ret = rpma_peer_mr_reg(peer, &mr, MOCK_ADDR, - MOCK_LEN, MOCK_ACCESS); + MOCK_LEN, MOCK_USAGE); /* verify the results */ #ifdef ON_DEMAND_PAGING_SUPPORTED