diff mbox series

[v3,5/8] drm/i915/selftests: Add live vma selftest

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

Commit Message

Ville Syrjala Sept. 25, 2018, 7:37 p.m. UTC
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(+)

Comments

Chris Wilson Sept. 25, 2018, 8:19 p.m. UTC | #1
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
Chris Wilson Sept. 25, 2018, 8:40 p.m. UTC | #2
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
Ville Syrjala Sept. 26, 2018, 9:33 a.m. UTC | #3
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 mbox series

Patch

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);
+}