isert_init_conn(struct isert_conn *isert_conn)
{
isert_conn->state = ISER_CONN_INIT;
- INIT_LIST_HEAD(&isert_conn->accept_node);
+ INIT_LIST_HEAD(&isert_conn->node);
init_completion(&isert_conn->login_comp);
init_completion(&isert_conn->login_req_comp);
init_completion(&isert_conn->wait);
ret = isert_rdma_post_recvl(isert_conn);
if (ret)
goto out_conn_dev;
- /*
- * Obtain the second reference now before isert_rdma_accept() to
- * ensure that any initiator generated REJECT CM event that occurs
- * asynchronously won't drop the last reference until the error path
- * in iscsi_target_login_sess_out() does it's ->iscsit_free_conn() ->
- * isert_free_conn() -> isert_put_conn() -> kref_put().
- */
- if (!kref_get_unless_zero(&isert_conn->kref)) {
- isert_warn("conn %p connect_release is running\n", isert_conn);
- goto out_conn_dev;
- }
ret = isert_rdma_accept(isert_conn);
if (ret)
goto out_conn_dev;
mutex_lock(&isert_np->mutex);
- list_add_tail(&isert_conn->accept_node, &isert_np->accept_list);
+ list_add_tail(&isert_conn->node, &isert_np->accepted);
mutex_unlock(&isert_np->mutex);
- isert_info("np %p: Allow accept_np to continue\n", np);
- up(&isert_np->sem);
return 0;
out_conn_dev:
isert_connected_handler(struct rdma_cm_id *cma_id)
{
struct isert_conn *isert_conn = cma_id->qp->qp_context;
+ struct isert_np *isert_np = cma_id->context;
isert_info("conn %p\n", isert_conn);
mutex_lock(&isert_conn->mutex);
- if (isert_conn->state != ISER_CONN_FULL_FEATURE)
- isert_conn->state = ISER_CONN_UP;
+ isert_conn->state = ISER_CONN_UP;
+ kref_get(&isert_conn->kref);
mutex_unlock(&isert_conn->mutex);
+
+ mutex_lock(&isert_np->mutex);
+ list_move_tail(&isert_conn->node, &isert_np->pending);
+ mutex_unlock(&isert_np->mutex);
+
+ isert_info("np %p: Allow accept_np to continue\n", isert_np);
+ up(&isert_np->sem);
}
static void
goto out;
mutex_lock(&isert_np->mutex);
- if (!list_empty(&isert_conn->accept_node)) {
- list_del_init(&isert_conn->accept_node);
+ if (!list_empty(&isert_conn->node)) {
+ list_del_init(&isert_conn->node);
isert_put_conn(isert_conn);
queue_work(isert_release_wq, &isert_conn->release_work);
}
{
struct isert_conn *isert_conn = cma_id->qp->qp_context;
+ list_del_init(&isert_conn->node);
isert_conn->cm_id = NULL;
isert_put_conn(isert_conn);
}
sema_init(&isert_np->sem, 0);
mutex_init(&isert_np->mutex);
- INIT_LIST_HEAD(&isert_np->accept_list);
+ INIT_LIST_HEAD(&isert_np->accepted);
+ INIT_LIST_HEAD(&isert_np->pending);
isert_np->np = np;
/*
spin_unlock_bh(&np->np_thread_lock);
mutex_lock(&isert_np->mutex);
- if (list_empty(&isert_np->accept_list)) {
+ if (list_empty(&isert_np->pending)) {
mutex_unlock(&isert_np->mutex);
goto accept_wait;
}
- isert_conn = list_first_entry(&isert_np->accept_list,
- struct isert_conn, accept_node);
- list_del_init(&isert_conn->accept_node);
+ isert_conn = list_first_entry(&isert_np->pending,
+ struct isert_conn, node);
+ list_del_init(&isert_conn->node);
mutex_unlock(&isert_np->mutex);
conn->context = isert_conn;
* that at this point we don't have hanging connections that
* completed RDMA establishment but didn't start iscsi login
* process. So work-around this by cleaning up what ever piled
- * up in accept_list.
+ * up in accepted and pending lists.
*/
mutex_lock(&isert_np->mutex);
- if (!list_empty(&isert_np->accept_list)) {
- isert_info("Still have isert connections, cleaning up...\n");
+ if (!list_empty(&isert_np->pending)) {
+ isert_info("Still have isert pending connections\n");
+ list_for_each_entry_safe(isert_conn, n,
+ &isert_np->pending,
+ node) {
+ isert_info("cleaning isert_conn %p state (%d)\n",
+ isert_conn, isert_conn->state);
+ isert_connect_release(isert_conn);
+ }
+ }
+
+ if (!list_empty(&isert_np->accepted)) {
+ isert_info("Still have isert accepted connections\n");
list_for_each_entry_safe(isert_conn, n,
- &isert_np->accept_list,
- accept_node) {
+ &isert_np->accepted,
+ node) {
isert_info("cleaning isert_conn %p state (%d)\n",
isert_conn, isert_conn->state);
isert_connect_release(isert_conn);