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);