Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9d49f5e2 authored by Sagi Grimberg's avatar Sagi Grimberg Committed by Nicholas Bellinger
Browse files

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: default avatarSagi Grimberg <sagig@mellanox.com>
Cc: stable@vger.kernel.org # 3.10+
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent e346ab34
Loading
Loading
Loading
Loading
+10 −21
Original line number Diff line number Diff line
@@ -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");

	/* Send DREQ/DREP towards our initiator */
	rdma_disconnect(isert_conn->conn_cm_id);
		mutex_unlock(&isert_conn->conn_mutex);
		iscsit_cause_connection_reinstatement(isert_conn->conn, 0);
		goto wake_up;
	}

	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);
	}
+0 −1
Original line number Diff line number Diff line
@@ -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;