IB/iser: Protect iser state machine with a mutex
The iser connection state lookups and transitions are not fully protected. Some transitions are protected with a spinlock, and in some cases the state is accessed unprotected due to specific assumptions of the flow. Introduce a new mutex to protect the connection state access. We use a mutex since we need to also include a scheduling operations executed under the state lock. Each state transition/condition and its corresponding action will be protected with the state mutex. The rdma_cm events handler acquires the mutex when handling connection events. Since iser connection state can transition to DOWN concurrently during connection establishment, we bailout from addr/route resolution events when the state is not PENDING. This addresses a scenario where ep_poll retries expire during CMA connection establishment. In this case ep_disconnect is invoked while CMA events keep coming (address/route resolution, connected, etc...). Signed-off-by: Ariel Nahum <arieln@mellanox.com> Signed-off-by: Sagi Grimberg <sagig@mellanox.com> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
This commit is contained in:

committed by
Roland Dreier

parent
f1a8bf0983
commit
504130c039
@@ -632,10 +632,13 @@ iscsi_iser_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)
|
||||
msecs_to_jiffies(timeout_ms));
|
||||
|
||||
/* if conn establishment failed, return error code to iscsi */
|
||||
if (!rc &&
|
||||
(ib_conn->state == ISER_CONN_TERMINATING ||
|
||||
ib_conn->state == ISER_CONN_DOWN))
|
||||
rc = -1;
|
||||
if (rc == 0) {
|
||||
mutex_lock(&ib_conn->state_mutex);
|
||||
if (ib_conn->state == ISER_CONN_TERMINATING ||
|
||||
ib_conn->state == ISER_CONN_DOWN)
|
||||
rc = -1;
|
||||
mutex_unlock(&ib_conn->state_mutex);
|
||||
}
|
||||
|
||||
iser_info("ib conn %p rc = %d\n", ib_conn, rc);
|
||||
|
||||
@@ -654,6 +657,7 @@ iscsi_iser_ep_disconnect(struct iscsi_endpoint *ep)
|
||||
|
||||
ib_conn = ep->dd_data;
|
||||
iser_info("ep %p ib conn %p state %d\n", ep, ib_conn, ib_conn->state);
|
||||
mutex_lock(&ib_conn->state_mutex);
|
||||
iser_conn_terminate(ib_conn);
|
||||
|
||||
/*
|
||||
@@ -664,7 +668,10 @@ iscsi_iser_ep_disconnect(struct iscsi_endpoint *ep)
|
||||
if (ib_conn->iscsi_conn) {
|
||||
INIT_WORK(&ib_conn->release_work, iser_release_work);
|
||||
queue_work(release_wq, &ib_conn->release_work);
|
||||
mutex_unlock(&ib_conn->state_mutex);
|
||||
} else {
|
||||
ib_conn->state = ISER_CONN_DOWN;
|
||||
mutex_unlock(&ib_conn->state_mutex);
|
||||
iser_conn_release(ib_conn);
|
||||
}
|
||||
iscsi_destroy_endpoint(ep);
|
||||
|
Reference in New Issue
Block a user