From 991bb7640d7e0971c360b6166cbca84a7f502312 Mon Sep 17 00:00:00 2001 From: Sagi Grimberg Date: Sun, 7 Dec 2014 13:12:01 +0200 Subject: [PATCH] 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 Signed-off-by: Nicholas Bellinger --- drivers/infiniband/ulp/isert/ib_isert.c | 24 ++++++++++++++++-------- 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 fc4641e..1085484 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, break; ret = iscsit_handle_logout_cmd(conn, cmd, (unsigned char *)hdr); - if (ret > 0) - wait_for_completion_timeout(&conn->conn_logout_comp, - SECONDS_FOR_LOGOUT_COMP * - HZ); break; case ISCSI_OP_TEXT: cmd = isert_allocate_cmd(conn); @@ -2922,15 +2918,14 @@ isert_immediate_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state) static int isert_response_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state) { + struct isert_conn *isert_conn = conn->context; int ret; switch (state) { case ISTATE_SEND_LOGOUTRSP: ret = isert_put_logout_rsp(cmd, conn); - if (!ret) { - pr_debug("Returning iSER Logout -EAGAIN\n"); - ret = -EAGAIN; - } + if (!ret) + isert_conn->logout_posted = true; break; case ISTATE_SEND_NOPIN: ret = isert_put_nopin(cmd, conn, true); @@ -3236,6 +3231,18 @@ static void isert_release_work(struct work_struct *work) } static void +isert_wait4logout(struct isert_conn *isert_conn) +{ + struct iscsi_conn *conn = isert_conn->conn; + + if (isert_conn->logout_posted) { + pr_info("conn %p wait for conn_logout_comp\n", isert_conn); + wait_for_completion_timeout(&conn->conn_logout_comp, + SECONDS_FOR_LOGOUT_COMP * HZ); + } +} + +static void isert_wait4cmds(struct iscsi_conn *conn) { if (conn->sess) { @@ -3280,6 +3287,7 @@ static void isert_wait_conn(struct iscsi_conn *conn) isert_wait4cmds(conn); isert_wait4flush(isert_conn); + isert_wait4logout(isert_conn); INIT_WORK(&isert_conn->release_work, isert_release_work); 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 2a0721f..e89f384 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.h +++ b/drivers/infiniband/ulp/isert/ib_isert.h @@ -156,6 +156,7 @@ struct isert_conn { spinlock_t conn_lock; struct work_struct release_work; struct ib_recv_wr beacon; + bool logout_posted; }; #define ISERT_MAX_CQ 64 -- 2.7.4