aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp
diff options
context:
space:
mode:
authorSagi Grimberg <sagig@mellanox.com>2015-03-29 08:52:04 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2015-04-08 02:27:49 -0400
commit4a579da2586bd3b79b025947ea24ede2bbfede62 (patch)
treef0850fe250d94d04e8ac95ccbba448732609a0f3 /drivers/infiniband/ulp
parent364189f0ada5478e4faf8a552d6071a650d757cd (diff)
iser-target: Fix possible deadlock in RDMA_CM connection error
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> Cc: <stable@vger.kernel.org> # v3.10+ Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/infiniband/ulp')
-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 4b8d518826b9..147029adb885 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -222,7 +222,7 @@ fail:
222static void 222static void
223isert_free_rx_descriptors(struct isert_conn *isert_conn) 223isert_free_rx_descriptors(struct isert_conn *isert_conn)
224{ 224{
225 struct ib_device *ib_dev = isert_conn->conn_cm_id->device; 225 struct ib_device *ib_dev = isert_conn->conn_device->ib_device;
226 struct iser_rx_desc *rx_desc; 226 struct iser_rx_desc *rx_desc;
227 int i; 227 int i;
228 228
@@ -719,8 +719,8 @@ out:
719static void 719static void
720isert_connect_release(struct isert_conn *isert_conn) 720isert_connect_release(struct isert_conn *isert_conn)
721{ 721{
722 struct ib_device *ib_dev = isert_conn->conn_cm_id->device;
723 struct isert_device *device = isert_conn->conn_device; 722 struct isert_device *device = isert_conn->conn_device;
723 struct ib_device *ib_dev = device->ib_device;
724 724
725 isert_dbg("conn %p\n", isert_conn); 725 isert_dbg("conn %p\n", isert_conn);
726 726
@@ -728,7 +728,8 @@ isert_connect_release(struct isert_conn *isert_conn)
728 isert_conn_free_fastreg_pool(isert_conn); 728 isert_conn_free_fastreg_pool(isert_conn);
729 729
730 isert_free_rx_descriptors(isert_conn); 730 isert_free_rx_descriptors(isert_conn);
731 rdma_destroy_id(isert_conn->conn_cm_id); 731 if (isert_conn->conn_cm_id)
732 rdma_destroy_id(isert_conn->conn_cm_id);
732 733
733 if (isert_conn->conn_qp) { 734 if (isert_conn->conn_qp) {
734 struct isert_comp *comp = isert_conn->conn_qp->recv_cq->cq_context; 735 struct isert_comp *comp = isert_conn->conn_qp->recv_cq->cq_context;
@@ -878,12 +879,15 @@ isert_disconnected_handler(struct rdma_cm_id *cma_id,
878 return 0; 879 return 0;
879} 880}
880 881
881static void 882static int
882isert_connect_error(struct rdma_cm_id *cma_id) 883isert_connect_error(struct rdma_cm_id *cma_id)
883{ 884{
884 struct isert_conn *isert_conn = cma_id->qp->qp_context; 885 struct isert_conn *isert_conn = cma_id->qp->qp_context;
885 886
887 isert_conn->conn_cm_id = NULL;
886 isert_put_conn(isert_conn); 888 isert_put_conn(isert_conn);
889
890 return -1;
887} 891}
888 892
889static int 893static int
@@ -912,7 +916,7 @@ isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
912 case RDMA_CM_EVENT_REJECTED: /* FALLTHRU */ 916 case RDMA_CM_EVENT_REJECTED: /* FALLTHRU */
913 case RDMA_CM_EVENT_UNREACHABLE: /* FALLTHRU */ 917 case RDMA_CM_EVENT_UNREACHABLE: /* FALLTHRU */
914 case RDMA_CM_EVENT_CONNECT_ERROR: 918 case RDMA_CM_EVENT_CONNECT_ERROR:
915 isert_connect_error(cma_id); 919 ret = isert_connect_error(cma_id);
916 break; 920 break;
917 default: 921 default:
918 isert_err("Unhandled RDMA CMA event: %d\n", event->event); 922 isert_err("Unhandled RDMA CMA event: %d\n", event->event);