diff options
author | Sagi Grimberg <sagig@mellanox.com> | 2014-12-07 06:12:01 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-12-13 02:32:33 -0500 |
commit | 991bb7640d7e0971c360b6166cbca84a7f502312 (patch) | |
tree | 15a2c654a625cdfb9e843b65303cd9a209b702e1 /drivers/infiniband/ulp | |
parent | c7e160ee092059d3d1ddc24397c9d7a4dbe8186a (diff) |
iser-target: Fix logout sequence
We don't want to wait for conn_logout_comp from isert_comp_wq
context as this blocks further completions from being processed.
Instead we wait for it conditionally (if logout response was
actually posted) in wait_conn. This wait should normally happen
immediately as it occurs after we consumed all the completions
(including flush errors) and conn_logout_comp should have been
completed.
Signed-off-by: Sagi Grimberg <sagig@mellanox.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/infiniband/ulp')
-rw-r--r-- | drivers/infiniband/ulp/isert/ib_isert.c | 24 | ||||
-rw-r--r-- | drivers/infiniband/ulp/isert/ib_isert.h | 1 |
2 files changed, 17 insertions, 8 deletions
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index fc4641e5fd1e..108548437c9f 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c | |||
@@ -1426,10 +1426,6 @@ isert_rx_opcode(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc, | |||
1426 | break; | 1426 | break; |
1427 | 1427 | ||
1428 | ret = iscsit_handle_logout_cmd(conn, cmd, (unsigned char *)hdr); | 1428 | ret = iscsit_handle_logout_cmd(conn, cmd, (unsigned char *)hdr); |
1429 | if (ret > 0) | ||
1430 | wait_for_completion_timeout(&conn->conn_logout_comp, | ||
1431 | SECONDS_FOR_LOGOUT_COMP * | ||
1432 | HZ); | ||
1433 | break; | 1429 | break; |
1434 | case ISCSI_OP_TEXT: | 1430 | case ISCSI_OP_TEXT: |
1435 | cmd = isert_allocate_cmd(conn); | 1431 | cmd = isert_allocate_cmd(conn); |
@@ -2922,15 +2918,14 @@ isert_immediate_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state) | |||
2922 | static int | 2918 | static int |
2923 | isert_response_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state) | 2919 | isert_response_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state) |
2924 | { | 2920 | { |
2921 | struct isert_conn *isert_conn = conn->context; | ||
2925 | int ret; | 2922 | int ret; |
2926 | 2923 | ||
2927 | switch (state) { | 2924 | switch (state) { |
2928 | case ISTATE_SEND_LOGOUTRSP: | 2925 | case ISTATE_SEND_LOGOUTRSP: |
2929 | ret = isert_put_logout_rsp(cmd, conn); | 2926 | ret = isert_put_logout_rsp(cmd, conn); |
2930 | if (!ret) { | 2927 | if (!ret) |
2931 | pr_debug("Returning iSER Logout -EAGAIN\n"); | 2928 | isert_conn->logout_posted = true; |
2932 | ret = -EAGAIN; | ||
2933 | } | ||
2934 | break; | 2929 | break; |
2935 | case ISTATE_SEND_NOPIN: | 2930 | case ISTATE_SEND_NOPIN: |
2936 | ret = isert_put_nopin(cmd, conn, true); | 2931 | ret = isert_put_nopin(cmd, conn, true); |
@@ -3236,6 +3231,18 @@ static void isert_release_work(struct work_struct *work) | |||
3236 | } | 3231 | } |
3237 | 3232 | ||
3238 | static void | 3233 | static void |
3234 | isert_wait4logout(struct isert_conn *isert_conn) | ||
3235 | { | ||
3236 | struct iscsi_conn *conn = isert_conn->conn; | ||
3237 | |||
3238 | if (isert_conn->logout_posted) { | ||
3239 | pr_info("conn %p wait for conn_logout_comp\n", isert_conn); | ||
3240 | wait_for_completion_timeout(&conn->conn_logout_comp, | ||
3241 | SECONDS_FOR_LOGOUT_COMP * HZ); | ||
3242 | } | ||
3243 | } | ||
3244 | |||
3245 | static void | ||
3239 | isert_wait4cmds(struct iscsi_conn *conn) | 3246 | isert_wait4cmds(struct iscsi_conn *conn) |
3240 | { | 3247 | { |
3241 | if (conn->sess) { | 3248 | if (conn->sess) { |
@@ -3280,6 +3287,7 @@ static void isert_wait_conn(struct iscsi_conn *conn) | |||
3280 | 3287 | ||
3281 | isert_wait4cmds(conn); | 3288 | isert_wait4cmds(conn); |
3282 | isert_wait4flush(isert_conn); | 3289 | isert_wait4flush(isert_conn); |
3290 | isert_wait4logout(isert_conn); | ||
3283 | 3291 | ||
3284 | INIT_WORK(&isert_conn->release_work, isert_release_work); | 3292 | INIT_WORK(&isert_conn->release_work, isert_release_work); |
3285 | queue_work(isert_release_wq, &isert_conn->release_work); | 3293 | queue_work(isert_release_wq, &isert_conn->release_work); |
diff --git a/drivers/infiniband/ulp/isert/ib_isert.h b/drivers/infiniband/ulp/isert/ib_isert.h index 2a0721f1f5df..e89f384efc22 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.h +++ b/drivers/infiniband/ulp/isert/ib_isert.h | |||
@@ -156,6 +156,7 @@ struct isert_conn { | |||
156 | spinlock_t conn_lock; | 156 | spinlock_t conn_lock; |
157 | struct work_struct release_work; | 157 | struct work_struct release_work; |
158 | struct ib_recv_wr beacon; | 158 | struct ib_recv_wr beacon; |
159 | bool logout_posted; | ||
159 | }; | 160 | }; |
160 | 161 | ||
161 | #define ISERT_MAX_CQ 64 | 162 | #define ISERT_MAX_CQ 64 |