diff options
| author | Linas Vepstas <linas@austin.ibm.com> | 2006-10-30 16:15:59 +1100 | 
|---|---|---|
| committer | Paul Mackerras <paulus@samba.org> | 2006-11-01 14:52:48 +1100 | 
| commit | 5d2efba64b231a1733c4048d1708d77e07f26426 (patch) | |
| tree | 2893dd45b9c26cef6cddb5fef0c6f820c5eb534e /arch/powerpc/platforms/iseries/iommu.c | |
| parent | dd6c89f686bdb2a5de72fab636fc839e5a0add6d (diff) | |
| download | olio-linux-3.10-5d2efba64b231a1733c4048d1708d77e07f26426.tar.xz olio-linux-3.10-5d2efba64b231a1733c4048d1708d77e07f26426.zip  | |
[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/platforms/iseries/iommu.c')
| -rw-r--r-- | arch/powerpc/platforms/iseries/iommu.c | 11 | 
1 files changed, 2 insertions, 9 deletions
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index f4cbbcf8773..218817d13c5 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c @@ -43,9 +43,6 @@ static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages,  	u64 rc;  	u64 tce, rpn; -	index <<= TCE_PAGE_FACTOR; -	npages <<= TCE_PAGE_FACTOR; -  	while (npages--) {  		rpn = virt_to_abs(uaddr) >> TCE_SHIFT;  		tce = (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; @@ -75,9 +72,6 @@ static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages)  {  	u64 rc; -	npages <<= TCE_PAGE_FACTOR; -	index <<= TCE_PAGE_FACTOR; -  	while (npages--) {  		rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, 0);  		if (rc) @@ -136,10 +130,9 @@ void iommu_table_getparms_iSeries(unsigned long busno,  		panic("PCI_DMA: parms->size is zero, parms is 0x%p", parms);  	/* itc_size is in pages worth of table, it_size is in # of entries */ -	tbl->it_size = ((parms->itc_size * TCE_PAGE_SIZE) / -			TCE_ENTRY_SIZE) >> TCE_PAGE_FACTOR; +	tbl->it_size = (parms->itc_size * TCE_PAGE_SIZE) / TCE_ENTRY_SIZE;  	tbl->it_busno = parms->itc_busno; -	tbl->it_offset = parms->itc_offset >> TCE_PAGE_FACTOR; +	tbl->it_offset = parms->itc_offset;  	tbl->it_index = parms->itc_index;  	tbl->it_blocksize = 1;  	tbl->it_type = virtbus ? TCE_VB : TCE_PCI;  |