From: Prarit Bhargava <prarit@redhat.com>
To: Jesse Barnes <jbarnes@virtuousgeek.org>
Cc: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>,
joro@8bytes.org, linux-kernel@vger.kernel.org,
linux-pci@vger.kernel.org
Subject: Re: [PATCH]: PCI: GART iommu alignment fixes [v2]
Date: Tue, 29 Jul 2008 10:24:25 -0400 [thread overview]
Message-ID: <488F2819.2090303@redhat.com> (raw)
In-Reply-To: <200807281523.35469.jbarnes@virtuousgeek.org>
[-- Attachment #1: Type: text/plain, Size: 207 bytes --]
>
> Prarit, what's the latest here? The v3 patch I have from you doesn't apply to
> my tree but it looks like a good fix. Care to send me a new patch against my
> for-linus branch?
>
>
New patch.
[-- Attachment #2: upstream3.patch --]
[-- Type: text/plain, Size: 4534 bytes --]
pci_alloc_consistent/dma_alloc_coherent does not return size aligned
addresses.
>From Documentation/DMA-mapping.txt:
"pci_alloc_consistent returns two values: the virtual address which you
can use to access it from the CPU and dma_handle which you pass to the
card.
The cpu return address and the DMA bus master address are both
guaranteed to be aligned to the smallest PAGE_SIZE order which
is greater than or equal to the requested size. This invariant
exists (for example) to guarantee that if you allocate a chunk
which is smaller than or equal to 64 kilobytes, the extent of the
buffer you receive will not cross a 64K boundary."
1. Modify alloc_iommu to allow for an alignment mask
2. Modify pci_gart_simple to return size-aligned values.
3. Fix possible overflow in alloc_iommu's boundary_size calculation.
(It is possible that alloc_iommu()'s boundary_size overflows as
dma_get_seg_boundary can return 0xffffffff. In that case, further usage of
boundary_size triggers a BUG_ON() in the iommu code.)
End result: When allocating from IOMMU, pci_alloc_consistent/dma_alloc_coherent
will now return a size aligned value.
Signed-off-by: Prarit Bhargava <prarit@redhat.com>
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index 744126e..d3eb527 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -85,7 +85,8 @@ AGPEXTERN __u32 *agp_gatt_table;
static unsigned long next_bit; /* protected by iommu_bitmap_lock */
static int need_flush; /* global flush state. set for each gart wrap */
-static unsigned long alloc_iommu(struct device *dev, int size)
+static unsigned long alloc_iommu(struct device *dev, int size,
+ unsigned long mask)
{
unsigned long offset, flags;
unsigned long boundary_size;
@@ -93,16 +94,17 @@ static unsigned long alloc_iommu(struct device *dev, int size)
base_index = ALIGN(iommu_bus_base & dma_get_seg_boundary(dev),
PAGE_SIZE) >> PAGE_SHIFT;
- boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1,
+ boundary_size = ALIGN((unsigned long long)dma_get_seg_boundary(dev) + 1,
PAGE_SIZE) >> PAGE_SHIFT;
spin_lock_irqsave(&iommu_bitmap_lock, flags);
offset = iommu_area_alloc(iommu_gart_bitmap, iommu_pages, next_bit,
- size, base_index, boundary_size, 0);
+ size, base_index, boundary_size, mask);
if (offset == -1) {
need_flush = 1;
offset = iommu_area_alloc(iommu_gart_bitmap, iommu_pages, 0,
- size, base_index, boundary_size, 0);
+ size, base_index, boundary_size,
+ mask);
}
if (offset != -1) {
next_bit = offset+size;
@@ -239,10 +241,11 @@ nonforced_iommu(struct device *dev, unsigned long addr, size_t size)
* Caller needs to check if the iommu is needed and flush.
*/
static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem,
- size_t size, int dir)
+ size_t size, int dir, u64 align_mask)
{
unsigned long npages = to_pages(phys_mem, size);
- unsigned long iommu_page = alloc_iommu(dev, npages);
+ unsigned long palign_mask = align_mask >> PAGE_SHIFT;
+ unsigned long iommu_page = alloc_iommu(dev, npages, palign_mask);
int i;
if (iommu_page == -1) {
@@ -265,7 +268,7 @@ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem,
static dma_addr_t
gart_map_simple(struct device *dev, phys_addr_t paddr, size_t size, int dir)
{
- dma_addr_t map = dma_map_area(dev, paddr, size, dir);
+ dma_addr_t map = dma_map_area(dev, paddr, size, dir, size - 1);
flush_gart();
@@ -284,7 +287,8 @@ gart_map_single(struct device *dev, phys_addr_t paddr, size_t size, int dir)
if (!need_iommu(dev, paddr, size))
return paddr;
- bus = gart_map_simple(dev, paddr, size, dir);
+ bus = dma_map_area(dev, paddr, size, dir, 0);
+ flush_gart();
return bus;
}
@@ -343,7 +347,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
unsigned long addr = sg_phys(s);
if (nonforced_iommu(dev, addr, s->length)) {
- addr = dma_map_area(dev, addr, s->length, dir);
+ addr = dma_map_area(dev, addr, s->length, dir, 0);
if (addr == bad_dma_address) {
if (i > 0)
gart_unmap_sg(dev, sg, i, dir);
@@ -365,7 +369,7 @@ static int __dma_map_cont(struct device *dev, struct scatterlist *start,
int nelems, struct scatterlist *sout,
unsigned long pages)
{
- unsigned long iommu_start = alloc_iommu(dev, pages);
+ unsigned long iommu_start = alloc_iommu(dev, pages, 0);
unsigned long iommu_page = iommu_start;
struct scatterlist *s;
int i;
next prev parent reply other threads:[~2008-07-29 14:24 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-07-23 11:19 [PATCH]: PCI: GART iommu alignment fixes [v2] Prarit Bhargava
2008-07-23 22:10 ` Joerg Roedel
2008-07-23 23:14 ` FUJITA Tomonori
2008-07-23 23:47 ` Prarit Bhargava
2008-07-24 7:46 ` Joerg Roedel
2008-07-24 10:09 ` Prarit Bhargava
2008-07-24 10:34 ` FUJITA Tomonori
2008-07-24 12:37 ` Joerg Roedel
2008-07-24 12:49 ` Prarit Bhargava
2008-07-24 13:32 ` FUJITA Tomonori
2008-07-24 14:31 ` Prarit Bhargava
2008-07-24 14:40 ` FUJITA Tomonori
2008-07-24 15:13 ` Prarit Bhargava
2008-07-24 14:45 ` Prarit Bhargava
2008-07-28 22:23 ` Jesse Barnes
2008-07-29 14:24 ` Prarit Bhargava [this message]
2008-07-29 17:08 ` Jesse Barnes
2008-07-30 0:43 ` FUJITA Tomonori
2008-08-06 12:29 ` Prarit Bhargava
2008-08-06 13:23 ` Prarit Bhargava
2008-08-06 13:35 ` FUJITA Tomonori
2008-08-06 14:32 ` Prarit Bhargava
2008-08-07 17:03 ` Jesse Barnes
2008-08-07 17:41 ` Prarit Bhargava
2008-08-08 7:12 ` Muli Ben-Yehuda
2008-08-08 15:18 ` Prarit Bhargava
2008-08-08 16:15 ` Jesse Barnes
2008-08-08 21:13 ` FUJITA Tomonori
2008-08-09 1:40 ` Prarit Bhargava
2008-08-09 3:50 ` FUJITA Tomonori
2008-08-15 16:16 ` Ingo Molnar
2008-08-15 18:00 ` Ingo Molnar
2008-08-15 20:39 ` Prarit Bhargava
2008-08-15 21:20 ` Ingo Molnar
2008-08-16 1:15 ` FUJITA Tomonori
2008-08-17 12:56 ` Ingo Molnar
2008-08-17 15:36 ` FUJITA Tomonori
2008-08-17 15:42 ` Ingo Molnar
2008-08-17 15:48 ` FUJITA Tomonori
2008-08-17 15:54 ` FUJITA Tomonori
2008-08-07 17:45 ` Prarit Bhargava
2008-07-23 23:23 ` FUJITA Tomonori
2008-07-23 23:24 ` Prarit Bhargava
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=488F2819.2090303@redhat.com \
--to=prarit@redhat.com \
--cc=fujita.tomonori@lab.ntt.co.jp \
--cc=jbarnes@virtuousgeek.org \
--cc=joro@8bytes.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.