nvmf: Add an rdma_device struct
There is one of these per ibv_context. Change-Id: I660fed954c5a77fed9a6bda2321583ef05b30439 Signed-off-by: Ben Walker <benjamin.walker@intel.com> Reviewed-on: https://review.gerrithub.io/373837 Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com> Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
02e7c3ffbb
commit
958c68f175
109
lib/nvmf/rdma.c
109
lib/nvmf/rdma.c
@ -171,16 +171,24 @@ struct spdk_nvmf_rdma_poll_group {
|
||||
|
||||
SLIST_HEAD(, spdk_nvmf_rdma_buf) data_buf_pool;
|
||||
|
||||
struct ibv_context *verbs;
|
||||
struct spdk_nvmf_rdma_device *device;
|
||||
|
||||
uint8_t *buf;
|
||||
struct ibv_mr *buf_mr;
|
||||
};
|
||||
|
||||
/* Assuming rdma_cm uses just one protection domain per ibv_context. */
|
||||
struct spdk_nvmf_rdma_device {
|
||||
struct ibv_device_attr attr;
|
||||
struct ibv_context *context;
|
||||
|
||||
TAILQ_ENTRY(spdk_nvmf_rdma_device) link;
|
||||
};
|
||||
|
||||
struct spdk_nvmf_rdma_listen_addr {
|
||||
struct spdk_nvme_transport_id trid;
|
||||
struct rdma_cm_id *id;
|
||||
struct ibv_device_attr attr;
|
||||
struct spdk_nvmf_rdma_device *device;
|
||||
struct ibv_comp_channel *comp_channel;
|
||||
uint32_t ref;
|
||||
TAILQ_ENTRY(spdk_nvmf_rdma_listen_addr) link;
|
||||
@ -197,6 +205,7 @@ struct spdk_nvmf_rdma_transport {
|
||||
uint32_t max_io_size;
|
||||
uint32_t in_capsule_data_size;
|
||||
|
||||
TAILQ_HEAD(, spdk_nvmf_rdma_device) devices;
|
||||
TAILQ_HEAD(, spdk_nvmf_rdma_listen_addr) listen_addrs;
|
||||
};
|
||||
|
||||
@ -582,9 +591,9 @@ nvmf_rdma_connect(struct spdk_nvmf_transport *transport, struct rdma_cm_event *e
|
||||
/* Next check the local NIC's hardware limitations */
|
||||
SPDK_TRACELOG(SPDK_TRACE_RDMA,
|
||||
"Local NIC Max Send/Recv Queue Depth: %d Max Read/Write Queue Depth: %d\n",
|
||||
addr->attr.max_qp_wr, addr->attr.max_qp_rd_atom);
|
||||
max_queue_depth = spdk_min(max_queue_depth, addr->attr.max_qp_wr);
|
||||
max_rw_depth = spdk_min(max_rw_depth, addr->attr.max_qp_rd_atom);
|
||||
addr->device->attr.max_qp_wr, addr->device->attr.max_qp_rd_atom);
|
||||
max_queue_depth = spdk_min(max_queue_depth, addr->device->attr.max_qp_wr);
|
||||
max_rw_depth = spdk_min(max_rw_depth, addr->device->attr.max_qp_rd_atom);
|
||||
|
||||
/* Next check the remote NIC's hardware limitations */
|
||||
SPDK_TRACELOG(SPDK_TRACE_RDMA,
|
||||
@ -921,6 +930,9 @@ spdk_nvmf_rdma_create(struct spdk_nvmf_tgt *tgt)
|
||||
{
|
||||
int rc;
|
||||
struct spdk_nvmf_rdma_transport *rtransport;
|
||||
struct spdk_nvmf_rdma_device *device, *tmp;
|
||||
struct ibv_context **contexts;
|
||||
uint32_t i;
|
||||
|
||||
rtransport = calloc(1, sizeof(*rtransport));
|
||||
if (!rtransport) {
|
||||
@ -928,6 +940,7 @@ spdk_nvmf_rdma_create(struct spdk_nvmf_tgt *tgt)
|
||||
}
|
||||
|
||||
pthread_mutex_init(&rtransport->lock, NULL);
|
||||
TAILQ_INIT(&rtransport->devices);
|
||||
TAILQ_INIT(&rtransport->listen_addrs);
|
||||
|
||||
rtransport->transport.tgt = tgt;
|
||||
@ -953,13 +966,49 @@ spdk_nvmf_rdma_create(struct spdk_nvmf_tgt *tgt)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
contexts = rdma_get_devices(NULL);
|
||||
i = 0;
|
||||
rc = 0;
|
||||
while (contexts[i] != NULL) {
|
||||
device = calloc(1, sizeof(*device));
|
||||
if (!device) {
|
||||
SPDK_ERRLOG("Unable to allocate memory for RDMA devices.\n");
|
||||
rc = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
device->context = contexts[i];
|
||||
rc = ibv_query_device(device->context, &device->attr);
|
||||
if (rc < 0) {
|
||||
SPDK_ERRLOG("Failed to query RDMA device attributes.\n");
|
||||
free(device);
|
||||
break;
|
||||
|
||||
}
|
||||
TAILQ_INSERT_TAIL(&rtransport->devices, device, link);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
TAILQ_FOREACH_SAFE(device, &rtransport->devices, link, tmp) {
|
||||
TAILQ_REMOVE(&rtransport->devices, device, link);
|
||||
free(device);
|
||||
}
|
||||
rdma_destroy_event_channel(rtransport->event_channel);
|
||||
free(rtransport);
|
||||
rdma_free_devices(contexts);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rdma_free_devices(contexts);
|
||||
|
||||
return &rtransport->transport;
|
||||
}
|
||||
|
||||
static int
|
||||
spdk_nvmf_rdma_destroy(struct spdk_nvmf_transport *transport)
|
||||
{
|
||||
struct spdk_nvmf_rdma_transport *rtransport;
|
||||
struct spdk_nvmf_rdma_transport *rtransport;
|
||||
struct spdk_nvmf_rdma_device *device, *device_tmp;
|
||||
|
||||
rtransport = SPDK_CONTAINEROF(transport, struct spdk_nvmf_rdma_transport, transport);
|
||||
|
||||
@ -968,6 +1017,11 @@ spdk_nvmf_rdma_destroy(struct spdk_nvmf_transport *transport)
|
||||
rdma_destroy_event_channel(rtransport->event_channel);
|
||||
}
|
||||
|
||||
TAILQ_FOREACH_SAFE(device, &rtransport->devices, link, device_tmp) {
|
||||
TAILQ_REMOVE(&rtransport->devices, device, link);
|
||||
free(device);
|
||||
}
|
||||
|
||||
free(rtransport);
|
||||
|
||||
return 0;
|
||||
@ -978,6 +1032,7 @@ spdk_nvmf_rdma_listen(struct spdk_nvmf_transport *transport,
|
||||
const struct spdk_nvme_transport_id *trid)
|
||||
{
|
||||
struct spdk_nvmf_rdma_transport *rtransport;
|
||||
struct spdk_nvmf_rdma_device *device;
|
||||
struct spdk_nvmf_rdma_listen_addr *addr_tmp, *addr;
|
||||
struct sockaddr_in saddr;
|
||||
int rc;
|
||||
@ -1030,15 +1085,6 @@ spdk_nvmf_rdma_listen(struct spdk_nvmf_transport *transport,
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ibv_query_device(addr->id->verbs, &addr->attr);
|
||||
if (rc < 0) {
|
||||
SPDK_ERRLOG("Failed to query RDMA device attributes.\n");
|
||||
rdma_destroy_id(addr->id);
|
||||
free(addr);
|
||||
pthread_mutex_unlock(&rtransport->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
addr->comp_channel = ibv_create_comp_channel(addr->id->verbs);
|
||||
if (!addr->comp_channel) {
|
||||
SPDK_ERRLOG("Failed to create completion channel\n");
|
||||
@ -1070,6 +1116,22 @@ spdk_nvmf_rdma_listen(struct spdk_nvmf_transport *transport,
|
||||
return rc;
|
||||
}
|
||||
|
||||
TAILQ_FOREACH(device, &rtransport->devices, link) {
|
||||
if (device->context == addr->id->verbs) {
|
||||
addr->device = device;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!addr->device) {
|
||||
SPDK_ERRLOG("Accepted a connection with verbs %p, but unable to find a corresponding device.\n",
|
||||
addr->id->verbs);
|
||||
ibv_destroy_comp_channel(addr->comp_channel);
|
||||
rdma_destroy_id(addr->id);
|
||||
free(addr);
|
||||
pthread_mutex_unlock(&rtransport->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
SPDK_NOTICELOG("*** NVMf Target Listening on %s port %d ***\n",
|
||||
addr->trid.traddr, ntohs(rdma_get_src_port(addr->id)));
|
||||
|
||||
@ -1265,13 +1327,14 @@ spdk_nvmf_rdma_poll_group_add(struct spdk_nvmf_poll_group *group,
|
||||
struct spdk_nvmf_rdma_poll_group *rgroup;
|
||||
struct spdk_nvmf_rdma_qpair *rdma_qpair;
|
||||
struct spdk_nvmf_rdma_transport *rtransport;
|
||||
struct spdk_nvmf_rdma_device *device;
|
||||
|
||||
rgroup = SPDK_CONTAINEROF(group, struct spdk_nvmf_rdma_poll_group, group);
|
||||
rdma_qpair = SPDK_CONTAINEROF(qpair, struct spdk_nvmf_rdma_qpair, qpair);
|
||||
rtransport = SPDK_CONTAINEROF(group->transport, struct spdk_nvmf_rdma_transport, transport);
|
||||
|
||||
if (rgroup->verbs != NULL) {
|
||||
if (rgroup->verbs != rdma_qpair->cm_id->verbs) {
|
||||
if (rgroup->device != NULL) {
|
||||
if (rgroup->device->context != rdma_qpair->cm_id->verbs) {
|
||||
SPDK_ERRLOG("Attempted to add a qpair to a poll group with mismatched RDMA devices.\n");
|
||||
return -1;
|
||||
}
|
||||
@ -1281,7 +1344,17 @@ spdk_nvmf_rdma_poll_group_add(struct spdk_nvmf_poll_group *group,
|
||||
return 0;
|
||||
}
|
||||
|
||||
rgroup->verbs = rdma_qpair->cm_id->verbs;
|
||||
TAILQ_FOREACH(device, &rtransport->devices, link) {
|
||||
if (device->context == rdma_qpair->cm_id->verbs) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!device) {
|
||||
SPDK_ERRLOG("Attempted to add a qpair with an unknown device\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rgroup->device = device;
|
||||
rgroup->buf_mr = ibv_reg_mr(rdma_qpair->cm_id->pd, rgroup->buf,
|
||||
rtransport->max_queue_depth * rtransport->max_io_size,
|
||||
IBV_ACCESS_LOCAL_WRITE |
|
||||
|
Loading…
Reference in New Issue
Block a user