aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSagi Grimberg <sagig@mellanox.com>2015-06-04 12:49:20 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2015-06-09 01:16:40 -0400
commit2f1b6b7d9a815f341b18dfd26a363f37d4d3c96a (patch)
tree123ecc3256ebcd5e2b893aa60df2287492a117a6
parent9253e667ab50fd4611a60e1cdd6a6e05a1d91cf1 (diff)
iser-target: release stale iser connections
When receiving a new iser connect request we serialize the pending requests by adding the newly created iser connection to the np accept list and let the login thread process the connect request one by one (np_accept_wait). In case we received a disconnect request before the iser_conn has begun processing (still linked in np_accept_list) we should detach it from the list and clean it up and not have the login thread process a stale connection. We do it only when the connection state is not already terminating (initiator driven disconnect) as this might lead us to access np_accept_mutex after the np was released in live shutdown scenarios. Signed-off-by: Sagi Grimberg <sagig@mellanox.com> Signed-off-by: Jenny Falkovich <jennyf@mellanox.com> Cc: stable@vger.kernel.org # 3.10+ Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r--drivers/infiniband/ulp/isert/ib_isert.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index 2c86bd1f1417..bad1f5d32227 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -65,6 +65,8 @@ static int
65isert_rdma_accept(struct isert_conn *isert_conn); 65isert_rdma_accept(struct isert_conn *isert_conn);
66struct rdma_cm_id *isert_setup_id(struct isert_np *isert_np); 66struct rdma_cm_id *isert_setup_id(struct isert_np *isert_np);
67 67
68static void isert_release_work(struct work_struct *work);
69
68static inline bool 70static inline bool
69isert_prot_cmd(struct isert_conn *conn, struct se_cmd *cmd) 71isert_prot_cmd(struct isert_conn *conn, struct se_cmd *cmd)
70{ 72{
@@ -648,6 +650,7 @@ isert_init_conn(struct isert_conn *isert_conn)
648 mutex_init(&isert_conn->mutex); 650 mutex_init(&isert_conn->mutex);
649 spin_lock_init(&isert_conn->pool_lock); 651 spin_lock_init(&isert_conn->pool_lock);
650 INIT_LIST_HEAD(&isert_conn->fr_pool); 652 INIT_LIST_HEAD(&isert_conn->fr_pool);
653 INIT_WORK(&isert_conn->release_work, isert_release_work);
651} 654}
652 655
653static void 656static void
@@ -925,6 +928,7 @@ isert_disconnected_handler(struct rdma_cm_id *cma_id,
925{ 928{
926 struct isert_np *isert_np = cma_id->context; 929 struct isert_np *isert_np = cma_id->context;
927 struct isert_conn *isert_conn; 930 struct isert_conn *isert_conn;
931 bool terminating = false;
928 932
929 if (isert_np->np_cm_id == cma_id) 933 if (isert_np->np_cm_id == cma_id)
930 return isert_np_cma_handler(cma_id->context, event); 934 return isert_np_cma_handler(cma_id->context, event);
@@ -932,12 +936,25 @@ isert_disconnected_handler(struct rdma_cm_id *cma_id,
932 isert_conn = cma_id->qp->qp_context; 936 isert_conn = cma_id->qp->qp_context;
933 937
934 mutex_lock(&isert_conn->mutex); 938 mutex_lock(&isert_conn->mutex);
939 terminating = (isert_conn->state == ISER_CONN_TERMINATING);
935 isert_conn_terminate(isert_conn); 940 isert_conn_terminate(isert_conn);
936 mutex_unlock(&isert_conn->mutex); 941 mutex_unlock(&isert_conn->mutex);
937 942
938 isert_info("conn %p completing wait\n", isert_conn); 943 isert_info("conn %p completing wait\n", isert_conn);
939 complete(&isert_conn->wait); 944 complete(&isert_conn->wait);
940 945
946 if (terminating)
947 goto out;
948
949 mutex_lock(&isert_np->np_accept_mutex);
950 if (!list_empty(&isert_conn->accept_node)) {
951 list_del_init(&isert_conn->accept_node);
952 isert_put_conn(isert_conn);
953 queue_work(isert_release_wq, &isert_conn->release_work);
954 }
955 mutex_unlock(&isert_np->np_accept_mutex);
956
957out:
941 return 0; 958 return 0;
942} 959}
943 960
@@ -3368,7 +3385,6 @@ static void isert_wait_conn(struct iscsi_conn *conn)
3368 isert_wait4flush(isert_conn); 3385 isert_wait4flush(isert_conn);
3369 isert_wait4logout(isert_conn); 3386 isert_wait4logout(isert_conn);
3370 3387
3371 INIT_WORK(&isert_conn->release_work, isert_release_work);
3372 queue_work(isert_release_wq, &isert_conn->release_work); 3388 queue_work(isert_release_wq, &isert_conn->release_work);
3373} 3389}
3374 3390