Message ID | 20180925193714.25280-6-ville.syrjala@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/i915: GTT remapping for display | expand |
Quoting Ville Syrjala (2018-09-25 20:37:11) > From: Ville Syrjälä <ville.syrjala@linux.intel.com> > > Add a live selftest to excercise rotated/remapped vmas. We simply > write through the rotated/remapped vma, and confirm that the data > appears in the right page when read through the normal vma. > > Not sure what the fallout of making all rotated/remapped vmas > mappable/fenceable would be, hence I just hacked it in the test. Fair enough. This test by itself is not enough to prove fencing works (it should be perfectly happy) and certainly doesn't exercise any other code that doesn't expect a fence :) > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > --- > .../gpu/drm/i915/selftests/i915_live_selftests.h | 1 + > drivers/gpu/drm/i915/selftests/i915_vma.c | 136 +++++++++++++++++++++ > 2 files changed, 137 insertions(+) > > diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h > index a15713cae3b3..095e25e92a36 100644 > --- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h > +++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h > @@ -15,6 +15,7 @@ selftest(workarounds, intel_workarounds_live_selftests) > selftest(requests, i915_request_live_selftests) > selftest(objects, i915_gem_object_live_selftests) > selftest(dmabuf, i915_gem_dmabuf_live_selftests) > +selftest(vma, i915_vma_live_selftests) > selftest(coherency, i915_gem_coherency_live_selftests) > selftest(gtt, i915_gem_gtt_live_selftests) > selftest(gem, i915_gem_live_selftests) > diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c > index 6e84e5cc93a0..e0e4d4578c4d 100644 > --- a/drivers/gpu/drm/i915/selftests/i915_vma.c > +++ b/drivers/gpu/drm/i915/selftests/i915_vma.c > @@ -797,3 +797,139 @@ int i915_vma_mock_selftests(void) > return err; > } > > +static int igt_vma_remapped_gtt(void *arg) > +{ > + struct drm_i915_private *i915 = arg; > + const struct intel_remapped_plane_info planes[] = { > + { .width = 1, .height = 1, .stride = 1 }, > + { .width = 2, .height = 2, .stride = 2 }, > + { .width = 4, .height = 4, .stride = 4 }, > + { .width = 8, .height = 8, .stride = 8 }, > + > + { .width = 3, .height = 5, .stride = 3 }, > + { .width = 3, .height = 5, .stride = 4 }, > + { .width = 3, .height = 5, .stride = 5 }, > + > + { .width = 5, .height = 3, .stride = 5 }, > + { .width = 5, .height = 3, .stride = 7 }, > + { .width = 5, .height = 3, .stride = 9 }, > + > + { .width = 4, .height = 6, .stride = 6 }, > + { .width = 6, .height = 4, .stride = 6 }, > + { } > + }, *p; > + enum i915_ggtt_view_type types[] = { > + I915_GGTT_VIEW_ROTATED, > + I915_GGTT_VIEW_REMAPPED, > + 0, > + }, *t; > + struct drm_i915_gem_object *obj; > + int err = 0; > + > + obj = i915_gem_object_create_internal(i915, 10 * 10 * PAGE_SIZE); > + if (IS_ERR(obj)) > + return PTR_ERR(obj); > + > + mutex_lock(&i915->drm.struct_mutex); Looks like it will require intel_runtime_pm_get(i915); Memory says iomap expects the caller to manage the rpm wakeref. Lgtm, add the rpm wakeref and Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> -Chris
Quoting Ville Syrjala (2018-09-25 20:37:11) > From: Ville Syrjälä <ville.syrjala@linux.intel.com> > > Add a live selftest to excercise rotated/remapped vmas. We simply > write through the rotated/remapped vma, and confirm that the data > appears in the right page when read through the normal vma. > > Not sure what the fallout of making all rotated/remapped vmas > mappable/fenceable would be, hence I just hacked it in the test. > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > --- > .../gpu/drm/i915/selftests/i915_live_selftests.h | 1 + > drivers/gpu/drm/i915/selftests/i915_vma.c | 136 +++++++++++++++++++++ > 2 files changed, 137 insertions(+) > > diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h > index a15713cae3b3..095e25e92a36 100644 > --- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h > +++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h > @@ -15,6 +15,7 @@ selftest(workarounds, intel_workarounds_live_selftests) > selftest(requests, i915_request_live_selftests) > selftest(objects, i915_gem_object_live_selftests) > selftest(dmabuf, i915_gem_dmabuf_live_selftests) > +selftest(vma, i915_vma_live_selftests) > selftest(coherency, i915_gem_coherency_live_selftests) > selftest(gtt, i915_gem_gtt_live_selftests) > selftest(gem, i915_gem_live_selftests) > diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c > index 6e84e5cc93a0..e0e4d4578c4d 100644 > --- a/drivers/gpu/drm/i915/selftests/i915_vma.c > +++ b/drivers/gpu/drm/i915/selftests/i915_vma.c > @@ -797,3 +797,139 @@ int i915_vma_mock_selftests(void) > return err; > } > > +static int igt_vma_remapped_gtt(void *arg) > +{ > + struct drm_i915_private *i915 = arg; > + const struct intel_remapped_plane_info planes[] = { > + { .width = 1, .height = 1, .stride = 1 }, > + { .width = 2, .height = 2, .stride = 2 }, > + { .width = 4, .height = 4, .stride = 4 }, > + { .width = 8, .height = 8, .stride = 8 }, > + > + { .width = 3, .height = 5, .stride = 3 }, > + { .width = 3, .height = 5, .stride = 4 }, > + { .width = 3, .height = 5, .stride = 5 }, > + > + { .width = 5, .height = 3, .stride = 5 }, > + { .width = 5, .height = 3, .stride = 7 }, > + { .width = 5, .height = 3, .stride = 9 }, > + > + { .width = 4, .height = 6, .stride = 6 }, > + { .width = 6, .height = 4, .stride = 6 }, > + { } > + }, *p; > + enum i915_ggtt_view_type types[] = { > + I915_GGTT_VIEW_ROTATED, > + I915_GGTT_VIEW_REMAPPED, > + 0, > + }, *t; > + struct drm_i915_gem_object *obj; > + int err = 0; > + > + obj = i915_gem_object_create_internal(i915, 10 * 10 * PAGE_SIZE); > + if (IS_ERR(obj)) > + return PTR_ERR(obj); > + > + mutex_lock(&i915->drm.struct_mutex); > + > + for (t = types; *t; t++) { > + for (p = planes; p->width; p++) { > + struct i915_ggtt_view view = { > + .type = *t, > + .rotated.plane[0] = *p, > + }; > + struct i915_vma *vma; > + u32 __iomem *map; > + unsigned int x, y; > + int err; > + > + err = i915_gem_object_set_to_gtt_domain(obj, true); > + if (err) > + goto out; > + > + vma = i915_gem_object_ggtt_pin(obj, &view, 0, 0, PIN_MAPPABLE); Ok. Code needs a little more help to allow PIN_MAPPABLE on unfenceable vma. Personally, I'd just kill the exception from __i915_vma_set_map_and_fenceable(). Nobody actually grabs the fence for remapped vma afaict, so we shouldn't end with a wasted fence. > + if (IS_ERR(vma)) { > + err = PTR_ERR(vma); > + goto out; > + } Hmm, I guess we might need a GEM_BUG_ON(vma->view.type != *t); and co > + > + /* kludge */ > + vma->flags |= I915_VMA_CAN_FENCE; > + > + map = i915_vma_pin_iomap(vma); > + i915_vma_unpin(vma); > + if (IS_ERR(map)) { > + err = PTR_ERR(map); > + goto out; > + } > + > + for (y = 0 ; y < p->height; y++) { > + for (x = 0 ; x < p->width; x++) { > + unsigned int offset; > + u32 val = y << 16 | x; > + > + if (*t == I915_GGTT_VIEW_ROTATED) > + offset = (x * p->height + y) * PAGE_SIZE; > + else > + offset = (y * p->width + x) * PAGE_SIZE; > + > + iowrite32(val, &map[offset / sizeof(*map)]); > + } > + } > + > + i915_vma_unpin_iomap(vma); > + > + vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, PIN_MAPPABLE); > + if (IS_ERR(vma)) { > + err = PTR_ERR(vma); > + goto out; > + } GEM_BUG_ON(vma->view.type); -Chris
On Tue, Sep 25, 2018 at 09:40:30PM +0100, Chris Wilson wrote: > Quoting Ville Syrjala (2018-09-25 20:37:11) > > From: Ville Syrjälä <ville.syrjala@linux.intel.com> > > > > Add a live selftest to excercise rotated/remapped vmas. We simply > > write through the rotated/remapped vma, and confirm that the data > > appears in the right page when read through the normal vma. > > > > Not sure what the fallout of making all rotated/remapped vmas > > mappable/fenceable would be, hence I just hacked it in the test. > > > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > > --- > > .../gpu/drm/i915/selftests/i915_live_selftests.h | 1 + > > drivers/gpu/drm/i915/selftests/i915_vma.c | 136 +++++++++++++++++++++ > > 2 files changed, 137 insertions(+) > > > > diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h > > index a15713cae3b3..095e25e92a36 100644 > > --- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h > > +++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h > > @@ -15,6 +15,7 @@ selftest(workarounds, intel_workarounds_live_selftests) > > selftest(requests, i915_request_live_selftests) > > selftest(objects, i915_gem_object_live_selftests) > > selftest(dmabuf, i915_gem_dmabuf_live_selftests) > > +selftest(vma, i915_vma_live_selftests) > > selftest(coherency, i915_gem_coherency_live_selftests) > > selftest(gtt, i915_gem_gtt_live_selftests) > > selftest(gem, i915_gem_live_selftests) > > diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c > > index 6e84e5cc93a0..e0e4d4578c4d 100644 > > --- a/drivers/gpu/drm/i915/selftests/i915_vma.c > > +++ b/drivers/gpu/drm/i915/selftests/i915_vma.c > > @@ -797,3 +797,139 @@ int i915_vma_mock_selftests(void) > > return err; > > } > > > > +static int igt_vma_remapped_gtt(void *arg) > > +{ > > + struct drm_i915_private *i915 = arg; > > + const struct intel_remapped_plane_info planes[] = { > > + { .width = 1, .height = 1, .stride = 1 }, > > + { .width = 2, .height = 2, .stride = 2 }, > > + { .width = 4, .height = 4, .stride = 4 }, > > + { .width = 8, .height = 8, .stride = 8 }, > > + > > + { .width = 3, .height = 5, .stride = 3 }, > > + { .width = 3, .height = 5, .stride = 4 }, > > + { .width = 3, .height = 5, .stride = 5 }, > > + > > + { .width = 5, .height = 3, .stride = 5 }, > > + { .width = 5, .height = 3, .stride = 7 }, > > + { .width = 5, .height = 3, .stride = 9 }, > > + > > + { .width = 4, .height = 6, .stride = 6 }, > > + { .width = 6, .height = 4, .stride = 6 }, > > + { } > > + }, *p; > > + enum i915_ggtt_view_type types[] = { > > + I915_GGTT_VIEW_ROTATED, > > + I915_GGTT_VIEW_REMAPPED, > > + 0, > > + }, *t; > > + struct drm_i915_gem_object *obj; > > + int err = 0; > > + > > + obj = i915_gem_object_create_internal(i915, 10 * 10 * PAGE_SIZE); > > + if (IS_ERR(obj)) > > + return PTR_ERR(obj); > > + > > + mutex_lock(&i915->drm.struct_mutex); > > + > > + for (t = types; *t; t++) { > > + for (p = planes; p->width; p++) { > > + struct i915_ggtt_view view = { > > + .type = *t, > > + .rotated.plane[0] = *p, > > + }; > > + struct i915_vma *vma; > > + u32 __iomem *map; > > + unsigned int x, y; > > + int err; > > + > > + err = i915_gem_object_set_to_gtt_domain(obj, true); > > + if (err) > > + goto out; > > + > > + vma = i915_gem_object_ggtt_pin(obj, &view, 0, 0, PIN_MAPPABLE); > > Ok. Code needs a little more help to allow PIN_MAPPABLE on unfenceable > vma. Personally, I'd just kill the exception from > __i915_vma_set_map_and_fenceable(). Nobody actually grabs the fence for > remapped vma afaict, so we shouldn't end with a wasted fence. I think intel_pin_and_fence_fb_obj() would grab one. It just checks for i915_vma_is_map_and_fenceable() currently. But we can easily avoid that by having intel_plane_uses_fence() return false for remapped/rotated vma. > > > + if (IS_ERR(vma)) { > > + err = PTR_ERR(vma); > > + goto out; > > + } > > Hmm, I guess we might need a GEM_BUG_ON(vma->view.type != *t); and co > > > + > > + /* kludge */ > > + vma->flags |= I915_VMA_CAN_FENCE; > > + > > + map = i915_vma_pin_iomap(vma); > > + i915_vma_unpin(vma); > > + if (IS_ERR(map)) { > > + err = PTR_ERR(map); > > + goto out; > > + } > > + > > + for (y = 0 ; y < p->height; y++) { > > + for (x = 0 ; x < p->width; x++) { > > + unsigned int offset; > > + u32 val = y << 16 | x; > > + > > + if (*t == I915_GGTT_VIEW_ROTATED) > > + offset = (x * p->height + y) * PAGE_SIZE; > > + else > > + offset = (y * p->width + x) * PAGE_SIZE; > > + > > + iowrite32(val, &map[offset / sizeof(*map)]); > > + } > > + } > > + > > + i915_vma_unpin_iomap(vma); > > + > > + vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, PIN_MAPPABLE); > > + if (IS_ERR(vma)) { > > + err = PTR_ERR(vma); > > + goto out; > > + } > > GEM_BUG_ON(vma->view.type); > -Chris
diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h index a15713cae3b3..095e25e92a36 100644 --- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h +++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h @@ -15,6 +15,7 @@ selftest(workarounds, intel_workarounds_live_selftests) selftest(requests, i915_request_live_selftests) selftest(objects, i915_gem_object_live_selftests) selftest(dmabuf, i915_gem_dmabuf_live_selftests) +selftest(vma, i915_vma_live_selftests) selftest(coherency, i915_gem_coherency_live_selftests) selftest(gtt, i915_gem_gtt_live_selftests) selftest(gem, i915_gem_live_selftests) diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c index 6e84e5cc93a0..e0e4d4578c4d 100644 --- a/drivers/gpu/drm/i915/selftests/i915_vma.c +++ b/drivers/gpu/drm/i915/selftests/i915_vma.c @@ -797,3 +797,139 @@ int i915_vma_mock_selftests(void) return err; } +static int igt_vma_remapped_gtt(void *arg) +{ + struct drm_i915_private *i915 = arg; + const struct intel_remapped_plane_info planes[] = { + { .width = 1, .height = 1, .stride = 1 }, + { .width = 2, .height = 2, .stride = 2 }, + { .width = 4, .height = 4, .stride = 4 }, + { .width = 8, .height = 8, .stride = 8 }, + + { .width = 3, .height = 5, .stride = 3 }, + { .width = 3, .height = 5, .stride = 4 }, + { .width = 3, .height = 5, .stride = 5 }, + + { .width = 5, .height = 3, .stride = 5 }, + { .width = 5, .height = 3, .stride = 7 }, + { .width = 5, .height = 3, .stride = 9 }, + + { .width = 4, .height = 6, .stride = 6 }, + { .width = 6, .height = 4, .stride = 6 }, + { } + }, *p; + enum i915_ggtt_view_type types[] = { + I915_GGTT_VIEW_ROTATED, + I915_GGTT_VIEW_REMAPPED, + 0, + }, *t; + struct drm_i915_gem_object *obj; + int err = 0; + + obj = i915_gem_object_create_internal(i915, 10 * 10 * PAGE_SIZE); + if (IS_ERR(obj)) + return PTR_ERR(obj); + + mutex_lock(&i915->drm.struct_mutex); + + for (t = types; *t; t++) { + for (p = planes; p->width; p++) { + struct i915_ggtt_view view = { + .type = *t, + .rotated.plane[0] = *p, + }; + struct i915_vma *vma; + u32 __iomem *map; + unsigned int x, y; + int err; + + err = i915_gem_object_set_to_gtt_domain(obj, true); + if (err) + goto out; + + vma = i915_gem_object_ggtt_pin(obj, &view, 0, 0, PIN_MAPPABLE); + if (IS_ERR(vma)) { + err = PTR_ERR(vma); + goto out; + } + + /* kludge */ + vma->flags |= I915_VMA_CAN_FENCE; + + map = i915_vma_pin_iomap(vma); + i915_vma_unpin(vma); + if (IS_ERR(map)) { + err = PTR_ERR(map); + goto out; + } + + for (y = 0 ; y < p->height; y++) { + for (x = 0 ; x < p->width; x++) { + unsigned int offset; + u32 val = y << 16 | x; + + if (*t == I915_GGTT_VIEW_ROTATED) + offset = (x * p->height + y) * PAGE_SIZE; + else + offset = (y * p->width + x) * PAGE_SIZE; + + iowrite32(val, &map[offset / sizeof(*map)]); + } + } + + i915_vma_unpin_iomap(vma); + + vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, PIN_MAPPABLE); + if (IS_ERR(vma)) { + err = PTR_ERR(vma); + goto out; + } + + map = i915_vma_pin_iomap(vma); + i915_vma_unpin(vma); + if (IS_ERR(map)) { + err = PTR_ERR(map); + goto out; + } + + for (y = 0 ; y < p->height; y++) { + for (x = 0 ; x < p->width; x++) { + unsigned int offset, src_idx; + u32 exp = y << 16 | x; + u32 val; + + if (*t == I915_GGTT_VIEW_ROTATED) + src_idx = rotated_index(&view.rotated, 0, x, y); + else + src_idx = remapped_index(&view.remapped, 0, x, y); + offset = src_idx * PAGE_SIZE; + + val = ioread32(&map[offset / sizeof(*map)]); + if (val != exp) { + pr_err("%s VMA write test failed, expected 0x%x, found 0x%x\n", + *t == I915_GGTT_VIEW_ROTATED ? "Rotated" : "Remapped", + val, exp); + i915_vma_unpin_iomap(vma); + goto out; + } + } + } + i915_vma_unpin_iomap(vma); + } + } + +out: + mutex_unlock(&i915->drm.struct_mutex); + i915_gem_object_put(obj); + + return err; +} + +int i915_vma_live_selftests(struct drm_i915_private *i915) +{ + static const struct i915_subtest tests[] = { + SUBTEST(igt_vma_remapped_gtt), + }; + + return i915_subtests(tests, i915); +}