diff options
author | Linas Vepstas <linas@austin.ibm.com> | 2006-10-30 00:15:59 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-10-31 22:52:48 -0500 |
commit | 5d2efba64b231a1733c4048d1708d77e07f26426 (patch) | |
tree | 2893dd45b9c26cef6cddb5fef0c6f820c5eb534e /arch/powerpc/sysdev/dart_iommu.c | |
parent | dd6c89f686bdb2a5de72fab636fc839e5a0add6d (diff) |
[POWERPC] Use 4kB iommu pages even on 64kB-page systems
The 10Gigabit ethernet device drivers appear to be able to chew
up all 256MB of TCE mappings on pSeries systems, as evidenced by
numerous error messages:
iommu_alloc failed, tbl c0000000010d5c48 vaddr c0000000d875eff0 npages 1
Some experimentation indicates that this is essentially because
one 1500 byte ethernet MTU gets mapped as a 64K DMA region when
the large 64K pages are enabled. Thus, it doesn't take much to
exhaust all of the available DMA mappings for a high-speed card.
This patch changes the iommu allocator to work with its own
unique, distinct page size. Although the patch is long, its
actually quite simple: it just #defines a distinct IOMMU_PAGE_SIZE
and then uses this in all the places that matter.
As a side effect, it also dramatically improves network performance
on platforms with H-calls on iommu translation inserts/removes (since
we no longer call it 16 times for a 1500 bytes packet when the iommu HW
is still 4k).
In the future, we might want to make the IOMMU_PAGE_SIZE a variable
in the iommu_table instance, thus allowing support for different HW
page sizes in the iommu itself.
Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: Olof Johansson <olof@lixom.net>
Acked-by: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/sysdev/dart_iommu.c')
-rw-r--r-- | arch/powerpc/sysdev/dart_iommu.c | 8 |
1 files changed, 1 insertions, 7 deletions
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index 03b4477dd7f0..572b7846cc77 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c | |||
@@ -156,9 +156,6 @@ static void dart_build(struct iommu_table *tbl, long index, | |||
156 | 156 | ||
157 | DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr); | 157 | DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr); |
158 | 158 | ||
159 | index <<= DART_PAGE_FACTOR; | ||
160 | npages <<= DART_PAGE_FACTOR; | ||
161 | |||
162 | dp = ((unsigned int*)tbl->it_base) + index; | 159 | dp = ((unsigned int*)tbl->it_base) + index; |
163 | 160 | ||
164 | /* On U3, all memory is contigous, so we can move this | 161 | /* On U3, all memory is contigous, so we can move this |
@@ -199,9 +196,6 @@ static void dart_free(struct iommu_table *tbl, long index, long npages) | |||
199 | 196 | ||
200 | DBG("dart: free at: %lx, %lx\n", index, npages); | 197 | DBG("dart: free at: %lx, %lx\n", index, npages); |
201 | 198 | ||
202 | index <<= DART_PAGE_FACTOR; | ||
203 | npages <<= DART_PAGE_FACTOR; | ||
204 | |||
205 | dp = ((unsigned int *)tbl->it_base) + index; | 199 | dp = ((unsigned int *)tbl->it_base) + index; |
206 | 200 | ||
207 | while (npages--) | 201 | while (npages--) |
@@ -281,7 +275,7 @@ static void iommu_table_dart_setup(void) | |||
281 | iommu_table_dart.it_busno = 0; | 275 | iommu_table_dart.it_busno = 0; |
282 | iommu_table_dart.it_offset = 0; | 276 | iommu_table_dart.it_offset = 0; |
283 | /* it_size is in number of entries */ | 277 | /* it_size is in number of entries */ |
284 | iommu_table_dart.it_size = (dart_tablesize / sizeof(u32)) >> DART_PAGE_FACTOR; | 278 | iommu_table_dart.it_size = dart_tablesize / sizeof(u32); |
285 | 279 | ||
286 | /* Initialize the common IOMMU code */ | 280 | /* Initialize the common IOMMU code */ |
287 | iommu_table_dart.it_base = (unsigned long)dart_vbase; | 281 | iommu_table_dart.it_base = (unsigned long)dart_vbase; |