From: Mike Christie <[EMAIL PROTECTED]>

The timer_pending check is broken in fc_fcp.c, because if the
timer function is running there is no timer_pending. If that
timer function is just trying to grab the pkt lock, then
fc_io_compl (which has the lock) would see no timer pending,
and free the pkt from under the timer function. We just
want to call del_timer_sync in this case.

This patch also removes the fc_fcp_complete del_timer_sync
since it is a dup of what fc_io_compl does. And this
patch fixes the refcounting for when we drop the pkt
lock to call del_timer_sync. We must take a ref in
case the lun reset code were to clean us up or if
the timeout code were killing the command we then we
got a response we could hit the same problem.

Patch was made over
libfc: remove shared tag map and fix timer usage in fc_fcp.c (take 2)

This patch is not tested. I am having hardware troubles, and only
have a laptop (has anyone run stgt and the initiator on the same box
and do you have to use aliases or something to get it to work?)
I will have a new target box soon but will not be done for day or so

The patch is small and we hit this code patch already
(normally when a command is completed the fsp->timer is not
running (it is pending) so we go down the del_timer_sync path), so
I think it should be ok, But do a simple IO test to make sure if you
merge before I can test.

Signed-off-by: Mike Christie <[EMAIL PROTECTED]>
---
 drivers/scsi/libfc/fc_fcp.c |   38 ++++++++++++++------------------------
 1 files changed, 14 insertions(+), 24 deletions(-)

diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index bfb9fc4..bb86ced 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -783,18 +783,6 @@ static void fc_fcp_complete(struct fc_fcp_pkt *fsp)
        struct fc_seq *sp;
        u32 f_ctl;
 
-       if (timer_pending(&fsp->timer)) {
-               spin_unlock(&fsp->scsi_pkt_lock);
-               /*
-                * TODO mnc: we should probably make the timer per port or per
-                * host, and then have that timer function check for timeouts
-                * on all commands. This will prevent the del_timer_sync call
-                * in the main IO path.
-                */
-               del_timer_sync(&fsp->timer);
-               spin_lock(&fsp->scsi_pkt_lock);
-       }
-
        /*
         * Test for transport underrun, independent of response underrun status.
         */
@@ -1051,11 +1039,9 @@ static int fc_fcp_pkt_abort(struct fc_lport *lp, struct 
fc_fcp_pkt *fsp)
                rc = SUCCESS;
        }
 
-       if (timer_pending(&fsp->timer)) {
-               spin_unlock(&fsp->scsi_pkt_lock);
-               del_timer_sync(&fsp->timer);
-               spin_lock(&fsp->scsi_pkt_lock);
-       }
+       spin_unlock(&fsp->scsi_pkt_lock);
+       del_timer_sync(&fsp->timer);
+       spin_lock(&fsp->scsi_pkt_lock);
        return rc;
 }
 
@@ -1791,15 +1777,19 @@ static void fc_io_compl(struct fc_fcp_pkt *sp)
        struct scsi_cmnd *sc_cmd;
        struct fc_lport *lp;
        unsigned long flags;
+       int rc;
 
        sp->state |= FC_SRB_COMPL;
-       if (timer_pending(&sp->timer)) {
-               fc_fcp_unlock_pkt(sp);
-               del_timer_sync(&sp->timer);
-               if (fc_fcp_lock_pkt(sp))
-                       /* A TMF or relogin killed the command from under us */
-                       return;
-       }
+       fc_fcp_pkt_hold(sp);
+       fc_fcp_unlock_pkt(sp);
+
+       del_timer_sync(&sp->timer);
+
+       rc = fc_fcp_lock_pkt(sp);
+       fc_fcp_pkt_release(sp);
+       if (rc)
+               /* A TMF or relogin killed the command from under us */
+               return;
 
        lp = sp->lp;
        spin_lock_irqsave(lp->host->host_lock, flags);
-- 
1.5.5.1

_______________________________________________
devel mailing list
[email protected]
http://www.open-fcoe.org/mailman/listinfo/devel

Reply via email to