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