[PATCH 13/20] drm/i915/gtt: Introduce copy_page_dma and copy_px

Mika Kuoppala
2015-05-21T14:38:25Z

Every time we allocate page structure, we fill it out
it to point into lower level scratch structure. But
as we have already setup scratch page directory and
scratch page table in when ppgtt was initialized, take
advantage of that and do a page copy from those.

Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
---
drivers/gpu/drm/i915/i915_gem_gtt.c | 61 +++++++++++++++++++++++++------------
1 file changed, 41 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 3d94ad8..fa253cd 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -335,16 +335,34 @@ static void *kmap_page_dma(struct i915_page_dma *p)
return kmap_atomic(p->page);
}

-static void kunmap_page_dma(struct drm_device *dev, void *vaddr)
+static void kunmap_page_dma(struct drm_device *dev, void *vaddr, bool dirty)
{
- if (!HAS_LLC(dev))
+ if (dirty && !HAS_LLC(dev))
drm_clflush_virt_range(vaddr, PAGE_SIZE);

kunmap_atomic(vaddr);
}

#define kmap_px(px) kmap_page_dma(&(px)->base)
-#define kunmap_px(ppgtt, vaddr) kunmap_page_dma((ppgtt)->base.dev, (vaddr));
+#define kunmap_px(ppgtt, vaddr) kunmap_page_dma((ppgtt)->base.dev, (vaddr), true);
+
+#define copy_px(ppgtt, to, from) \
+ copy_page_dma((ppgtt)->base.dev, &(to)->base, &(from)->base)
+
+static void copy_page_dma(struct drm_device *dev,
+ struct i915_page_dma *to,
+ struct i915_page_dma *from)
+{
+ void *dst, *src;
+
+ src = kmap_page_dma(from);
+ dst = kmap_page_dma(to);
+
+ copy_page(dst, src);
+
+ kunmap_page_dma(dev, dst, true);
+ kunmap_page_dma(dev, src, false);
+}

static void fill_page_dma(struct drm_device *dev, struct i915_page_dma *p,
const uint64_t val)
@@ -355,7 +373,7 @@ static void fill_page_dma(struct drm_device *dev, struct i915_page_dma *p,
for (i = 0; i < 512; i++)
vaddr[i] = val;

- kunmap_page_dma(dev, vaddr);
+ kunmap_page_dma(dev, vaddr, true);
}

static void fill_page_dma_32(struct drm_device *dev, struct i915_page_dma *p,
@@ -374,15 +392,16 @@ static void free_pt(struct drm_device *dev, struct i915_page_table *pt)
kfree(pt);
}

-static void gen8_initialize_pt(struct i915_address_space *vm,
- struct i915_page_table *pt)
+static void gen8_setup_scratch_pt(struct i915_address_space *vm)
{
+ struct i915_hw_ppgtt *ppgtt =
+ container_of(vm, struct i915_hw_ppgtt, base);
gen8_pte_t scratch_pte;

scratch_pte = gen8_pte_encode(vm->scratch.addr,
I915_CACHE_LLC, true);

- fill_page_dma(vm->dev, &pt->base, scratch_pte);
+ fill_page_dma(vm->dev, &ppgtt->scratch_pt->base, scratch_pte);
}

static struct i915_page_table *alloc_pt(struct drm_device *dev)
@@ -600,8 +619,7 @@ static void __gen8_do_map_pt(gen8_pde_t * const pde,
*pde = entry;
}

-static void gen8_initialize_pd(struct i915_address_space *vm,
- struct i915_page_directory *pd)
+static void gen8_setup_scratch_pd(struct i915_address_space *vm)
{
struct i915_hw_ppgtt *ppgtt =
container_of(vm, struct i915_hw_ppgtt, base);
@@ -610,7 +628,7 @@ static void gen8_initialize_pd(struct i915_address_space *vm,
scratch_pde = gen8_pde_encode(vm->dev, ppgtt->scratch_pt->base.daddr,
I915_CACHE_LLC);

- fill_page_dma(vm->dev, &pd->base, scratch_pde);
+ fill_page_dma(vm->dev, &ppgtt->scratch_pd->base, scratch_pde);
}

static void gen8_free_page_tables(struct i915_page_directory *pd, struct drm_device *dev)
@@ -688,7 +706,8 @@ static int gen8_ppgtt_alloc_pagetabs(struct i915_hw_ppgtt *ppgtt,
if (IS_ERR(pt))
goto unwind_out;

- gen8_initialize_pt(&ppgtt->base, pt);
+ copy_px(ppgtt, pt, ppgtt->scratch_pt);
+
pd->page_table[pde] = pt;
set_bit(pde, new_pts);
}
@@ -746,7 +765,8 @@ static int gen8_ppgtt_alloc_page_directories(struct i915_hw_ppgtt *ppgtt,
if (IS_ERR(pd))
goto unwind_out;

- gen8_initialize_pd(&ppgtt->base, pd);
+ copy_px(ppgtt, pd, ppgtt->scratch_pd);
+
pdp->page_directory[pdpe] = pd;
set_bit(pdpe, new_pds);
}
@@ -937,8 +957,8 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
if (IS_ERR(ppgtt->scratch_pd))
return PTR_ERR(ppgtt->scratch_pd);

- gen8_initialize_pt(&ppgtt->base, ppgtt->scratch_pt);
- gen8_initialize_pd(&ppgtt->base, ppgtt->scratch_pd);
+ gen8_setup_scratch_pt(&ppgtt->base);
+ gen8_setup_scratch_pd(&ppgtt->base);

ppgtt->base.start = 0;
ppgtt->base.total = 1ULL << 32;
@@ -1251,17 +1271,18 @@ static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
kunmap_px(ppgtt, pt_vaddr);
}

-static void gen6_initialize_pt(struct i915_address_space *vm,
- struct i915_page_table *pt)
+static void gen6_setup_scratch_pt(struct i915_address_space *vm)
{
+ struct i915_hw_ppgtt *ppgtt =
+ container_of(vm, struct i915_hw_ppgtt, base);
gen6_pte_t scratch_pte;

WARN_ON(vm->scratch.addr == 0);

scratch_pte = vm->pte_encode(vm->scratch.addr,
- I915_CACHE_LLC, true, 0);
+ I915_CACHE_LLC, true, 0);

- fill_page_dma_32(vm->dev, &pt->base, scratch_pte);
+ fill_page_dma_32(vm->dev, &ppgtt->scratch_pt->base, scratch_pte);
}

static int gen6_alloc_va_range(struct i915_address_space *vm,
@@ -1305,7 +1326,7 @@ static int gen6_alloc_va_range(struct i915_address_space *vm,
goto unwind_out;
}

- gen6_initialize_pt(vm, pt);
+ copy_px(ppgtt, pt, ppgtt->scratch_pt);

ppgtt->pd.page_table[pde] = pt;
set_bit(pde, new_page_tables);
@@ -1388,7 +1409,7 @@ static int gen6_ppgtt_allocate_page_directories(struct i915_hw_ppgtt *ppgtt)
if (IS_ERR(ppgtt->scratch_pt))
return PTR_ERR(ppgtt->scratch_pt);

- gen6_initialize_pt(&ppgtt->base, ppgtt->scratch_pt);
+ gen6_setup_scratch_pt(&ppgtt->base);

alloc:
ret = drm_mm_insert_node_in_range_generic(&dev_priv->gtt.base.mm,