nvmf,rdma: Solve nvmf host reconnect issue.
Kernel nvmf host always tries to connect nvmf target when we does not issue nvme disconnect command. Thus, we face rdma_create_qp issue, the reason is that we call rdma_listen too early, and the event retrieved from rdma_cm_get_event is too late. And this patch solves this issue. Change-Id: I153a8aea7420a86a236301dad9bd54af97f60865 Signed-off-by: Ziye Yang <ziye.yang@intel.com>
This commit is contained in:
parent
5a3b89a679
commit
97e15fedb8
@ -152,6 +152,7 @@ struct spdk_nvmf_rdma_listen_addr {
|
||||
struct ibv_device_attr attr;
|
||||
struct ibv_comp_channel *comp_channel;
|
||||
uint32_t ref;
|
||||
bool is_listened;
|
||||
TAILQ_ENTRY(spdk_nvmf_rdma_listen_addr) link;
|
||||
};
|
||||
|
||||
@ -1062,17 +1063,49 @@ spdk_nvmf_rdma_listen_remove(struct spdk_nvmf_listen_addr *listen_addr)
|
||||
static int
|
||||
spdk_nvmf_rdma_poll(struct spdk_nvmf_conn *conn);
|
||||
|
||||
static void
|
||||
spdk_nvmf_rdma_addr_listen_init(struct spdk_nvmf_rdma_listen_addr *addr)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = rdma_listen(addr->id, 10); /* 10 = backlog */
|
||||
if (rc < 0) {
|
||||
SPDK_ERRLOG("rdma_listen() failed\n");
|
||||
addr->ref--;
|
||||
assert(addr->ref == 0);
|
||||
TAILQ_REMOVE(&g_rdma.listen_addrs, addr, link);
|
||||
ibv_destroy_comp_channel(addr->comp_channel);
|
||||
rdma_destroy_id(addr->id);
|
||||
spdk_nvmf_rdma_listen_addr_free(addr);
|
||||
return;
|
||||
}
|
||||
|
||||
addr->is_listened = true;
|
||||
|
||||
SPDK_NOTICELOG("*** NVMf Target Listening on %s port %d ***\n",
|
||||
addr->traddr, ntohs(rdma_get_src_port(addr->id)));
|
||||
}
|
||||
|
||||
static void
|
||||
spdk_nvmf_rdma_acceptor_poll(void)
|
||||
{
|
||||
struct rdma_cm_event *event;
|
||||
int rc;
|
||||
struct spdk_nvmf_rdma_conn *rdma_conn, *tmp;
|
||||
struct spdk_nvmf_rdma_listen_addr *addr = NULL, *addr_tmp;
|
||||
|
||||
if (g_rdma.event_channel == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&g_rdma.lock);
|
||||
TAILQ_FOREACH_SAFE(addr, &g_rdma.listen_addrs, link, addr_tmp) {
|
||||
if (!addr->is_listened) {
|
||||
spdk_nvmf_rdma_addr_listen_init(addr);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&g_rdma.lock);
|
||||
|
||||
/* Process pending connections for incoming capsules. The only capsule
|
||||
* this should ever find is a CONNECT request. */
|
||||
TAILQ_FOREACH_SAFE(rdma_conn, &g_pending_conns, link, tmp) {
|
||||
@ -1187,15 +1220,6 @@ spdk_nvmf_rdma_listen(struct spdk_nvmf_listen_addr *listen_addr)
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = rdma_listen(addr->id, 10); /* 10 = backlog */
|
||||
if (rc < 0) {
|
||||
SPDK_ERRLOG("rdma_listen() failed\n");
|
||||
rdma_destroy_id(addr->id);
|
||||
spdk_nvmf_rdma_listen_addr_free(addr);
|
||||
pthread_mutex_unlock(&g_rdma.lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = ibv_query_device(addr->id->verbs, &addr->attr);
|
||||
if (rc < 0) {
|
||||
SPDK_ERRLOG("Failed to query RDMA device attributes.\n");
|
||||
@ -1226,12 +1250,11 @@ spdk_nvmf_rdma_listen(struct spdk_nvmf_listen_addr *listen_addr)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
addr->ref = 1;
|
||||
TAILQ_INSERT_TAIL(&g_rdma.listen_addrs, addr, link);
|
||||
pthread_mutex_unlock(&g_rdma.lock);
|
||||
|
||||
SPDK_NOTICELOG("*** NVMf Target Listening on %s port %d ***\n",
|
||||
addr->traddr, ntohs(rdma_get_src_port(addr->id)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user