IB/iser: Handle aborting a command after it is sent
authorErez Zilber <erezz@voltaire.com>
Sun, 25 Mar 2007 10:07:10 +0000 (12:07 +0200)
committerRoland Dreier <rolandd@cisco.com>
Mon, 26 Mar 2007 23:35:09 +0000 (16:35 -0700)
The SCSI midlayer may abort a command that was already sent.  If the
initiator is still trying to send the command (or data-out PDUs for
that command), the QP may time out after the midlayer times
out. Therefore, when aborting the command, iSER may still have
references for the command's buffers.  When sending these PDUs, the
sends will complete with an error and their resources will be released
then.

Signed-off-by: Erez Zilber <erezz@voltaire.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
drivers/infiniband/ulp/iser/iser_initiator.c

index 89e37283c83689a9896b7beee38bc6491939e6de..278fcbccc2d995e21b167d7623575009f2fa948c 100644 (file)
@@ -658,6 +658,7 @@ void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *iser_ctask)
 {
        int deferred;
        int is_rdma_aligned = 1;
+       struct iser_regd_buf *regd;
 
        /* if we were reading, copy back to unaligned sglist,
         * anyway dma_unmap and free the copy
@@ -672,20 +673,20 @@ void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *iser_ctask)
        }
 
        if (iser_ctask->dir[ISER_DIR_IN]) {
-               deferred = iser_regd_buff_release
-                       (&iser_ctask->rdma_regd[ISER_DIR_IN]);
+               regd = &iser_ctask->rdma_regd[ISER_DIR_IN];
+               deferred = iser_regd_buff_release(regd);
                if (deferred) {
-                       iser_err("References remain for BUF-IN rdma reg\n");
-                       BUG();
+                       iser_err("%d references remain for BUF-IN rdma reg\n",
+                                atomic_read(&regd->ref_count));
                }
        }
 
        if (iser_ctask->dir[ISER_DIR_OUT]) {
-               deferred = iser_regd_buff_release
-                       (&iser_ctask->rdma_regd[ISER_DIR_OUT]);
+               regd = &iser_ctask->rdma_regd[ISER_DIR_OUT];
+               deferred = iser_regd_buff_release(regd);
                if (deferred) {
-                       iser_err("References remain for BUF-OUT rdma reg\n");
-                       BUG();
+                       iser_err("%d references remain for BUF-OUT rdma reg\n",
+                                atomic_read(&regd->ref_count));
                }
        }