Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b90f90d2303f27b9b241ab78419a07b41de5ac62
Commit:     b90f90d2303f27b9b241ab78419a07b41de5ac62
Parent:     80b1c7bdc1cc69a804f416761f5faafcb6284086
Author:     Salyzyn, Mark <[EMAIL PROTECTED]>
AuthorDate: Fri Jul 27 09:48:49 2007 -0400
Committer:  James Bottomley <[EMAIL PROTECTED]>
CommitDate: Sat Jul 28 10:09:07 2007 -0400

    [SCSI] aacraid: add SCSI SYNCHONIZE_CACHE range checking
    
    Customer running an application that issues SYNCHRONIZE_CACHE calls
    directly noticed the broad stroke of the current implementation in the
    aacraid driver resulting in multiple applications feeding I/O to the
    storage causing the issuing application to stall for long periods of
    time. By only waiting for the current WRITE commands, rather than all
    commands, to complete; and those that are in range of the
    SYNCHRONIZE_CACHE call that would associate more tightly with the
    issuing application before telling the Firmware to flush it's dirty
    cache, we managed to reduce the stalling. The Firmware itself still
    flushes all the dirty cache associated with the array ignoring the
    range, it just does so in a more timely manner.
    
    Signed-off-by: Mark Salyzyn <[EMAIL PROTECTED]>
    Signed-off-by: James Bottomley <[EMAIL PROTECTED]>
---
 drivers/scsi/aacraid/aachba.c |   63 +++++++++++++++++++++++++++++++++++-----
 1 files changed, 55 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 54cdfcc..6800e57 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -1688,23 +1688,23 @@ static void synchronize_callback(void *context, struct 
fib *fibptr)
        if (!aac_valid_context(cmd, fibptr))
                return;
 
-       dprintk((KERN_DEBUG "synchronize_callback[cpu %d]: t = %ld.\n", 
+       dprintk((KERN_DEBUG "synchronize_callback[cpu %d]: t = %ld.\n",
                                smp_processor_id(), jiffies));
        BUG_ON(fibptr == NULL);
 
 
        synchronizereply = fib_data(fibptr);
        if (le32_to_cpu(synchronizereply->status) == CT_OK)
-               cmd->result = DID_OK << 16 | 
+               cmd->result = DID_OK << 16 |
                        COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
        else {
                struct scsi_device *sdev = cmd->device;
                struct aac_dev *dev = fibptr->dev;
                u32 cid = sdev_id(sdev);
-               printk(KERN_WARNING 
+               printk(KERN_WARNING
                     "synchronize_callback: synchronize failed, status = %d\n",
                     le32_to_cpu(synchronizereply->status));
-               cmd->result = DID_OK << 16 | 
+               cmd->result = DID_OK << 16 |
                        COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
                set_sense((u8 *)&dev->fsa_dev[cid].sense_data,
                                    HARDWARE_ERROR,
@@ -1712,7 +1712,7 @@ static void synchronize_callback(void *context, struct 
fib *fibptr)
                                    ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,
                                    0, 0);
                memcpy(cmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
-                 min(sizeof(dev->fsa_dev[cid].sense_data), 
+                 min(sizeof(dev->fsa_dev[cid].sense_data),
                          sizeof(cmd->sense_buffer)));
        }
 
@@ -1730,6 +1730,9 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd)
        struct scsi_device *sdev = scsicmd->device;
        int active = 0;
        struct aac_dev *aac;
+       u64 lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) |
+               (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
+       u32 count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];
        unsigned long flags;
 
        /*
@@ -1738,7 +1741,51 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd)
         */
        spin_lock_irqsave(&sdev->list_lock, flags);
        list_for_each_entry(cmd, &sdev->cmd_list, list)
-               if (cmd != scsicmd && cmd->SCp.phase == AAC_OWNER_FIRMWARE) {
+               if (cmd->SCp.phase == AAC_OWNER_FIRMWARE) {
+                       u64 cmnd_lba;
+                       u32 cmnd_count;
+
+                       if (cmd->cmnd[0] == WRITE_6) {
+                               cmnd_lba = ((cmd->cmnd[1] & 0x1F) << 16) |
+                                       (cmd->cmnd[2] << 8) |
+                                       cmd->cmnd[3];
+                               cmnd_count = cmd->cmnd[4];
+                               if (cmnd_count == 0)
+                                       cmnd_count = 256;
+                       } else if (cmd->cmnd[0] == WRITE_16) {
+                               cmnd_lba = ((u64)cmd->cmnd[2] << 56) |
+                                       ((u64)cmd->cmnd[3] << 48) |
+                                       ((u64)cmd->cmnd[4] << 40) |
+                                       ((u64)cmd->cmnd[5] << 32) |
+                                       ((u64)cmd->cmnd[6] << 24) |
+                                       (cmd->cmnd[7] << 16) |
+                                       (cmd->cmnd[8] << 8) |
+                                       cmd->cmnd[9];
+                               cmnd_count = (cmd->cmnd[10] << 24) |
+                                       (cmd->cmnd[11] << 16) |
+                                       (cmd->cmnd[12] << 8) |
+                                       cmd->cmnd[13];
+                       } else if (cmd->cmnd[0] == WRITE_12) {
+                               cmnd_lba = ((u64)cmd->cmnd[2] << 24) |
+                                       (cmd->cmnd[3] << 16) |
+                                       (cmd->cmnd[4] << 8) |
+                                       cmd->cmnd[5];
+                               cmnd_count = (cmd->cmnd[6] << 24) |
+                                       (cmd->cmnd[7] << 16) |
+                                       (cmd->cmnd[8] << 8) |
+                                       cmd->cmnd[9];
+                       } else if (cmd->cmnd[0] == WRITE_10) {
+                               cmnd_lba = ((u64)cmd->cmnd[2] << 24) |
+                                       (cmd->cmnd[3] << 16) |
+                                       (cmd->cmnd[4] << 8) |
+                                       cmd->cmnd[5];
+                               cmnd_count = (cmd->cmnd[7] << 8) |
+                                       cmd->cmnd[8];
+                       } else
+                               continue;
+                       if (((cmnd_lba + cmnd_count) < lba) ||
+                         (count && ((lba + count) < cmnd_lba)))
+                               continue;
                        ++active;
                        break;
                }
@@ -1767,7 +1814,7 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd)
        synchronizecmd->command = cpu_to_le32(VM_ContainerConfig);
        synchronizecmd->type = cpu_to_le32(CT_FLUSH_CACHE);
        synchronizecmd->cid = cpu_to_le32(scmd_id(scsicmd));
-       synchronizecmd->count = 
+       synchronizecmd->count =
             cpu_to_le32(sizeof(((struct aac_synchronize_reply *)NULL)->data));
 
        /*
@@ -1789,7 +1836,7 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd)
                return 0;
        }
 
-       printk(KERN_WARNING 
+       printk(KERN_WARNING
                "aac_synchronize: aac_fib_send failed with status: %d.\n", 
status);
        aac_fib_complete(cmd_fibcontext);
        aac_fib_free(cmd_fibcontext);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to