|
@@ -65,6 +65,8 @@ static int
|
|
|
isert_rdma_accept(struct isert_conn *isert_conn);
|
|
isert_rdma_accept(struct isert_conn *isert_conn);
|
|
|
struct rdma_cm_id *isert_setup_id(struct isert_np *isert_np);
|
|
struct rdma_cm_id *isert_setup_id(struct isert_np *isert_np);
|
|
|
|
|
|
|
|
|
|
+static void isert_release_work(struct work_struct *work);
|
|
|
|
|
+
|
|
|
static inline bool
|
|
static inline bool
|
|
|
isert_prot_cmd(struct isert_conn *conn, struct se_cmd *cmd)
|
|
isert_prot_cmd(struct isert_conn *conn, struct se_cmd *cmd)
|
|
|
{
|
|
{
|
|
@@ -648,6 +650,7 @@ isert_init_conn(struct isert_conn *isert_conn)
|
|
|
mutex_init(&isert_conn->mutex);
|
|
mutex_init(&isert_conn->mutex);
|
|
|
spin_lock_init(&isert_conn->pool_lock);
|
|
spin_lock_init(&isert_conn->pool_lock);
|
|
|
INIT_LIST_HEAD(&isert_conn->fr_pool);
|
|
INIT_LIST_HEAD(&isert_conn->fr_pool);
|
|
|
|
|
+ INIT_WORK(&isert_conn->release_work, isert_release_work);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
static void
|
|
@@ -925,6 +928,7 @@ isert_disconnected_handler(struct rdma_cm_id *cma_id,
|
|
|
{
|
|
{
|
|
|
struct isert_np *isert_np = cma_id->context;
|
|
struct isert_np *isert_np = cma_id->context;
|
|
|
struct isert_conn *isert_conn;
|
|
struct isert_conn *isert_conn;
|
|
|
|
|
+ bool terminating = false;
|
|
|
|
|
|
|
|
if (isert_np->np_cm_id == cma_id)
|
|
if (isert_np->np_cm_id == cma_id)
|
|
|
return isert_np_cma_handler(cma_id->context, event);
|
|
return isert_np_cma_handler(cma_id->context, event);
|
|
@@ -932,12 +936,25 @@ isert_disconnected_handler(struct rdma_cm_id *cma_id,
|
|
|
isert_conn = cma_id->qp->qp_context;
|
|
isert_conn = cma_id->qp->qp_context;
|
|
|
|
|
|
|
|
mutex_lock(&isert_conn->mutex);
|
|
mutex_lock(&isert_conn->mutex);
|
|
|
|
|
+ terminating = (isert_conn->state == ISER_CONN_TERMINATING);
|
|
|
isert_conn_terminate(isert_conn);
|
|
isert_conn_terminate(isert_conn);
|
|
|
mutex_unlock(&isert_conn->mutex);
|
|
mutex_unlock(&isert_conn->mutex);
|
|
|
|
|
|
|
|
isert_info("conn %p completing wait\n", isert_conn);
|
|
isert_info("conn %p completing wait\n", isert_conn);
|
|
|
complete(&isert_conn->wait);
|
|
complete(&isert_conn->wait);
|
|
|
|
|
|
|
|
|
|
+ if (terminating)
|
|
|
|
|
+ goto out;
|
|
|
|
|
+
|
|
|
|
|
+ mutex_lock(&isert_np->np_accept_mutex);
|
|
|
|
|
+ if (!list_empty(&isert_conn->accept_node)) {
|
|
|
|
|
+ list_del_init(&isert_conn->accept_node);
|
|
|
|
|
+ isert_put_conn(isert_conn);
|
|
|
|
|
+ queue_work(isert_release_wq, &isert_conn->release_work);
|
|
|
|
|
+ }
|
|
|
|
|
+ mutex_unlock(&isert_np->np_accept_mutex);
|
|
|
|
|
+
|
|
|
|
|
+out:
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -3368,7 +3385,6 @@ static void isert_wait_conn(struct iscsi_conn *conn)
|
|
|
isert_wait4flush(isert_conn);
|
|
isert_wait4flush(isert_conn);
|
|
|
isert_wait4logout(isert_conn);
|
|
isert_wait4logout(isert_conn);
|
|
|
|
|
|
|
|
- INIT_WORK(&isert_conn->release_work, isert_release_work);
|
|
|
|
|
queue_work(isert_release_wq, &isert_conn->release_work);
|
|
queue_work(isert_release_wq, &isert_conn->release_work);
|
|
|
}
|
|
}
|
|
|
|
|
|