rdma: Add functions to work with SRQ

Add 4 new functions to create/delete SRQ, queue and flush
recv Work Requests.

Change-Id: I55401d22724cf1ce24f2cca588f2bd1384cdbcd0
Signed-off-by: Alexey Marchuk <alexeymar@mellanox.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6289
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Alexey Marchuk 2020-12-03 13:47:34 +03:00 committed by Tomasz Zawadzki
parent 4f2a837238
commit 27d8fd9f4c
3 changed files with 142 additions and 1 deletions

View File

@ -55,6 +55,11 @@ struct spdk_rdma_send_wr_list {
struct ibv_send_wr *last; struct ibv_send_wr *last;
}; };
struct spdk_rdma_recv_wr_list {
struct ibv_recv_wr *first;
struct ibv_recv_wr *last;
};
struct spdk_rdma_qp { struct spdk_rdma_qp {
struct ibv_qp *qp; struct ibv_qp *qp;
struct rdma_cm_id *cm_id; struct rdma_cm_id *cm_id;
@ -77,6 +82,50 @@ struct spdk_rdma_memory_translation {
union spdk_rdma_mr mr_or_key; union spdk_rdma_mr mr_or_key;
uint8_t translation_type; uint8_t translation_type;
}; };
struct spdk_rdma_srq_init_attr {
struct ibv_pd *pd;
struct ibv_srq_init_attr srq_init_attr;
};
struct spdk_rdma_srq {
struct ibv_srq *srq;
struct spdk_rdma_recv_wr_list recv_wrs;
};
/**
* Create RDMA SRQ
*
* \param init_attr Pointer to SRQ init attr
* \return pointer to srq on success or NULL on failure. errno is updated in failure case.
*/
struct spdk_rdma_srq *spdk_rdma_srq_create(struct spdk_rdma_srq_init_attr *init_attr);
/**
* Destroy RDMA SRQ
*
* \param rdma_srq Pointer to SRQ
* \return 0 on succes, errno on failure
*/
int spdk_rdma_srq_destroy(struct spdk_rdma_srq *rdma_srq);
/**
* Append the given recv wr structure to the SRQ's outstanding recv list.
* This function accepts either a single Work Request or the first WR in a linked list.
*
* \param rdma_srq Pointer to SRQ
* \param first pointer to the first Work Request
* \return true if there were no outstanding WRs before, false otherwise
*/
bool spdk_rdma_srq_queue_recv_wrs(struct spdk_rdma_srq *rdma_srq, struct ibv_recv_wr *first);
/**
* Submit all queued receive Work Request
*
* \param rdma_srq Pointer to SRQ
* \param bad_wr Stores a pointer to the first failed WR if this function return nonzero value
* \return 0 on succes, errno on failure
*/
int spdk_rdma_srq_flush_recv_wrs(struct spdk_rdma_srq *rdma_srq, struct ibv_recv_wr **bad_wr);
/** /**
* Create RDMA provider specific qpair * Create RDMA provider specific qpair

View File

@ -2,7 +2,7 @@
* BSD LICENSE * BSD LICENSE
* *
* Copyright (c) Intel Corporation. All rights reserved. * Copyright (c) Intel Corporation. All rights reserved.
* Copyright (c) Mellanox Technologies LTD. All rights reserved. * Copyright (c) 2020, 2021 Mellanox Technologies LTD. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -31,8 +31,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <rdma/rdma_cma.h>
#include "spdk/log.h" #include "spdk/log.h"
#include "spdk/env.h" #include "spdk/env.h"
#include "spdk/string.h"
#include "spdk/likely.h" #include "spdk/likely.h"
#include "spdk_internal/rdma.h" #include "spdk_internal/rdma.h"
@ -217,3 +220,88 @@ spdk_rdma_get_translation(struct spdk_rdma_mem_map *map, void *address,
return 0; return 0;
} }
struct spdk_rdma_srq *
spdk_rdma_srq_create(struct spdk_rdma_srq_init_attr *init_attr)
{
assert(init_attr);
assert(init_attr->pd);
struct spdk_rdma_srq *rdma_srq = calloc(1, sizeof(*rdma_srq));
if (!rdma_srq) {
SPDK_ERRLOG("Can't allocate memory for SRQ handle\n");
return NULL;
}
rdma_srq->srq = ibv_create_srq(init_attr->pd, &init_attr->srq_init_attr);
if (!rdma_srq->srq) {
SPDK_ERRLOG("Unable to create SRQ, errno %d (%s)\n", errno, spdk_strerror(errno));
free(rdma_srq);
return NULL;
}
return rdma_srq;
}
int
spdk_rdma_srq_destroy(struct spdk_rdma_srq *rdma_srq)
{
int rc;
if (!rdma_srq) {
return 0;
}
assert(rdma_srq->srq);
if (rdma_srq->recv_wrs.first != NULL) {
SPDK_WARNLOG("Destroying RDMA SRQ with queued recv WRs\n");
}
rc = ibv_destroy_srq(rdma_srq->srq);
if (rc) {
SPDK_ERRLOG("SRQ destroy failed with %d\n", rc);
}
free(rdma_srq);
return rc;
}
bool
spdk_rdma_srq_queue_recv_wrs(struct spdk_rdma_srq *rdma_srq, struct ibv_recv_wr *first)
{
struct ibv_recv_wr *last;
last = first;
while (last->next != NULL) {
last = last->next;
}
if (rdma_srq->recv_wrs.first == NULL) {
rdma_srq->recv_wrs.first = first;
rdma_srq->recv_wrs.last = last;
return true;
} else {
rdma_srq->recv_wrs.last->next = first;
rdma_srq->recv_wrs.last = last;
return false;
}
}
int
spdk_rdma_srq_flush_recv_wrs(struct spdk_rdma_srq *rdma_srq, struct ibv_recv_wr **bad_wr)
{
int rc;
if (spdk_unlikely(rdma_srq->recv_wrs.first == NULL)) {
return 0;
}
rc = ibv_post_srq_recv(rdma_srq->srq, rdma_srq->recv_wrs.first, bad_wr);
rdma_srq->recv_wrs.first = NULL;
return rc;
}

View File

@ -2,6 +2,10 @@
global: global:
# Public functions # Public functions
spdk_rdma_srq_create;
spdk_rdma_srq_destroy;
spdk_rdma_srq_queue_recv_wrs;
spdk_rdma_srq_flush_recv_wrs;
spdk_rdma_qp_create; spdk_rdma_qp_create;
spdk_rdma_qp_accept; spdk_rdma_qp_accept;
spdk_rdma_qp_complete_connect; spdk_rdma_qp_complete_connect;