ttm dma allocator issue ?
Konrad Rzeszutek Wilk
konrad.wilk at oracle.com
Mon Dec 12 09:37:43 PST 2011
> > Any ideas ?
>
> The only way to do that would be to modify the 'struct dma_page' vaddr and dma
> variables from what they had in __ttm_dma_alloc_page. But I am not seeing any
> willfull modifications. We do pass in to dma_free_coherent the _same_ values!
>
>
> Hm, it might be worth adding in the 'struct dma_page' a 'virt_to_phys' value
> (which is what the DMA debug API uses to check), and see we get inconsitent
> values _before_ we call the DMA debug API. This is rather to double check
> the DMA API debug API. I am going to try something like this (not compile tested at all):
This one is compile tested :-)
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
index 6678abc..659b0ee 100644
--- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
+++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
@@ -32,7 +32,7 @@
* - Tracks whether the page is UC, WB or cached (and reverts to WB
* when freed).
*/
-
+#define DEBUG 1
#include <linux/dma-mapping.h>
#include <linux/list.h>
#include <linux/seq_file.h> /* for seq_printf */
@@ -127,6 +127,7 @@ struct dma_page {
void *vaddr;
struct page *p;
dma_addr_t dma;
+ void *phys; /* Based on virt_to_phys so not really bus addr */
};
/*
@@ -330,6 +331,11 @@ static int ttm_set_pages_caching(struct dma_pool *pool,
static void __ttm_dma_free_page(struct dma_pool *pool, struct dma_page *d_page)
{
dma_addr_t dma = d_page->dma;
+
+ WARN(virt_to_phys(d_page->vaddr) != d_page->phys,
+ "We saved 0x%lx, but now we get 0x%lx!?\n",
+ (unsigned long)d_page->phys, (unsigned long)virt_to_phys(d_page->vaddr));
+
dma_free_coherent(pool->dev, pool->size, d_page->vaddr, dma);
kfree(d_page);
@@ -346,8 +352,10 @@ static struct dma_page *__ttm_dma_alloc_page(struct dma_pool *pool)
d_page->vaddr = dma_alloc_coherent(pool->dev, pool->size,
&d_page->dma,
pool->gfp_flags);
- if (d_page->vaddr)
+ if (d_page->vaddr) {
d_page->p = virt_to_page(d_page->vaddr);
+ d_page->phys = virt_to_phys(d_page->vaddr);
+ }
else {
kfree(d_page);
d_page = NULL;
More information about the dri-devel
mailing list