drm/i915/chv: Flush caches when programming page tables
authorRafael Barbalho <rafael.barbalho@intel.com>
Wed, 9 Apr 2014 10:28:02 +0000 (13:28 +0300)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 6 May 2014 16:30:08 +0000 (18:30 +0200)
Page table updates were getting stuck in the CPU cache on chv causing
spurious page faults and strange behaviour.

Signed-off-by: Rafael Barbalho <rafael.barbalho@intel.com>
[vsyrjala: Add !HAS_LLC checks]
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_gem_gtt.c

index 836c8b6391c2cea799e85ac45de157ff771915d4..1827b4b349a1a6a8f70d44b743b1c75867aba51e 100644 (file)
@@ -276,6 +276,8 @@ static void gen8_ppgtt_clear_range(struct i915_address_space *vm,
                        num_entries--;
                }
 
+               if (!HAS_LLC(ppgtt->base.dev))
+                       drm_clflush_virt_range(pt_vaddr, PAGE_SIZE);
                kunmap_atomic(pt_vaddr);
 
                pte = 0;
@@ -312,6 +314,8 @@ static void gen8_ppgtt_insert_entries(struct i915_address_space *vm,
                        gen8_pte_encode(sg_page_iter_dma_address(&sg_iter),
                                        cache_level, true);
                if (++pte == GEN8_PTES_PER_PAGE) {
+                       if (!HAS_LLC(ppgtt->base.dev))
+                               drm_clflush_virt_range(pt_vaddr, PAGE_SIZE);
                        kunmap_atomic(pt_vaddr);
                        pt_vaddr = NULL;
                        if (++pde == GEN8_PDES_PER_PAGE) {
@@ -321,8 +325,11 @@ static void gen8_ppgtt_insert_entries(struct i915_address_space *vm,
                        pte = 0;
                }
        }
-       if (pt_vaddr)
+       if (pt_vaddr) {
+               if (!HAS_LLC(ppgtt->base.dev))
+                       drm_clflush_virt_range(pt_vaddr, PAGE_SIZE);
                kunmap_atomic(pt_vaddr);
+       }
 }
 
 static void gen8_free_page_tables(struct page **pt_pages)
@@ -585,6 +592,8 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, uint64_t size)
                        pd_vaddr[j] = gen8_pde_encode(ppgtt->base.dev, addr,
                                                      I915_CACHE_LLC);
                }
+               if (!HAS_LLC(ppgtt->base.dev))
+                       drm_clflush_virt_range(pd_vaddr, PAGE_SIZE);
                kunmap_atomic(pd_vaddr);
        }