]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
bnx2fc: cleanup task management IO when it times out.
authorBhanu Prakash Gollapudi <bprakash@broadcom.com>
Tue, 24 Apr 2012 22:26:03 +0000 (15:26 -0700)
committerJoe Jin <joe.jin@oracle.com>
Wed, 29 Aug 2012 00:22:07 +0000 (08:22 +0800)
When the task management IO times out, or a flush operation is performed while
task management IO is pending, driver is not cleaning up the IO. This patch
cleans up the IO for the above cases.

(cherry picked from commit 92886c9c97fd20dde26a12cd9f43cd3c786bc8ea)
Signed-off-by: Bhanu Prakash Gollapudi <bprakash@broadcom.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Signed-off-by: Joe Jin <joe.jin@oracle.com>
drivers/scsi/bnx2fc/bnx2fc_io.c
drivers/scsi/bnx2fc/bnx2fc_tgt.c

index 4843b42b22043d7226dd8af033dcf1c3d25690ab..27074eea35162333f3aaa0e4e15998a442bec296 100644 (file)
@@ -810,8 +810,22 @@ retry_tmf:
        spin_lock_bh(&tgt->tgt_lock);
 
        io_req->wait_for_comp = 0;
-       if (!(test_bit(BNX2FC_FLAG_TM_COMPL, &io_req->req_flags)))
+       if (!(test_bit(BNX2FC_FLAG_TM_COMPL, &io_req->req_flags))) {
                set_bit(BNX2FC_FLAG_TM_TIMEOUT, &io_req->req_flags);
+               if (io_req->on_tmf_queue) {
+                       list_del_init(&io_req->link);
+                       io_req->on_tmf_queue = 0;
+               }
+               io_req->wait_for_comp = 1;
+               bnx2fc_initiate_cleanup(io_req);
+               spin_unlock_bh(&tgt->tgt_lock);
+               rc = wait_for_completion_timeout(&io_req->tm_done,
+                                                BNX2FC_FW_TIMEOUT);
+               spin_lock_bh(&tgt->tgt_lock);
+               io_req->wait_for_comp = 0;
+               if (!rc)
+                       kref_put(&io_req->refcount, bnx2fc_cmd_release);
+       }
 
        spin_unlock_bh(&tgt->tgt_lock);
 
index d3ee231a5680653d931f10a7b31645272e3d4907..082a25c3117e58cf961c383803e743ac92b7da24 100644 (file)
@@ -185,6 +185,16 @@ void bnx2fc_flush_active_ios(struct bnx2fc_rport *tgt)
                BUG_ON(rc);
        }
 
+       list_for_each_safe(list, tmp, &tgt->active_tm_queue) {
+               i++;
+               io_req = (struct bnx2fc_cmd *)list;
+               list_del_init(&io_req->link);
+               io_req->on_tmf_queue = 0;
+               BNX2FC_IO_DBG(io_req, "tm_queue cleanup\n");
+               if (io_req->wait_for_comp)
+                       complete(&io_req->tm_done);
+       }
+
        list_for_each_safe(list, tmp, &tgt->els_queue) {
                i++;
                io_req = (struct bnx2fc_cmd *)list;