aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSagi Grimberg <sagig@mellanox.com>2015-03-29 15:52:04 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-08-03 09:29:46 -0700
commit394adc1d4905b143a3f4f6a859a2253becc1101e (patch)
tree534babd386dd666d5d8ab1820c3c6daa9b430d00
parent49b028d31aedc00f179c883e87f1b4f2cf55923b (diff)
iser-target: Fix possible deadlock in RDMA_CM connection error
commit 4a579da2586bd3b79b025947ea24ede2bbfede62 upstream. Before we reach to connection established we may get an error event. In this case the core won't teardown this connection (never established it), so we take care of freeing it ourselves. Signed-off-by: Sagi Grimberg <sagig@mellanox.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/infiniband/ulp/isert/ib_isert.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index 8019e642d2f5..4c2ed0b7d140 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -202,7 +202,7 @@ fail:
static void
isert_free_rx_descriptors(struct isert_conn *isert_conn)
{
- struct ib_device *ib_dev = isert_conn->conn_cm_id->device;
+ struct ib_device *ib_dev = isert_conn->conn_device->ib_device;
struct iser_rx_desc *rx_desc;
int i;
@@ -527,14 +527,15 @@ out:
static void
isert_connect_release(struct isert_conn *isert_conn)
{
- struct ib_device *ib_dev = isert_conn->conn_cm_id->device;
struct isert_device *device = isert_conn->conn_device;
int cq_index;
+ struct ib_device *ib_dev = device->ib_device;
pr_debug("Entering isert_connect_release(): >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
isert_free_rx_descriptors(isert_conn);
- rdma_destroy_id(isert_conn->conn_cm_id);
+ if (isert_conn->conn_cm_id)
+ rdma_destroy_id(isert_conn->conn_cm_id);
if (isert_conn->conn_qp) {
cq_index = ((struct isert_cq_desc *)
@@ -689,12 +690,15 @@ isert_disconnected_handler(struct rdma_cm_id *cma_id,
return 0;
}
-static void
+static int
isert_connect_error(struct rdma_cm_id *cma_id)
{
struct isert_conn *isert_conn = cma_id->qp->qp_context;
+ isert_conn->conn_cm_id = NULL;
isert_put_conn(isert_conn);
+
+ return -1;
}
static int
@@ -724,7 +728,7 @@ isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
case RDMA_CM_EVENT_REJECTED: /* FALLTHRU */
case RDMA_CM_EVENT_UNREACHABLE: /* FALLTHRU */
case RDMA_CM_EVENT_CONNECT_ERROR:
- isert_connect_error(cma_id);
+ ret = isert_connect_error(cma_id);
break;
default:
pr_err("Unhandled RDMA CMA event: %d\n", event->event);