diff options
author | Sagi Grimberg <sagig@mellanox.com> | 2014-05-19 10:44:23 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-05-19 17:38:49 -0400 |
commit | 9d49f5e284e700576f3b65f1e28dea8539da6661 (patch) | |
tree | b780028276b9f5261b23505d3c16197a4964a2d4 | |
parent | e346ab343f4f58c12a96725c7b13df9cc2ad56f6 (diff) |
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>
-rw-r--r-- | drivers/infiniband/ulp/isert/ib_isert.c | 31 | ||||
-rw-r--r-- | drivers/infiniband/ulp/isert/ib_isert.h | 1 |
2 files changed, 10 insertions, 22 deletions
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index 7676bcb7105a..ef73a38bcb6b 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c | |||
@@ -787,14 +787,10 @@ isert_disconnect_work(struct work_struct *work) | |||
787 | isert_put_conn(isert_conn); | 787 | isert_put_conn(isert_conn); |
788 | return; | 788 | return; |
789 | } | 789 | } |
790 | if (!isert_conn->logout_posted) { | 790 | |
791 | pr_debug("Calling rdma_disconnect for !logout_posted from" | 791 | /* Send DREQ/DREP towards our initiator */ |
792 | " isert_disconnect_work\n"); | 792 | rdma_disconnect(isert_conn->conn_cm_id); |
793 | rdma_disconnect(isert_conn->conn_cm_id); | 793 | |
794 | mutex_unlock(&isert_conn->conn_mutex); | ||
795 | iscsit_cause_connection_reinstatement(isert_conn->conn, 0); | ||
796 | goto wake_up; | ||
797 | } | ||
798 | mutex_unlock(&isert_conn->conn_mutex); | 794 | mutex_unlock(&isert_conn->conn_mutex); |
799 | 795 | ||
800 | wake_up: | 796 | wake_up: |
@@ -1822,11 +1818,8 @@ isert_do_control_comp(struct work_struct *work) | |||
1822 | break; | 1818 | break; |
1823 | case ISTATE_SEND_LOGOUTRSP: | 1819 | case ISTATE_SEND_LOGOUTRSP: |
1824 | pr_debug("Calling iscsit_logout_post_handler >>>>>>>>>>>>>>\n"); | 1820 | pr_debug("Calling iscsit_logout_post_handler >>>>>>>>>>>>>>\n"); |
1825 | /* | 1821 | |
1826 | * Call atomic_dec(&isert_conn->post_send_buf_count) | 1822 | atomic_dec(&isert_conn->post_send_buf_count); |
1827 | * from isert_wait_conn() | ||
1828 | */ | ||
1829 | isert_conn->logout_posted = true; | ||
1830 | iscsit_logout_post_handler(cmd, cmd->conn); | 1823 | iscsit_logout_post_handler(cmd, cmd->conn); |
1831 | break; | 1824 | break; |
1832 | case ISTATE_SEND_TEXTRSP: | 1825 | case ISTATE_SEND_TEXTRSP: |
@@ -2032,6 +2025,8 @@ isert_cq_rx_comp_err(struct isert_conn *isert_conn) | |||
2032 | isert_conn->state = ISER_CONN_DOWN; | 2025 | isert_conn->state = ISER_CONN_DOWN; |
2033 | mutex_unlock(&isert_conn->conn_mutex); | 2026 | mutex_unlock(&isert_conn->conn_mutex); |
2034 | 2027 | ||
2028 | iscsit_cause_connection_reinstatement(isert_conn->conn, 0); | ||
2029 | |||
2035 | complete(&isert_conn->conn_wait_comp_err); | 2030 | complete(&isert_conn->conn_wait_comp_err); |
2036 | } | 2031 | } |
2037 | 2032 | ||
@@ -3211,15 +3206,9 @@ static void isert_wait_conn(struct iscsi_conn *conn) | |||
3211 | struct isert_conn *isert_conn = conn->context; | 3206 | struct isert_conn *isert_conn = conn->context; |
3212 | 3207 | ||
3213 | pr_debug("isert_wait_conn: Starting \n"); | 3208 | pr_debug("isert_wait_conn: Starting \n"); |
3214 | /* | ||
3215 | * Decrement post_send_buf_count for special case when called | ||
3216 | * from isert_do_control_comp() -> iscsit_logout_post_handler() | ||
3217 | */ | ||
3218 | mutex_lock(&isert_conn->conn_mutex); | ||
3219 | if (isert_conn->logout_posted) | ||
3220 | atomic_dec(&isert_conn->post_send_buf_count); | ||
3221 | 3209 | ||
3222 | if (isert_conn->conn_cm_id && isert_conn->state != ISER_CONN_DOWN) { | 3210 | mutex_lock(&isert_conn->conn_mutex); |
3211 | if (isert_conn->conn_cm_id) { | ||
3223 | pr_debug("Calling rdma_disconnect from isert_wait_conn\n"); | 3212 | pr_debug("Calling rdma_disconnect from isert_wait_conn\n"); |
3224 | rdma_disconnect(isert_conn->conn_cm_id); | 3213 | rdma_disconnect(isert_conn->conn_cm_id); |
3225 | } | 3214 | } |
diff --git a/drivers/infiniband/ulp/isert/ib_isert.h b/drivers/infiniband/ulp/isert/ib_isert.h index da6612e68000..a2e926452f76 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.h +++ b/drivers/infiniband/ulp/isert/ib_isert.h | |||
@@ -116,7 +116,6 @@ struct isert_device; | |||
116 | 116 | ||
117 | struct isert_conn { | 117 | struct isert_conn { |
118 | enum iser_conn_state state; | 118 | enum iser_conn_state state; |
119 | bool logout_posted; | ||
120 | int post_recv_buf_count; | 119 | int post_recv_buf_count; |
121 | atomic_t post_send_buf_count; | 120 | atomic_t post_send_buf_count; |
122 | u32 responder_resources; | 121 | u32 responder_resources; |