Skip to content

Commit

Permalink
prov/efa: Require FI_MR_LOCAL for zero-copy receive
Browse files Browse the repository at this point in the history
Zero-copy receive requires application to register the local buffer
for transfer, otherwise libfabric will need to do a copy or
registration internally, which doesn't comply with the zero-copy nature.
Therefore, FI_MR_LOCAL is required for libfabric to turn on zcpy recv.

Signed-off-by: Jessie Yang <[email protected]>
  • Loading branch information
jiaxiyan authored and shijin-aws committed Aug 27, 2024
1 parent fb361d4 commit 5e31d84
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 4 deletions.
7 changes: 7 additions & 0 deletions prov/efa/src/rdm/efa_rdm_ep_fiops.c
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,13 @@ void efa_rdm_ep_set_use_zcpy_rx(struct efa_rdm_ep *ep)
goto out;
}

/* FI_MR_LOCAL is not set, turn off zcpy recv */
if (!ep->base_ep.domain->mr_local) {
EFA_INFO(FI_LOG_EP_CTRL, "FI_MR_LOCAL mode bit is not set, zero-copy receive protocol will be disabled\n");
ep->use_zcpy_rx = false;
goto out;
}

if (ep->shm_ep) {
EFA_INFO(FI_LOG_EP_CTRL, "Libfabric SHM is not turned off, zero-copy receive protocol will be disabled\n");
ep->use_zcpy_rx = false;
Expand Down
22 changes: 18 additions & 4 deletions prov/efa/src/rdm/efa_rdm_ep_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ struct efa_rdm_ope *efa_rdm_ep_alloc_rxe(struct efa_rdm_ep *ep, fi_addr_t addr,
*/
int efa_rdm_ep_post_user_recv_buf(struct efa_rdm_ep *ep, struct efa_rdm_ope *rxe, size_t flags)
{
struct efa_rdm_pke *pkt_entry;
struct efa_rdm_pke *pkt_entry = NULL;
size_t rx_iov_offset = 0;
int err, rx_iov_index = 0;

Expand All @@ -225,29 +225,43 @@ int efa_rdm_ep_post_user_recv_buf(struct efa_rdm_ep *ep, struct efa_rdm_ope *rxe
err = ofi_iov_locate(rxe->iov, rxe->iov_count, ep->msg_prefix_size, &rx_iov_index, &rx_iov_offset);
if (OFI_UNLIKELY(err)) {
EFA_WARN(FI_LOG_CQ, "ofi_iov_locate failure: %s (%d)\n", fi_strerror(-err), -err);
return err;
goto err_free;
}

assert(rx_iov_index < rxe->iov_count);
assert(rx_iov_offset < rxe->iov[rx_iov_index].iov_len);
assert(ep->base_ep.domain->mr_local);

if (!rxe->desc[rx_iov_index]) {
err = -FI_EINVAL;
EFA_WARN(FI_LOG_EP_CTRL,
"No valid desc is provided, not complied with FI_MR_LOCAL: %s (%d)\n",
fi_strerror(-err), -err);
goto err_free;
}

pkt_entry->payload = (char *) rxe->iov[rx_iov_index].iov_base + rx_iov_offset;
pkt_entry->payload_mr = rxe->desc[rx_iov_index];
pkt_entry->payload_size = ofi_total_iov_len(&rxe->iov[rx_iov_index], rxe->iov_count - rx_iov_index) - rx_iov_offset;

err = efa_rdm_pke_recvv(&pkt_entry, 1);
if (OFI_UNLIKELY(err)) {
efa_rdm_pke_release_rx(pkt_entry);
EFA_WARN(FI_LOG_EP_CTRL,
"failed to post user supplied buffer %d (%s)\n", -err,
fi_strerror(-err));
return err;
goto err_free;
}

#if ENABLE_DEBUG
dlist_insert_tail(&pkt_entry->dbg_entry, &ep->rx_posted_buf_list);
#endif
ep->user_rx_pkts_posted++;
return 0;

err_free:
if (pkt_entry)
efa_rdm_pke_release_rx(pkt_entry);
return err;
}


Expand Down
16 changes: 16 additions & 0 deletions prov/efa/test/efa_unit_test_ep.c
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,22 @@ void test_efa_rdm_ep_user_p2p_not_supported_zcpy_rx_happy(struct efa_resource **
test_efa_rdm_ep_use_zcpy_rx_impl(resource, false, false, false);
}

/**
* @brief Verify zcpy_rx is disabled if FI_MR_LOCAL is not set
*/
void test_efa_rdm_ep_user_zcpy_rx_unhappy_due_to_no_mr_local(struct efa_resource **state)
{
struct efa_resource *resource = *state;

resource->hints = efa_unit_test_alloc_hints(FI_EP_RDM);
assert_non_null(resource->hints);

resource->hints->caps = FI_MSG;
resource->hints->domain_attr->mr_mode &= ~FI_MR_LOCAL;

test_efa_rdm_ep_use_zcpy_rx_impl(resource, false, true, false);
}

void test_efa_rdm_ep_close_discard_posted_recv(struct efa_resource **state)
{
struct efa_resource *resource = *state;
Expand Down
1 change: 1 addition & 0 deletions prov/efa/test/efa_unit_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ int main(void)
cmocka_unit_test_setup_teardown(test_efa_rdm_ep_user_disable_p2p_zcpy_rx_happy, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown),
cmocka_unit_test_setup_teardown(test_efa_rdm_ep_user_zcpy_rx_unhappy_due_to_sas, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown),
cmocka_unit_test_setup_teardown(test_efa_rdm_ep_user_p2p_not_supported_zcpy_rx_happy, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown),
cmocka_unit_test_setup_teardown(test_efa_rdm_ep_user_zcpy_rx_unhappy_due_to_no_mr_local, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown),
cmocka_unit_test_setup_teardown(test_efa_rdm_ep_close_discard_posted_recv, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown),
cmocka_unit_test_setup_teardown(test_efa_rdm_ep_zcpy_recv_cancel, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown),
cmocka_unit_test_setup_teardown(test_efa_rdm_ep_post_handshake_error_handling_pke_exhaustion, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown),
Expand Down
1 change: 1 addition & 0 deletions prov/efa/test/efa_unit_tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ void test_efa_rdm_ep_user_zcpy_rx_disabled();
void test_efa_rdm_ep_user_disable_p2p_zcpy_rx_happy();
void test_efa_rdm_ep_user_zcpy_rx_unhappy_due_to_sas();
void test_efa_rdm_ep_user_p2p_not_supported_zcpy_rx_happy();
void test_efa_rdm_ep_user_zcpy_rx_unhappy_due_to_no_mr_local();
void test_efa_rdm_ep_close_discard_posted_recv();
void test_efa_rdm_ep_zcpy_recv_cancel();
void test_efa_rdm_ep_post_handshake_error_handling_pke_exhaustion();
Expand Down

0 comments on commit 5e31d84

Please sign in to comment.