]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.fixes/scsi-ibmvscsi-vio_leak.patch
Fix oinkmaster patch.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.fixes / scsi-ibmvscsi-vio_leak.patch
CommitLineData
2cb7cef9
BS
1Subject: Correct VIO bus/device CMO accounting problems
2From: Robert Jennings <rcj@linux.vnet.ibm.com>
3References: 468304 - LTC51205
4
5This corrects three entitlement accounting issues that are all small in
6scope but at least two of them are critical.
7
8In the VIO bus code the wrappers for dma alloc_coherent and free_coherent
9calls are rounding to IOMMU_PAGE_SIZE. Taking a look at the underlying
10calls, the actual mapping is promoted to PAGE_SIZE. Changing the
11rounding in these two functions fixes under reporting the entitlement
12used. Without this change, the system could run out of entitlement before
13it believes it has and incur mapping failures at the firmware level.
14
15Also in the VIO bus code, the wrapper for dma map_sg is not exiting in
16an error path where it should. Rather than fall through to code for the
17success case, this patch adds the return that is needed in the error path.
18
19The ibmvscsi client driver is not unmapping the scsi command after
20encountering a dma mapping error while trying to map an indirect
21scattergather list. This leads to a leak of dma entitlement that could
22result in the device failing future dma operations.
23
24Signed-off-by: Robert Jennings <rcj@linux.vnet.ibm.com>
25Signed-off-by: Olaf Hering <olh@suse.de>
26
27--
28 arch/powerpc/kernel/vio.c | 7 ++++---
29 drivers/scsi/ibmvscsi/ibmvfc.c | 4 +++-
30 drivers/scsi/ibmvscsi/ibmvscsi.c | 1 +
31 3 files changed, 8 insertions(+), 4 deletions(-)
32
33--- a/arch/powerpc/kernel/vio.c
34+++ b/arch/powerpc/kernel/vio.c
35@@ -492,14 +492,14 @@ static void *vio_dma_iommu_alloc_coheren
36 struct vio_dev *viodev = to_vio_dev(dev);
37 void *ret;
38
39- if (vio_cmo_alloc(viodev, roundup(size, IOMMU_PAGE_SIZE))) {
40+ if (vio_cmo_alloc(viodev, roundup(size, PAGE_SIZE))) {
41 atomic_inc(&viodev->cmo.allocs_failed);
42 return NULL;
43 }
44
45 ret = dma_iommu_ops.alloc_coherent(dev, size, dma_handle, flag);
46 if (unlikely(ret == NULL)) {
47- vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE));
48+ vio_cmo_dealloc(viodev, roundup(size, PAGE_SIZE));
49 atomic_inc(&viodev->cmo.allocs_failed);
50 }
51
52@@ -513,7 +513,7 @@ static void vio_dma_iommu_free_coherent(
53
54 dma_iommu_ops.free_coherent(dev, size, vaddr, dma_handle);
55
56- vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE));
57+ vio_cmo_dealloc(viodev, roundup(size, PAGE_SIZE));
58 }
59
60 static dma_addr_t vio_dma_iommu_map_single(struct device *dev, void *vaddr,
61@@ -572,6 +572,7 @@ static int vio_dma_iommu_map_sg(struct d
62 if (unlikely(!ret)) {
63 vio_cmo_dealloc(viodev, alloc_size);
64 atomic_inc(&viodev->cmo.allocs_failed);
65+ return ret;
66 }
67
68 for (sgl = sglist, count = 0; count < ret; count++, sgl++)
69--- a/drivers/scsi/ibmvscsi/ibmvfc.c
70+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
71@@ -1323,7 +1323,9 @@ static int ibmvfc_map_sg_data(struct scs
72 &evt->ext_list_token);
73
74 if (!evt->ext_list) {
75- scmd_printk(KERN_ERR, scmd, "Can't allocate memory for scatterlist\n");
76+ scsi_dma_unmap(scmd);
77+ if (vhost->log_level > IBMVFC_DEFAULT_LOG_LEVEL)
78+ scmd_printk(KERN_ERR, scmd, "Can't allocate memory for scatterlist\n");
79 return -ENOMEM;
80 }
81 }
82--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
83+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
84@@ -435,6 +435,7 @@ static int map_sg_data(struct scsi_cmnd
85 sdev_printk(KERN_ERR, cmd->device,
86 "Can't allocate memory "
87 "for indirect table\n");
88+ scsi_dma_unmap(cmd);
89 return 0;
90 }
91 }