lkml.org 
[lkml]   [2006]   [Feb]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
SubjectRe: [PATCH] ipr: don't doublefree pages from scatterlist
Date
On Monday 06 February 2006 17:45, Hugh Dickins wrote:

>
> But all this presupposes that someone is suddenly going to change the
> x86_64 gart_map_sg (and subfunctions), or else force its iommu=nomerge:
> that won't be me.

Ok i changed it to conform to the gospel. I gave it some basic pounding LTP/dd IO with
and without IOMMU force, but it's not that well tested. More testing welcome.

-Andi

Don't touch the non DMA members in the sg list in dma_map_sg in the IOMMU

Some drivers (in particular ipr) ran into problems because they
reused the sg lists after passing them to pci_map_sg(). The merging
procedure in the K8 GART IOMMU corrupted the state. This patch
changes it to only touch the dma* entries during merging,
but not the other fields. Approach suggested by Dave Miller.

I did some basic tests with CONFIG_IOMMU_DEBUG (LTP, large dd)
and without and it hold up, but needs more testing.

Signed-off-by: Andi Kleen <ak@suse.de>

Index: linux/arch/x86_64/kernel/pci-gart.c
===================================================================
--- linux.orig/arch/x86_64/kernel/pci-gart.c
+++ linux/arch/x86_64/kernel/pci-gart.c
@@ -300,7 +300,7 @@ void gart_unmap_sg(struct device *dev, s

for (i = 0; i < nents; i++) {
struct scatterlist *s = &sg[i];
- if (!s->dma_length || !s->length)
+ if (!s->dma_length)
break;
dma_unmap_single(dev, s->dma_address, s->dma_length, dir);
}
@@ -354,7 +354,6 @@ static int __dma_map_cont(struct scatter

BUG_ON(i > start && s->offset);
if (i == start) {
- *sout = *s;
sout->dma_address = iommu_bus_base;
sout->dma_address += iommu_page*PAGE_SIZE + s->offset;
sout->dma_length = s->length;
@@ -369,7 +368,7 @@ static int __dma_map_cont(struct scatter
SET_LEAK(iommu_page);
addr += PAGE_SIZE;
iommu_page++;
- }
+ }
}
BUG_ON(iommu_page - iommu_start != pages);
return 0;
@@ -381,7 +380,6 @@ static inline int dma_map_cont(struct sc
{
if (!need) {
BUG_ON(stopat - start != 1);
- *sout = sg[start];
sout->dma_length = sg[start].length;
return 0;
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
\
 
 \ /
  Last update: 2006-02-06 22:15    [from the cache]
©2003-2011 Jasper Spaans