Target/iser: Fix hangs in connection teardown
In ungraceful teardowns isert close flows seem racy such that isert_wait_conn hangs as RDMA_CM_EVENT_DISCONNECTED never gets invoked (no one called rdma_disconnect). Both graceful and ungraceful teardowns will have rx flush errors (isert posts a batch once connection is established). Once all flush errors are consumed we invoke isert_wait_conn and it will be responsible for calling rdma_disconnect. This way it can be sure that rdma_disconnect was called and it won't wait forever. This patch also removes the logout_posted indicator. either the logout completion was consumed and no problem decrementing the post_send_buf_count, or it was consumed as a flush error. no point of keeping it for isert_wait_conn as there is no danger that isert_conn will be accidentally removed while it is running. (Drop unnecessary sleep_on_conn_wait_comp check in isert_cq_rx_comp_err - nab) Signed-off-by: Sagi Grimberg <sagig@mellanox.com> Cc: stable@vger.kernel.org # 3.10+ Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
parent
e346ab343f
commit
9d49f5e284
2 changed files with 10 additions and 22 deletions
|
@ -787,14 +787,10 @@ isert_disconnect_work(struct work_struct *work)
|
|||
isert_put_conn(isert_conn);
|
||||
return;
|
||||
}
|
||||
if (!isert_conn->logout_posted) {
|
||||
pr_debug("Calling rdma_disconnect for !logout_posted from"
|
||||
" isert_disconnect_work\n");
|
||||
rdma_disconnect(isert_conn->conn_cm_id);
|
||||
mutex_unlock(&isert_conn->conn_mutex);
|
||||
iscsit_cause_connection_reinstatement(isert_conn->conn, 0);
|
||||
goto wake_up;
|
||||
}
|
||||
|
||||
/* Send DREQ/DREP towards our initiator */
|
||||
rdma_disconnect(isert_conn->conn_cm_id);
|
||||
|
||||
mutex_unlock(&isert_conn->conn_mutex);
|
||||
|
||||
wake_up:
|
||||
|
@ -1822,11 +1818,8 @@ isert_do_control_comp(struct work_struct *work)
|
|||
break;
|
||||
case ISTATE_SEND_LOGOUTRSP:
|
||||
pr_debug("Calling iscsit_logout_post_handler >>>>>>>>>>>>>>\n");
|
||||
/*
|
||||
* Call atomic_dec(&isert_conn->post_send_buf_count)
|
||||
* from isert_wait_conn()
|
||||
*/
|
||||
isert_conn->logout_posted = true;
|
||||
|
||||
atomic_dec(&isert_conn->post_send_buf_count);
|
||||
iscsit_logout_post_handler(cmd, cmd->conn);
|
||||
break;
|
||||
case ISTATE_SEND_TEXTRSP:
|
||||
|
@ -2032,6 +2025,8 @@ isert_cq_rx_comp_err(struct isert_conn *isert_conn)
|
|||
isert_conn->state = ISER_CONN_DOWN;
|
||||
mutex_unlock(&isert_conn->conn_mutex);
|
||||
|
||||
iscsit_cause_connection_reinstatement(isert_conn->conn, 0);
|
||||
|
||||
complete(&isert_conn->conn_wait_comp_err);
|
||||
}
|
||||
|
||||
|
@ -3211,15 +3206,9 @@ static void isert_wait_conn(struct iscsi_conn *conn)
|
|||
struct isert_conn *isert_conn = conn->context;
|
||||
|
||||
pr_debug("isert_wait_conn: Starting \n");
|
||||
/*
|
||||
* Decrement post_send_buf_count for special case when called
|
||||
* from isert_do_control_comp() -> iscsit_logout_post_handler()
|
||||
*/
|
||||
mutex_lock(&isert_conn->conn_mutex);
|
||||
if (isert_conn->logout_posted)
|
||||
atomic_dec(&isert_conn->post_send_buf_count);
|
||||
|
||||
if (isert_conn->conn_cm_id && isert_conn->state != ISER_CONN_DOWN) {
|
||||
mutex_lock(&isert_conn->conn_mutex);
|
||||
if (isert_conn->conn_cm_id) {
|
||||
pr_debug("Calling rdma_disconnect from isert_wait_conn\n");
|
||||
rdma_disconnect(isert_conn->conn_cm_id);
|
||||
}
|
||||
|
|
|
@ -116,7 +116,6 @@ struct isert_device;
|
|||
|
||||
struct isert_conn {
|
||||
enum iser_conn_state state;
|
||||
bool logout_posted;
|
||||
int post_recv_buf_count;
|
||||
atomic_t post_send_buf_count;
|
||||
u32 responder_resources;
|
||||
|
|
Loading…
Reference in a new issue