summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSagi Grimberg <sagig@mellanox.com>2014-12-07 12:12:01 +0100
committerNicholas Bellinger <nab@linux-iscsi.org>2014-12-13 08:32:33 +0100
commit991bb7640d7e0971c360b6166cbca84a7f502312 (patch)
tree15a2c654a625cdfb9e843b65303cd9a209b702e1 /drivers
parentiser-target: Don't wait for session commands from completion context (diff)
downloadlinux-991bb7640d7e0971c360b6166cbca84a7f502312.tar.xz
linux-991bb7640d7e0971c360b6166cbca84a7f502312.zip
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')
-rw-r--r--drivers/infiniband/ulp/isert/ib_isert.c24
-rw-r--r--drivers/infiniband/ulp/isert/ib_isert.h1
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,
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 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 {
spinlock_t conn_lock;
struct work_struct release_work;
struct ib_recv_wr beacon;
+ bool logout_posted;
};
#define ISERT_MAX_CQ 64