ia64: round iommu allocations to power-of-two sizes.
Linux Kernel Mailing List <[email protected]> Fri, 02 Jul 2004 21:41:59 +0000
| Newsgroups | gmane.linux.kernel.commits.2-4 |
|---|---|
| Message-ID | <[email protected]> |
ChangeSet 1.1451, 2004/07/02 15:41:59-06:00, [email protected] ia64: round iommu allocations to power-of-two sizes. Round IOVA allocations to power-of-two sizes to avoid REO/Grande defect AR2305. sba_iommu.c | 9 +++++++++ 1 files changed, 9 insertions(+) diff -Nru a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c --- a/arch/ia64/hp/common/sba_iommu.c 2005-03-24 09:03:41 -08:00 +++ b/arch/ia64/hp/common/sba_iommu.c 2005-03-24 09:03:41 -08:00 @@ -447,6 +447,14 @@ ASSERT(((unsigned long) ioc->res_hint & (sizeof(unsigned long) - 1UL)) == 0); ASSERT(res_ptr < res_end); + + /* + * N.B. REO/Grande defect AR2305 can cause TLB fetch timeouts + * if a TLB entry is purged while in use. sba_mark_invalid() + * purges IOTLB entries in power-of-two sizes, so we also + * allocate IOVA space in power-of-two sizes. + */ + bits_wanted = 1UL << get_iovp_order(bits_wanted << PAGE_SHIFT); if (bits_wanted > (BITS_PER_LONG/2)) { /* Search word at a time - no mask needed */ for(; res_ptr < res_end; ++res_ptr) { @@ -583,6 +591,7 @@ unsigned long *res_ptr = (unsigned long *) &((ioc)->res_map[ridx & ~RESMAP_IDX_MASK]); int bits_not_wanted = size >> iovp_shift; + bits_not_wanted = 1UL << get_iovp_order(bits_not_wanted << PAGE_SHIFT); /* 3-bits "bit" address plus 2 (or 3) bits for "byte" == bit in word */ unsigned long m = RESMAP_MASK(bits_not_wanted) << (pide & (BITS_PER_LONG - 1));