aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSalyzyn, Mark <mark_salyzyn@adaptec.com>2007-07-27 09:48:49 -0400
committerJames Bottomley <jejb@mulgrave.localdomain>2007-07-28 10:09:07 -0400
commitb90f90d2303f27b9b241ab78419a07b41de5ac62 (patch)
treefe609680bf9030fdebe38928dc05ca9d0f553590 /drivers
parent80b1c7bdc1cc69a804f416761f5faafcb6284086 (diff)
[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 <aacraid@adaptec.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/aacraid/aachba.c63
1 files changed, 55 insertions, 8 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 54cdfcc929ae..6800e578e4b1 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)
1688 if (!aac_valid_context(cmd, fibptr)) 1688 if (!aac_valid_context(cmd, fibptr))
1689 return; 1689 return;
1690 1690
1691 dprintk((KERN_DEBUG "synchronize_callback[cpu %d]: t = %ld.\n", 1691 dprintk((KERN_DEBUG "synchronize_callback[cpu %d]: t = %ld.\n",
1692 smp_processor_id(), jiffies)); 1692 smp_processor_id(), jiffies));
1693 BUG_ON(fibptr == NULL); 1693 BUG_ON(fibptr == NULL);
1694 1694
1695 1695
1696 synchronizereply = fib_data(fibptr); 1696 synchronizereply = fib_data(fibptr);
1697 if (le32_to_cpu(synchronizereply->status) == CT_OK) 1697 if (le32_to_cpu(synchronizereply->status) == CT_OK)
1698 cmd->result = DID_OK << 16 | 1698 cmd->result = DID_OK << 16 |
1699 COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; 1699 COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
1700 else { 1700 else {
1701 struct scsi_device *sdev = cmd->device; 1701 struct scsi_device *sdev = cmd->device;
1702 struct aac_dev *dev = fibptr->dev; 1702 struct aac_dev *dev = fibptr->dev;
1703 u32 cid = sdev_id(sdev); 1703 u32 cid = sdev_id(sdev);
1704 printk(KERN_WARNING 1704 printk(KERN_WARNING
1705 "synchronize_callback: synchronize failed, status = %d\n", 1705 "synchronize_callback: synchronize failed, status = %d\n",
1706 le32_to_cpu(synchronizereply->status)); 1706 le32_to_cpu(synchronizereply->status));
1707 cmd->result = DID_OK << 16 | 1707 cmd->result = DID_OK << 16 |
1708 COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; 1708 COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
1709 set_sense((u8 *)&dev->fsa_dev[cid].sense_data, 1709 set_sense((u8 *)&dev->fsa_dev[cid].sense_data,
1710 HARDWARE_ERROR, 1710 HARDWARE_ERROR,
@@ -1712,7 +1712,7 @@ static void synchronize_callback(void *context, struct fib *fibptr)
1712 ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0, 1712 ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,
1713 0, 0); 1713 0, 0);
1714 memcpy(cmd->sense_buffer, &dev->fsa_dev[cid].sense_data, 1714 memcpy(cmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
1715 min(sizeof(dev->fsa_dev[cid].sense_data), 1715 min(sizeof(dev->fsa_dev[cid].sense_data),
1716 sizeof(cmd->sense_buffer))); 1716 sizeof(cmd->sense_buffer)));
1717 } 1717 }
1718 1718
@@ -1730,6 +1730,9 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd)
1730 struct scsi_device *sdev = scsicmd->device; 1730 struct scsi_device *sdev = scsicmd->device;
1731 int active = 0; 1731 int active = 0;
1732 struct aac_dev *aac; 1732 struct aac_dev *aac;
1733 u64 lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) |
1734 (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
1735 u32 count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];
1733 unsigned long flags; 1736 unsigned long flags;
1734 1737
1735 /* 1738 /*
@@ -1738,7 +1741,51 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd)
1738 */ 1741 */
1739 spin_lock_irqsave(&sdev->list_lock, flags); 1742 spin_lock_irqsave(&sdev->list_lock, flags);
1740 list_for_each_entry(cmd, &sdev->cmd_list, list) 1743 list_for_each_entry(cmd, &sdev->cmd_list, list)
1741 if (cmd != scsicmd && cmd->SCp.phase == AAC_OWNER_FIRMWARE) { 1744 if (cmd->SCp.phase == AAC_OWNER_FIRMWARE) {
1745 u64 cmnd_lba;
1746 u32 cmnd_count;
1747
1748 if (cmd->cmnd[0] == WRITE_6) {
1749 cmnd_lba = ((cmd->cmnd[1] & 0x1F) << 16) |
1750 (cmd->cmnd[2] << 8) |
1751 cmd->cmnd[3];
1752 cmnd_count = cmd->cmnd[4];
1753 if (cmnd_count == 0)
1754 cmnd_count = 256;
1755 } else if (cmd->cmnd[0] == WRITE_16) {
1756 cmnd_lba = ((u64)cmd->cmnd[2] << 56) |
1757 ((u64)cmd->cmnd[3] << 48) |
1758 ((u64)cmd->cmnd[4] << 40) |
1759 ((u64)cmd->cmnd[5] << 32) |
1760 ((u64)cmd->cmnd[6] << 24) |
1761 (cmd->cmnd[7] << 16) |
1762 (cmd->cmnd[8] << 8) |
1763 cmd->cmnd[9];
1764 cmnd_count = (cmd->cmnd[10] << 24) |
1765 (cmd->cmnd[11] << 16) |
1766 (cmd->cmnd[12] << 8) |
1767 cmd->cmnd[13];
1768 } else if (cmd->cmnd[0] == WRITE_12) {
1769 cmnd_lba = ((u64)cmd->cmnd[2] << 24) |
1770 (cmd->cmnd[3] << 16) |
1771 (cmd->cmnd[4] << 8) |
1772 cmd->cmnd[5];
1773 cmnd_count = (cmd->cmnd[6] << 24) |
1774 (cmd->cmnd[7] << 16) |
1775 (cmd->cmnd[8] << 8) |
1776 cmd->cmnd[9];
1777 } else if (cmd->cmnd[0] == WRITE_10) {
1778 cmnd_lba = ((u64)cmd->cmnd[2] << 24) |
1779 (cmd->cmnd[3] << 16) |
1780 (cmd->cmnd[4] << 8) |
1781 cmd->cmnd[5];
1782 cmnd_count = (cmd->cmnd[7] << 8) |
1783 cmd->cmnd[8];
1784 } else
1785 continue;
1786 if (((cmnd_lba + cmnd_count) < lba) ||
1787 (count && ((lba + count) < cmnd_lba)))
1788 continue;
1742 ++active; 1789 ++active;
1743 break; 1790 break;
1744 } 1791 }
@@ -1767,7 +1814,7 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd)
1767 synchronizecmd->command = cpu_to_le32(VM_ContainerConfig); 1814 synchronizecmd->command = cpu_to_le32(VM_ContainerConfig);
1768 synchronizecmd->type = cpu_to_le32(CT_FLUSH_CACHE); 1815 synchronizecmd->type = cpu_to_le32(CT_FLUSH_CACHE);
1769 synchronizecmd->cid = cpu_to_le32(scmd_id(scsicmd)); 1816 synchronizecmd->cid = cpu_to_le32(scmd_id(scsicmd));
1770 synchronizecmd->count = 1817 synchronizecmd->count =
1771 cpu_to_le32(sizeof(((struct aac_synchronize_reply *)NULL)->data)); 1818 cpu_to_le32(sizeof(((struct aac_synchronize_reply *)NULL)->data));
1772 1819
1773 /* 1820 /*
@@ -1789,7 +1836,7 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd)
1789 return 0; 1836 return 0;
1790 } 1837 }
1791 1838
1792 printk(KERN_WARNING 1839 printk(KERN_WARNING
1793 "aac_synchronize: aac_fib_send failed with status: %d.\n", status); 1840 "aac_synchronize: aac_fib_send failed with status: %d.\n", status);
1794 aac_fib_complete(cmd_fibcontext); 1841 aac_fib_complete(cmd_fibcontext);
1795 aac_fib_free(cmd_fibcontext); 1842 aac_fib_free(cmd_fibcontext);