OSDN Git Service

iser-target: Fix logout sequence
authorSagi Grimberg <sagig@mellanox.com>
Sun, 7 Dec 2014 11:12:01 +0000 (13:12 +0200)
committerNicholas Bellinger <nab@linux-iscsi.org>
Sat, 13 Dec 2014 07:32:33 +0000 (23:32 -0800)
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>
drivers/infiniband/ulp/isert/ib_isert.c
drivers/infiniband/ulp/isert/ib_isert.h

index fc4641e..1085484 100644 (file)
@@ -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);
index 2a0721f..e89f384 100644 (file)
@@ -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