Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > media > main-src > by-pkgid > d0a35cd31c1125e2132804d68547073d > files > 3711

kernel-2.6.18-194.26.1.el5.src.rpm

From: David Milburn <dmilburn@redhat.com>
Date: Wed, 15 Jul 2009 13:48:11 -0500
Subject: [scsi] stex: minimize DMA coherent allocation
Message-id: 20090715184811.GA6275@dhcp-210.hsv.redhat.com
O-Subject: [RHEL5.4 PATCH] stex: minimize DMA coherent allocation
Bugzilla: 486466
RH-Acked-by: Jeff Garzik <jgarzik@redhat.com>
RH-Acked-by: Stefan Assmann <sassmann@redhat.com>
RH-Acked-by: Prarit Bhargava <prarit@redhat.com>

RHEL5 xen kernel may panic if the Promise SuperTrak
EX driver fails a dma memory allocation. The stex
driver tries to allocate an additional 2MB for the
st_vsc sas/sata raid controller which exeeds the
largest contiguous allocation allowed by the xen
kernel. The controller firmware is using the
additional buffer to support a raid migration
feature set, if the controller has a reduced buffer
it may have to reject certain migration requests.
According to Promise normally I/O requests will
not be affected and reducing the allocation will
not result in any data loss or corruption. According
to Promise this patch will be included in their
next upstream stex driver update. Hitachi has con-
firmed a -157.el5 xen test kernel built with this
patch.

This is for BZ 486466, please review and ACK.

Thanks,
David

 drivers/scsi/stex.c |   25 +++++++++++++++++++++----
 1 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index aaaaa39..685a84c 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -154,6 +154,7 @@ enum {
 	INQUIRY_EVPD				= 0x01,
 
 	ST_ADDITIONAL_MEM			= 0x200000,
+	ST_ADDITIONAL_MEM_MIN                   = 0x80000,
 };
 
 struct st_sgitem {
@@ -1622,10 +1623,26 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	hba->dma_mem = dma_alloc_coherent(&pdev->dev,
 		hba->dma_size, &hba->dma_handle, GFP_KERNEL);
 	if (!hba->dma_mem) {
-		err = -ENOMEM;
-		printk(KERN_ERR DRV_NAME "(%s): dma mem alloc failed\n",
-			pci_name(pdev));
-		goto out_iounmap;
+		/* Retry minimum coherent mapping for st_seq and st_vsc */
+		if (hba->cardtype == st_seq ||
+		    (hba->cardtype == st_vsc && (pdev->subsystem_device & 1))) {
+			printk(KERN_WARNING DRV_NAME
+			       "(%s): Allocating min buffer for controller\n",
+			       pci_name(pdev));
+			hba->dma_size = hba->extra_offset
+				+ ST_ADDITIONAL_MEM_MIN;
+			hba->dma_mem = dma_alloc_coherent(&pdev->dev,
+							  hba->dma_size,
+							  &hba->dma_handle,
+							  GFP_KERNEL);
+		}
+
+		if (!hba->dma_mem) {
+			err = -ENOMEM;
+			printk(KERN_ERR DRV_NAME "(%s): dma mem alloc failed\n",
+			       pci_name(pdev));
+			goto out_iounmap;
+		}
 	}
 
 	hba->ccb = kcalloc(ci->rq_count, sizeof(struct st_ccb), GFP_KERNEL);