This is a note to let you know that I've just added the patch titled

    [SCSI] mpt2sas: Fix the race between broadcast asyn event and scsi command 
completion

to the 2.6.36-stable tree which can be found at:
    
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     
mpt2sas-fix-the-race-between-broadcast-asyn-event-and-scsi-command-completion.patch
and it can be found in the queue-2.6.36 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <[email protected]> know about it.


>From ec07a053597bdab51cbd23619f9f9f392712508a Mon Sep 17 00:00:00 2001
From: Kashyap, Desai <[email protected]>
Date: Wed, 5 Jan 2011 17:54:32 +0530
Subject: [SCSI] mpt2sas: Fix the race between broadcast asyn event and scsi 
command completion

From: Kashyap, Desai <[email protected]>

commit ec07a053597bdab51cbd23619f9f9f392712508a upstream.

False timeout after hard resets, there were two issues which leads
to timeout.
(1) Panic because of invalid memory access in the broadcast asyn
event processing routine due to a race between accessing the scsi command
pointer from broadcast asyn event processing thread and completing
the same scsi command from the interrupt context.
(2)  Broadcast asyn event notifcations are not handled due to events
ignored while the broadcast asyn event is activity being processed
from the event process kernel thread.

In addition, changed the ABRT_TASK_SET to ABORT_TASK in the
broadcast async event processing routine.   This is less disruptive to other
request that generate Broadcast Asyn Primitives besides target
reset. e.g clear reservations, microcode download,and mode select.

Signed-off-by: Kashyap Desai <[email protected]>
Signed-off-by: James Bottomley <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
 drivers/scsi/mpt2sas/mpt2sas_scsih.c |   54 +++++++++++++++++++++++++++++------
 1 file changed, 45 insertions(+), 9 deletions(-)

--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -819,7 +819,7 @@ _scsih_is_end_device(u32 device_info)
 }
 
 /**
- * mptscsih_get_scsi_lookup - returns scmd entry
+ * _scsih_scsi_lookup_get - returns scmd entry
  * @ioc: per adapter object
  * @smid: system request message index
  *
@@ -832,6 +832,28 @@ _scsih_scsi_lookup_get(struct MPT2SAS_AD
 }
 
 /**
+ * _scsih_scsi_lookup_get_clear - returns scmd entry
+ * @ioc: per adapter object
+ * @smid: system request message index
+ *
+ * Returns the smid stored scmd pointer.
+ * Then will derefrence the stored scmd pointer.
+ */
+static inline struct scsi_cmnd *
+_scsih_scsi_lookup_get_clear(struct MPT2SAS_ADAPTER *ioc, u16 smid)
+{
+       unsigned long flags;
+       struct scsi_cmnd *scmd;
+
+       spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
+       scmd = ioc->scsi_lookup[smid - 1].scmd;
+       ioc->scsi_lookup[smid - 1].scmd = NULL;
+       spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
+
+       return scmd;
+}
+
+/**
  * _scsih_scsi_lookup_find_by_scmd - scmd lookup
  * @ioc: per adapter object
  * @smid: system request message index
@@ -3183,7 +3205,7 @@ _scsih_flush_running_cmds(struct MPT2SAS
        u16 count = 0;
 
        for (smid = 1; smid <= ioc->scsiio_depth; smid++) {
-               scmd = _scsih_scsi_lookup_get(ioc, smid);
+               scmd = _scsih_scsi_lookup_get_clear(ioc, smid);
                if (!scmd)
                        continue;
                count++;
@@ -3775,7 +3797,7 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *i
        u32 response_code = 0;
 
        mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
-       scmd = _scsih_scsi_lookup_get(ioc, smid);
+       scmd = _scsih_scsi_lookup_get_clear(ioc, smid);
        if (scmd == NULL)
                return 1;
 
@@ -5037,6 +5059,7 @@ _scsih_sas_broadcast_primative_event(str
     struct fw_event_work *fw_event)
 {
        struct scsi_cmnd *scmd;
+       struct scsi_device *sdev;
        u16 smid, handle;
        u32 lun;
        struct MPT2SAS_DEVICE *sas_device_priv_data;
@@ -5047,12 +5070,17 @@ _scsih_sas_broadcast_primative_event(str
        Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data;
 #endif
        u16 ioc_status;
+       unsigned long flags;
+       int r;
+
        dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "broadcast primative: "
            "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum,
            event_data->PortWidth));
        dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
            __func__));
 
+       spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
+       ioc->broadcast_aen_busy = 0;
        termination_count = 0;
        query_count = 0;
        mpi_reply = ioc->tm_cmds.reply;
@@ -5060,7 +5088,8 @@ _scsih_sas_broadcast_primative_event(str
                scmd = _scsih_scsi_lookup_get(ioc, smid);
                if (!scmd)
                        continue;
-               sas_device_priv_data = scmd->device->hostdata;
+               sdev = scmd->device;
+               sas_device_priv_data = sdev->hostdata;
                if (!sas_device_priv_data || !sas_device_priv_data->sas_target)
                        continue;
                 /* skip hidden raid components */
@@ -5076,6 +5105,7 @@ _scsih_sas_broadcast_primative_event(str
                lun = sas_device_priv_data->lun;
                query_count++;
 
+               spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
                mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun,
                    MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30, NULL);
                ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
@@ -5085,14 +5115,20 @@ _scsih_sas_broadcast_primative_event(str
                    (mpi_reply->ResponseCode ==
                     MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED ||
                     mpi_reply->ResponseCode ==
-                    MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC))
+                    MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC)) {
+                       spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
                        continue;
-
-               mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun,
-                   MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, 0, 30, NULL);
+               }
+               r = mpt2sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id,
+                   sdev->lun, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30,
+                   scmd);
+               if (r == FAILED)
+                       sdev_printk(KERN_WARNING, sdev, "task abort: FAILED "
+                           "scmd(%p)\n", scmd);
                termination_count += le32_to_cpu(mpi_reply->TerminationCount);
+               spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
        }
-       ioc->broadcast_aen_busy = 0;
+       spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
 
        dtmprintk(ioc, printk(MPT2SAS_INFO_FMT
            "%s - exit, query_count = %d termination_count = %d\n",


Patches currently in stable-queue which might be from [email protected] are

queue-2.6.36/mpt2sas-kernel-panic-during-large-topology-discovery.patch
queue-2.6.36/mpt2sas-fix-the-race-between-broadcast-asyn-event-and-scsi-command-completion.patch
queue-2.6.36/mpt2sas-correct-resizing-calculation-for-max_queue_depth.patch
queue-2.6.36/mpt2sas-add-missing-initialization-of-scsih_cmds.patch
queue-2.6.36/mpt2sas-fix-integrated-raid-unsynced-on-shutdown-problem.patch
queue-2.6.36/mpt2sas-fix-internal-device-reset-for-older-firmware-prior-to-mpi-rev-k.patch
queue-2.6.36/mpt2sas-fix-device-removal-handshake-for-zoned-devices.patch

_______________________________________________
stable mailing list
[email protected]
http://linux.kernel.org/mailman/listinfo/stable

Reply via email to