mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	drm/tegra: gem: Fix CPU-cache maintenance for BO's allocated using get_pages()
The allocated pages need to be invalidated in CPU caches. On ARM32 the
DMA_BIDIRECTIONAL flag only ensures that data is written-back to DRAM and
the data stays in CPU cache lines. While the DMA_FROM_DEVICE flag ensures
that the corresponding CPU cache lines are getting invalidated and nothing
more, that's exactly what is needed for a newly allocated pages.
This fixes randomly failing rendercheck tests on Tegra30 using the
Opentegra driver for tests that use small-sized pixmaps (10x10 and less,
i.e. 1-2 memory pages) because apparently CPU reads out stale data from
caches and/or that data is getting evicted to DRAM at the time of HW job
execution.
Fixes: bd43c9f0fa ("drm/tegra: gem: Map pages via the DMA API")
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
			
			
This commit is contained in:
		
							parent
							
								
									11c632e1cf
								
							
						
					
					
						commit
						61b51fb51c
					
				
					 1 changed files with 2 additions and 2 deletions
				
			
		| 
						 | 
					@ -204,7 +204,7 @@ static void tegra_bo_free(struct drm_device *drm, struct tegra_bo *bo)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (bo->pages) {
 | 
						if (bo->pages) {
 | 
				
			||||||
		dma_unmap_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents,
 | 
							dma_unmap_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents,
 | 
				
			||||||
			     DMA_BIDIRECTIONAL);
 | 
								     DMA_FROM_DEVICE);
 | 
				
			||||||
		drm_gem_put_pages(&bo->gem, bo->pages, true, true);
 | 
							drm_gem_put_pages(&bo->gem, bo->pages, true, true);
 | 
				
			||||||
		sg_free_table(bo->sgt);
 | 
							sg_free_table(bo->sgt);
 | 
				
			||||||
		kfree(bo->sgt);
 | 
							kfree(bo->sgt);
 | 
				
			||||||
| 
						 | 
					@ -230,7 +230,7 @@ static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = dma_map_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents,
 | 
						err = dma_map_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents,
 | 
				
			||||||
			 DMA_BIDIRECTIONAL);
 | 
								 DMA_FROM_DEVICE);
 | 
				
			||||||
	if (err == 0) {
 | 
						if (err == 0) {
 | 
				
			||||||
		err = -EFAULT;
 | 
							err = -EFAULT;
 | 
				
			||||||
		goto free_sgt;
 | 
							goto free_sgt;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue