All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/8] drm/i915: GTT remapping for display
@ 2018-09-25 19:37 Ville Syrjala
  2018-09-25 19:37 ` [PATCH v3 1/8] drm/i915: Make sure fb gtt offsets stay within 32bits Ville Syrjala
                   ` (16 more replies)
  0 siblings, 17 replies; 62+ messages in thread
From: Ville Syrjala @ 2018-09-25 19:37 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Another gtt remapping posting.

Changes since the last time:
- split out the plane stride check function (already in)
- use add_overflows() (after massaging it a bit)
- include some selftests for the remapped/rotated vmas
- reduce the max fb size to 16kx16k on gen7+ due to mesa+glamor
  and keep it unchanged at 8kx8k on gen4+ for the same reason

Ville Syrjälä (8):
  drm/i915: Make sure fb gtt offsets stay within 32bits
  drm/i915: Decouple SKL stride units from intel_fb_stride_alignment()
  drm/i915: Add a new "remapped" gtt_view
  drm/i915/selftests: Add mock selftest for remapped vmas
  drm/i915/selftests: Add live vma selftest
  drm/i915: Overcome display engine stride limits via GTT remapping
  drm/i915: Bump gen4+ fb stride limit to 256KiB
  drm/i915: Bump gen7+ fb size limits to 16kx16k

 drivers/gpu/drm/i915/i915_debugfs.c                |  12 +
 drivers/gpu/drm/i915/i915_gem_gtt.c                |  91 +++++
 drivers/gpu/drm/i915/i915_gem_gtt.h                |  25 +-
 drivers/gpu/drm/i915/i915_utils.h                  |   8 +-
 drivers/gpu/drm/i915/i915_vma.c                    |   6 +-
 drivers/gpu/drm/i915/i915_vma.h                    |   3 +
 drivers/gpu/drm/i915/intel_display.c               | 435 ++++++++++++++++-----
 drivers/gpu/drm/i915/intel_drv.h                   |   1 +
 .../gpu/drm/i915/selftests/i915_live_selftests.h   |   1 +
 drivers/gpu/drm/i915/selftests/i915_vma.c          | 212 +++++++++-
 10 files changed, 682 insertions(+), 112 deletions(-)

-- 
2.16.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v3 1/8] drm/i915: Make sure fb gtt offsets stay within 32bits
  2018-09-25 19:37 [PATCH v3 0/8] drm/i915: GTT remapping for display Ville Syrjala
@ 2018-09-25 19:37 ` Ville Syrjala
  2018-09-25 20:29   ` Chris Wilson
  2018-10-23 16:02   ` [PATCH v4 " Ville Syrjala
  2018-09-25 19:37 ` [PATCH v3 2/8] drm/i915: Decouple SKL stride units from intel_fb_stride_alignment() Ville Syrjala
                   ` (15 subsequent siblings)
  16 siblings, 2 replies; 62+ messages in thread
From: Ville Syrjala @ 2018-09-25 19:37 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Let's try to make sure the fb offset computations never hit
an integer overflow by making sure the entire fb stays
below 32bits. framebuffer_check() in the core already does
the same check, but as it doesn't know about tiling some things
can slip through. Repeat the check in the driver with tiling
taken into account.

v2: Use add_overflows() after massaging it to work for me (Chris)

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_utils.h    |  8 ++++----
 drivers/gpu/drm/i915/intel_display.c | 18 +++++++++++++++++-
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h
index 395dd2511568..c43ec993fa90 100644
--- a/drivers/gpu/drm/i915/i915_utils.h
+++ b/drivers/gpu/drm/i915/i915_utils.h
@@ -44,13 +44,13 @@
 			     __stringify(x), (long)(x))
 
 #if defined(GCC_VERSION) && GCC_VERSION >= 70000
-#define add_overflows(A, B) \
-	__builtin_add_overflow_p((A), (B), (typeof((A) + (B)))0)
+#define add_overflows(A, B, C) \
+	__builtin_add_overflow_p((A), (B), (C))
 #else
-#define add_overflows(A, B) ({ \
+#define add_overflows(A, B, C) ({ \
 	typeof(A) a = (A); \
 	typeof(B) b = (B); \
-	a + b < a; \
+	(typeof(C))(a + b) < a; \
 })
 #endif
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 4c5c2b39e65c..a3ae24e03316 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2400,10 +2400,26 @@ static int intel_fb_offset_to_xy(int *x, int *y,
 				 int color_plane)
 {
 	struct drm_i915_private *dev_priv = to_i915(fb->dev);
+	unsigned int height;
 
 	if (fb->modifier != DRM_FORMAT_MOD_LINEAR &&
-	    fb->offsets[color_plane] % intel_tile_size(dev_priv))
+	    fb->offsets[color_plane] % intel_tile_size(dev_priv)) {
+		DRM_DEBUG_KMS("Misaligned offset 0x%08x for color plane %d\n",
+			      fb->offsets[color_plane], color_plane);
 		return -EINVAL;
+	}
+
+	height = drm_framebuffer_plane_height(fb->height, fb, color_plane);
+	height = ALIGN(height, intel_tile_height(fb, color_plane));
+
+	/* Catch potential overflows early */
+	if (add_overflows(mul_u32_u32(height, fb->pitches[color_plane]),
+			  fb->offsets[color_plane], (u32)0)) {
+		DRM_DEBUG_KMS("Bad offset 0x%08x or pitch %d for color plane %d\n",
+			      fb->offsets[color_plane], fb->pitches[color_plane],
+			      color_plane);
+		return -ERANGE;
+	}
 
 	*x = 0;
 	*y = 0;
-- 
2.16.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v3 2/8] drm/i915: Decouple SKL stride units from intel_fb_stride_alignment()
  2018-09-25 19:37 [PATCH v3 0/8] drm/i915: GTT remapping for display Ville Syrjala
  2018-09-25 19:37 ` [PATCH v3 1/8] drm/i915: Make sure fb gtt offsets stay within 32bits Ville Syrjala
@ 2018-09-25 19:37 ` Ville Syrjala
  2018-10-23 18:50   ` Chris Wilson
  2018-09-25 19:37 ` [PATCH v3 3/8] drm/i915: Add a new "remapped" gtt_view Ville Syrjala
                   ` (14 subsequent siblings)
  16 siblings, 1 reply; 62+ messages in thread
From: Ville Syrjala @ 2018-09-25 19:37 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

In the future framebuffer stride alignment requirements won't exactly
match the units in which skl+ plane stride is specified. So extract
the code for the skl+ stuff into a separate helper.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 28 +++++++++++++++++-----------
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index a3ae24e03316..1fe5cf3ed062 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3528,6 +3528,21 @@ static void skl_detach_scalers(struct intel_crtc *intel_crtc)
 	}
 }
 
+static unsigned int skl_plane_stride_mult(const struct drm_framebuffer *fb,
+					  int color_plane, unsigned int rotation)
+{
+	/*
+	 * The stride is either expressed as a multiple of 64 bytes chunks for
+	 * linear buffers or in number of tiles for tiled buffers.
+	 */
+	if (fb->modifier == DRM_FORMAT_MOD_LINEAR)
+		return 64;
+	else if (drm_rotation_90_or_270(rotation))
+		return intel_tile_height(fb, color_plane);
+	else
+		return intel_tile_width_bytes(fb, color_plane);
+}
+
 u32 skl_plane_stride(const struct intel_plane_state *plane_state,
 		     int color_plane)
 {
@@ -3538,16 +3553,7 @@ u32 skl_plane_stride(const struct intel_plane_state *plane_state,
 	if (color_plane >= fb->format->num_planes)
 		return 0;
 
-	/*
-	 * The stride is either expressed as a multiple of 64 bytes chunks for
-	 * linear buffers or in number of tiles for tiled buffers.
-	 */
-	if (drm_rotation_90_or_270(rotation))
-		stride /= intel_tile_height(fb, color_plane);
-	else
-		stride /= intel_fb_stride_alignment(fb, color_plane);
-
-	return stride;
+	return stride / skl_plane_stride_mult(fb, color_plane, rotation);
 }
 
 static u32 skl_plane_ctl_format(uint32_t pixel_format)
@@ -8897,7 +8903,7 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
 	fb->width = ((val >> 0) & 0x1fff) + 1;
 
 	val = I915_READ(PLANE_STRIDE(pipe, plane_id));
-	stride_mult = intel_fb_stride_alignment(fb, 0);
+	stride_mult = skl_plane_stride_mult(fb, 0, DRM_MODE_ROTATE_0);
 	fb->pitches[0] = (val & 0x3ff) * stride_mult;
 
 	aligned_height = intel_fb_align_height(fb, 0, fb->height);
-- 
2.16.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v3 3/8] drm/i915: Add a new "remapped" gtt_view
  2018-09-25 19:37 [PATCH v3 0/8] drm/i915: GTT remapping for display Ville Syrjala
  2018-09-25 19:37 ` [PATCH v3 1/8] drm/i915: Make sure fb gtt offsets stay within 32bits Ville Syrjala
  2018-09-25 19:37 ` [PATCH v3 2/8] drm/i915: Decouple SKL stride units from intel_fb_stride_alignment() Ville Syrjala
@ 2018-09-25 19:37 ` Ville Syrjala
  2018-09-26  7:50   ` Tvrtko Ursulin
  2018-10-23 16:02   ` [PATCH v4 " Ville Syrjala
  2018-09-25 19:37 ` [PATCH v3 4/8] drm/i915/selftests: Add mock selftest for remapped vmas Ville Syrjala
                   ` (13 subsequent siblings)
  16 siblings, 2 replies; 62+ messages in thread
From: Ville Syrjala @ 2018-09-25 19:37 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

To overcome display engine stride limits we'll want to remap the
pages in the GTT. To that end we need a new gtt_view type which
is just like the "rotated" type except not rotated.

v2: Use intel_remapped_plane_info base type
    s/unused/unused_mbz/ (Chris)
    Separate BUILD_BUG_ON()s (Chris)
    Use I915_GTT_PAGE_SIZE (Chris)

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c       | 12 ++++
 drivers/gpu/drm/i915/i915_gem_gtt.c       | 91 +++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_gem_gtt.h       | 25 +++++++--
 drivers/gpu/drm/i915/i915_vma.c           |  6 +-
 drivers/gpu/drm/i915/i915_vma.h           |  3 +
 drivers/gpu/drm/i915/intel_display.c      | 11 ++++
 drivers/gpu/drm/i915/intel_drv.h          |  1 +
 drivers/gpu/drm/i915/selftests/i915_vma.c |  6 +-
 8 files changed, 147 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index b4744a68cd88..edb9f6f3c0cf 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -196,6 +196,18 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
 					   vma->ggtt_view.rotated.plane[1].offset);
 				break;
 
+			case I915_GGTT_VIEW_REMAPPED:
+				seq_printf(m, ", remapped [(%ux%u, stride=%u, offset=%u), (%ux%u, stride=%u, offset=%u)]",
+					   vma->ggtt_view.remapped.plane[0].width,
+					   vma->ggtt_view.remapped.plane[0].height,
+					   vma->ggtt_view.remapped.plane[0].stride,
+					   vma->ggtt_view.remapped.plane[0].offset,
+					   vma->ggtt_view.remapped.plane[1].width,
+					   vma->ggtt_view.remapped.plane[1].height,
+					   vma->ggtt_view.remapped.plane[1].stride,
+					   vma->ggtt_view.remapped.plane[1].offset);
+				break;
+
 			default:
 				MISSING_CASE(vma->ggtt_view.type);
 				break;
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index f6c7ab413081..e4d49c345c81 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -3798,6 +3798,92 @@ intel_rotate_pages(struct intel_rotation_info *rot_info,
 	return ERR_PTR(ret);
 }
 
+static struct scatterlist *
+remap_pages(const dma_addr_t *in, unsigned int offset,
+	    unsigned int width, unsigned int height,
+	    unsigned int stride,
+	    struct sg_table *st, struct scatterlist *sg)
+{
+	unsigned int column, row;
+
+	for (row = 0; row < height; row++) {
+		for (column = 0; column < width; column++) {
+			st->nents++;
+			/* We don't need the pages, but need to initialize
+			 * the entries so the sg list can be happily traversed.
+			 * The only thing we need are DMA addresses.
+			 */
+			sg_set_page(sg, NULL, I915_GTT_PAGE_SIZE, 0);
+			sg_dma_address(sg) = in[offset + column];
+			sg_dma_len(sg) = I915_GTT_PAGE_SIZE;
+			sg = sg_next(sg);
+		}
+		offset += stride;
+	}
+
+	return sg;
+}
+
+static noinline struct sg_table *
+intel_remap_pages(struct intel_remapped_info *rem_info,
+		  struct drm_i915_gem_object *obj)
+{
+	const unsigned long n_pages = obj->base.size / I915_GTT_PAGE_SIZE;
+	unsigned int size = intel_remapped_info_size(rem_info);
+	struct sgt_iter sgt_iter;
+	dma_addr_t dma_addr;
+	unsigned long i;
+	dma_addr_t *page_addr_list;
+	struct sg_table *st;
+	struct scatterlist *sg;
+	int ret = -ENOMEM;
+
+	/* Allocate a temporary list of source pages for random access. */
+	page_addr_list = kvmalloc_array(n_pages,
+					sizeof(dma_addr_t),
+					GFP_KERNEL);
+	if (!page_addr_list)
+		return ERR_PTR(ret);
+
+	/* Allocate target SG list. */
+	st = kmalloc(sizeof(*st), GFP_KERNEL);
+	if (!st)
+		goto err_st_alloc;
+
+	ret = sg_alloc_table(st, size, GFP_KERNEL);
+	if (ret)
+		goto err_sg_alloc;
+
+	/* Populate source page list from the object. */
+	i = 0;
+	for_each_sgt_dma(dma_addr, sgt_iter, obj->mm.pages)
+		page_addr_list[i++] = dma_addr;
+
+	GEM_BUG_ON(i != n_pages);
+	st->nents = 0;
+	sg = st->sgl;
+
+	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
+		sg = remap_pages(page_addr_list, rem_info->plane[i].offset,
+				 rem_info->plane[i].width, rem_info->plane[i].height,
+				 rem_info->plane[i].stride, st, sg);
+	}
+
+	kvfree(page_addr_list);
+
+	return st;
+
+err_sg_alloc:
+	kfree(st);
+err_st_alloc:
+	kvfree(page_addr_list);
+
+	DRM_DEBUG_DRIVER("Failed to create remapped mapping for object size %zu! (%ux%u tiles, %u pages)\n",
+			 obj->base.size, rem_info->plane[0].width, rem_info->plane[0].height, size);
+
+	return ERR_PTR(ret);
+}
+
 static noinline struct sg_table *
 intel_partial_pages(const struct i915_ggtt_view *view,
 		    struct drm_i915_gem_object *obj)
@@ -3874,6 +3960,11 @@ i915_get_ggtt_vma_pages(struct i915_vma *vma)
 			intel_rotate_pages(&vma->ggtt_view.rotated, vma->obj);
 		break;
 
+	case I915_GGTT_VIEW_REMAPPED:
+		vma->pages =
+			intel_remap_pages(&vma->ggtt_view.remapped, vma->obj);
+		break;
+
 	case I915_GGTT_VIEW_PARTIAL:
 		vma->pages = intel_partial_pages(&vma->ggtt_view, vma->obj);
 		break;
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 7e2af5f4f39b..69a22f57e6ca 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -160,11 +160,18 @@ typedef u64 gen8_ppgtt_pml4e_t;
 
 struct sg_table;
 
+struct intel_remapped_plane_info {
+	/* in gtt pages */
+	unsigned int width, height, stride, offset;
+} __packed;
+
+struct intel_remapped_info {
+	struct intel_remapped_plane_info plane[2];
+	unsigned int unused_mbz;
+} __packed;
+
 struct intel_rotation_info {
-	struct intel_rotation_plane_info {
-		/* tiles */
-		unsigned int width, height, stride, offset;
-	} plane[2];
+	struct intel_remapped_plane_info plane[2];
 } __packed;
 
 struct intel_partial_info {
@@ -176,12 +183,20 @@ enum i915_ggtt_view_type {
 	I915_GGTT_VIEW_NORMAL = 0,
 	I915_GGTT_VIEW_ROTATED = sizeof(struct intel_rotation_info),
 	I915_GGTT_VIEW_PARTIAL = sizeof(struct intel_partial_info),
+	I915_GGTT_VIEW_REMAPPED = sizeof(struct intel_remapped_info),
 };
 
 static inline void assert_i915_gem_gtt_types(void)
 {
 	BUILD_BUG_ON(sizeof(struct intel_rotation_info) != 8*sizeof(unsigned int));
 	BUILD_BUG_ON(sizeof(struct intel_partial_info) != sizeof(u64) + sizeof(unsigned int));
+	BUILD_BUG_ON(sizeof(struct intel_remapped_info) != 9*sizeof(unsigned int));
+
+	/* Check that rotation/remapped shares offsets for simplicity */
+	BUILD_BUG_ON(offsetof(struct intel_remapped_info, plane[0]) !=
+		     offsetof(struct intel_rotation_info, plane[0]));
+	BUILD_BUG_ON(offsetofend(struct intel_remapped_info, plane[1]) !=
+		     offsetofend(struct intel_rotation_info, plane[1]));
 
 	/* As we encode the size of each branch inside the union into its type,
 	 * we have to be careful that each branch has a unique size.
@@ -190,6 +205,7 @@ static inline void assert_i915_gem_gtt_types(void)
 	case I915_GGTT_VIEW_NORMAL:
 	case I915_GGTT_VIEW_PARTIAL:
 	case I915_GGTT_VIEW_ROTATED:
+	case I915_GGTT_VIEW_REMAPPED:
 		/* gcc complains if these are identical cases */
 		break;
 	}
@@ -201,6 +217,7 @@ struct i915_ggtt_view {
 		/* Members need to contain no holes/padding */
 		struct intel_partial_info partial;
 		struct intel_rotation_info rotated;
+		struct intel_remapped_info remapped;
 	};
 };
 
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 31efc971a3a8..1793c702ab94 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -164,6 +164,9 @@ vma_create(struct drm_i915_gem_object *obj,
 		} else if (view->type == I915_GGTT_VIEW_ROTATED) {
 			vma->size = intel_rotation_info_size(&view->rotated);
 			vma->size <<= PAGE_SHIFT;
+		} else if (view->type == I915_GGTT_VIEW_REMAPPED) {
+			vma->size = intel_remapped_info_size(&view->remapped);
+			vma->size <<= PAGE_SHIFT;
 		}
 	}
 
@@ -464,7 +467,8 @@ void __i915_vma_set_map_and_fenceable(struct i915_vma *vma)
 	 * Explicitly disable for rotated VMA since the display does not
 	 * need the fence and the VMA is not accessible to other users.
 	 */
-	if (vma->ggtt_view.type == I915_GGTT_VIEW_ROTATED)
+	if (vma->ggtt_view.type == I915_GGTT_VIEW_ROTATED ||
+	    vma->ggtt_view.type == I915_GGTT_VIEW_REMAPPED)
 		return;
 
 	fenceable = (vma->node.size >= vma->fence_size &&
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 4f7c1c7599f4..64cf029c028a 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -265,8 +265,11 @@ i915_vma_compare(struct i915_vma *vma,
 	 */
 	BUILD_BUG_ON(I915_GGTT_VIEW_NORMAL >= I915_GGTT_VIEW_PARTIAL);
 	BUILD_BUG_ON(I915_GGTT_VIEW_PARTIAL >= I915_GGTT_VIEW_ROTATED);
+	BUILD_BUG_ON(I915_GGTT_VIEW_ROTATED >= I915_GGTT_VIEW_REMAPPED);
 	BUILD_BUG_ON(offsetof(typeof(*view), rotated) !=
 		     offsetof(typeof(*view), partial));
+	BUILD_BUG_ON(offsetof(typeof(*view), rotated) !=
+		     offsetof(typeof(*view), remapped));
 	return memcmp(&vma->ggtt_view.partial, &view->partial, view->type);
 }
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 1fe5cf3ed062..4f9f519ccd46 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2006,6 +2006,17 @@ unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info
 	return size;
 }
 
+unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info)
+{
+	unsigned int size = 0;
+	int i;
+
+	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++)
+		size += rem_info->plane[i].width * rem_info->plane[i].height;
+
+	return size;
+}
+
 static void
 intel_fill_fb_ggtt_view(struct i915_ggtt_view *view,
 			const struct drm_framebuffer *fb,
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 4fcba99d12c0..a88a16b74f24 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1503,6 +1503,7 @@ unsigned int intel_fb_xy_to_linear(int x, int y,
 void intel_add_fb_offsets(int *x, int *y,
 			  const struct intel_plane_state *state, int plane);
 unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info);
+unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info);
 bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv);
 void intel_mark_busy(struct drm_i915_private *dev_priv);
 void intel_mark_idle(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c
index ffa74290e054..4fc49c27f13c 100644
--- a/drivers/gpu/drm/i915/selftests/i915_vma.c
+++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
@@ -395,8 +395,8 @@ assert_rotated(struct drm_i915_gem_object *obj,
 	return sg;
 }
 
-static unsigned int rotated_size(const struct intel_rotation_plane_info *a,
-				 const struct intel_rotation_plane_info *b)
+static unsigned int rotated_size(const struct intel_remapped_plane_info *a,
+				 const struct intel_remapped_plane_info *b)
 {
 	return a->width * a->height + b->width * b->height;
 }
@@ -406,7 +406,7 @@ static int igt_vma_rotate(void *arg)
 	struct drm_i915_private *i915 = arg;
 	struct i915_address_space *vm = &i915->ggtt.vm;
 	struct drm_i915_gem_object *obj;
-	const struct intel_rotation_plane_info planes[] = {
+	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 },
-- 
2.16.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v3 4/8] drm/i915/selftests: Add mock selftest for remapped vmas
  2018-09-25 19:37 [PATCH v3 0/8] drm/i915: GTT remapping for display Ville Syrjala
                   ` (2 preceding siblings ...)
  2018-09-25 19:37 ` [PATCH v3 3/8] drm/i915: Add a new "remapped" gtt_view Ville Syrjala
@ 2018-09-25 19:37 ` Ville Syrjala
  2018-09-25 20:22   ` Chris Wilson
  2018-10-23 16:03   ` [PATCH v4 " Ville Syrjala
  2018-09-25 19:37 ` [PATCH v3 5/8] drm/i915/selftests: Add live vma selftest Ville Syrjala
                   ` (12 subsequent siblings)
  16 siblings, 2 replies; 62+ messages in thread
From: Ville Syrjala @ 2018-09-25 19:37 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Extend the rotated vma mock selftest to cover remapped vmas as
well.

TODO: reindent the loops I guess? Left like this for now to
ease review

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/selftests/i915_vma.c | 70 ++++++++++++++++++++++++++++---
 1 file changed, 65 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c
index 4fc49c27f13c..6e84e5cc93a0 100644
--- a/drivers/gpu/drm/i915/selftests/i915_vma.c
+++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
@@ -58,7 +58,7 @@ static bool assert_vma(struct i915_vma *vma,
 static struct i915_vma *
 checked_vma_instance(struct drm_i915_gem_object *obj,
 		     struct i915_address_space *vm,
-		     struct i915_ggtt_view *view)
+		     const struct i915_ggtt_view *view)
 {
 	struct i915_vma *vma;
 	bool ok = true;
@@ -395,13 +395,63 @@ assert_rotated(struct drm_i915_gem_object *obj,
 	return sg;
 }
 
+static unsigned long remapped_index(const struct intel_remapped_info *r,
+				    unsigned int n,
+				    unsigned int x,
+				    unsigned int y)
+{
+	return (r->plane[n].stride * y +
+		r->plane[n].offset + x);
+}
+
+static struct scatterlist *
+assert_remapped(struct drm_i915_gem_object *obj,
+		const struct intel_remapped_info *r, unsigned int n,
+		struct scatterlist *sg)
+{
+	unsigned int x, y;
+
+	for (y = 0; y < r->plane[n].height; y++) {
+		for (x = 0; x < r->plane[n].width; x++) {
+			unsigned long src_idx;
+			dma_addr_t src;
+
+			if (!sg) {
+				pr_err("Invalid sg table: too short at plane %d, (%d, %d)!\n",
+				       n, x, y);
+				return ERR_PTR(-EINVAL);
+			}
+
+			src_idx = remapped_index(r, n, x, y);
+			src = i915_gem_object_get_dma_address(obj, src_idx);
+
+			if (sg_dma_len(sg) != PAGE_SIZE) {
+				pr_err("Invalid sg.length, found %d, expected %lu for remapped page (%d, %d) [src index %lu]\n",
+				       sg_dma_len(sg), PAGE_SIZE,
+				       x, y, src_idx);
+				return ERR_PTR(-EINVAL);
+			}
+
+			if (sg_dma_address(sg) != src) {
+				pr_err("Invalid address for remapped page (%d, %d) [src index %lu]\n",
+				       x, y, src_idx);
+				return ERR_PTR(-EINVAL);
+			}
+
+			sg = sg_next(sg);
+		}
+	}
+
+	return sg;
+}
+
 static unsigned int rotated_size(const struct intel_remapped_plane_info *a,
 				 const struct intel_remapped_plane_info *b)
 {
 	return a->width * a->height + b->width * b->height;
 }
 
-static int igt_vma_rotate(void *arg)
+static int igt_vma_rotate_remap(void *arg)
 {
 	struct drm_i915_private *i915 = arg;
 	struct i915_address_space *vm = &i915->ggtt.vm;
@@ -424,6 +474,11 @@ static int igt_vma_rotate(void *arg)
 		{ .width = 6, .height = 4, .stride = 6 },
 		{ }
 	}, *a, *b;
+	enum i915_ggtt_view_type types[] = {
+		I915_GGTT_VIEW_ROTATED,
+		I915_GGTT_VIEW_REMAPPED,
+		0,
+	}, *t;
 	const unsigned int max_pages = 64;
 	int err = -ENOMEM;
 
@@ -435,6 +490,7 @@ static int igt_vma_rotate(void *arg)
 	if (IS_ERR(obj))
 		goto out;
 
+	for (t = types; *t; t++) {
 	for (a = planes; a->width; a++) {
 		for (b = planes + ARRAY_SIZE(planes); b-- != planes; ) {
 			struct i915_ggtt_view view;
@@ -445,7 +501,7 @@ static int igt_vma_rotate(void *arg)
 			GEM_BUG_ON(max_offset > max_pages);
 			max_offset = max_pages - max_offset;
 
-			view.type = I915_GGTT_VIEW_ROTATED;
+			view.type = *t;
 			view.rotated.plane[0] = *a;
 			view.rotated.plane[1] = *b;
 
@@ -495,7 +551,10 @@ static int igt_vma_rotate(void *arg)
 
 					sg = vma->pages->sgl;
 					for (n = 0; n < ARRAY_SIZE(view.rotated.plane); n++) {
-						sg = assert_rotated(obj, &view.rotated, n, sg);
+						if (view.type == I915_GGTT_VIEW_ROTATED)
+							sg = assert_rotated(obj, &view.rotated, n, sg);
+						else
+							sg = assert_remapped(obj, &view.remapped, n, sg);
 						if (IS_ERR(sg)) {
 							pr_err("Inconsistent VMA pages for plane %d: [(%d, %d, %d, %d), (%d, %d, %d, %d)]\n", n,
 							       view.rotated.plane[0].width,
@@ -516,6 +575,7 @@ static int igt_vma_rotate(void *arg)
 			}
 		}
 	}
+	}
 
 out_object:
 	i915_gem_object_put(obj);
@@ -719,7 +779,7 @@ int i915_vma_mock_selftests(void)
 	static const struct i915_subtest tests[] = {
 		SUBTEST(igt_vma_create),
 		SUBTEST(igt_vma_pin1),
-		SUBTEST(igt_vma_rotate),
+		SUBTEST(igt_vma_rotate_remap),
 		SUBTEST(igt_vma_partial),
 	};
 	struct drm_i915_private *i915;
-- 
2.16.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v3 5/8] drm/i915/selftests: Add live vma selftest
  2018-09-25 19:37 [PATCH v3 0/8] drm/i915: GTT remapping for display Ville Syrjala
                   ` (3 preceding siblings ...)
  2018-09-25 19:37 ` [PATCH v3 4/8] drm/i915/selftests: Add mock selftest for remapped vmas Ville Syrjala
@ 2018-09-25 19:37 ` Ville Syrjala
  2018-09-25 20:19   ` Chris Wilson
                     ` (2 more replies)
  2018-09-25 19:37 ` [PATCH v3 6/8] drm/i915: Overcome display engine stride limits via GTT remapping Ville Syrjala
                   ` (11 subsequent siblings)
  16 siblings, 3 replies; 62+ messages in thread
From: Ville Syrjala @ 2018-09-25 19:37 UTC (permalink / raw)
  To: intel-gfx

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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v3 6/8] drm/i915: Overcome display engine stride limits via GTT remapping
  2018-09-25 19:37 [PATCH v3 0/8] drm/i915: GTT remapping for display Ville Syrjala
                   ` (4 preceding siblings ...)
  2018-09-25 19:37 ` [PATCH v3 5/8] drm/i915/selftests: Add live vma selftest Ville Syrjala
@ 2018-09-25 19:37 ` Ville Syrjala
  2018-10-23 19:16   ` Chris Wilson
  2018-09-25 19:37 ` [PATCH v3 7/8] drm/i915: Bump gen4+ fb stride limit to 256KiB Ville Syrjala
                   ` (10 subsequent siblings)
  16 siblings, 1 reply; 62+ messages in thread
From: Ville Syrjala @ 2018-09-25 19:37 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

The display engine stride limits are getting in our way. On SKL+
we are limited to 8k pixels, which is easily exceeded with three
4k displays. To overcome this limitation we can remap the pages
in the GTT to provide the display engine with a view of memory
with a smaller stride.

The code is mostly already there as We already play tricks with
the plane surface address and x/y offsets.

A few caveats apply:
* linear buffers need the fb stride to be page aligned, as
  otherwise the remapped lines wouldn't start at the same
  spot
* compressed buffers can't be remapped due to the new
  ccs hash mode causing the virtual address of the pages
  to affect the interpretation of the compressed data. IIRC
  the old hash was limited to the low 12 bits so if we were
  using that mode we could remap. As it stands we just refuse
  to remapp with compressed fbs.
* no remapping gen2/3 as we'd need a fence for the remapped
  vma, which we currently don't have. Need to deal with the
  fence POT requirements, and do something about the gen2
  gtt page size vs tile size difference

v2: Rebase due to is_ccs_modifier()
    Fix up the skl+ stride_mult mess
    memset() the gtt_view because otherwise we could leave
    junk in plane[1] when going from 2 plane to 1 plane format
v3: intel_check_plane_stride() was split out

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 347 +++++++++++++++++++++++++++--------
 1 file changed, 270 insertions(+), 77 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 4f9f519ccd46..eca873653fea 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1924,7 +1924,7 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane)
 
 	switch (fb->modifier) {
 	case DRM_FORMAT_MOD_LINEAR:
-		return cpp;
+		return intel_tile_size(dev_priv);
 	case I915_FORMAT_MOD_X_TILED:
 		if (IS_GEN2(dev_priv))
 			return 128;
@@ -1967,11 +1967,8 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane)
 static unsigned int
 intel_tile_height(const struct drm_framebuffer *fb, int color_plane)
 {
-	if (fb->modifier == DRM_FORMAT_MOD_LINEAR)
-		return 1;
-	else
-		return intel_tile_size(to_i915(fb->dev)) /
-			intel_tile_width_bytes(fb, color_plane);
+	return intel_tile_size(to_i915(fb->dev)) /
+		intel_tile_width_bytes(fb, color_plane);
 }
 
 /* Return the tile dimensions in pixel units */
@@ -2226,16 +2223,8 @@ void intel_add_fb_offsets(int *x, int *y,
 			  int color_plane)
 
 {
-	const struct intel_framebuffer *intel_fb = to_intel_framebuffer(state->base.fb);
-	unsigned int rotation = state->base.rotation;
-
-	if (drm_rotation_90_or_270(rotation)) {
-		*x += intel_fb->rotated[color_plane].x;
-		*y += intel_fb->rotated[color_plane].y;
-	} else {
-		*x += intel_fb->normal[color_plane].x;
-		*y += intel_fb->normal[color_plane].y;
-	}
+	*x += state->color_plane[color_plane].x;
+	*y += state->color_plane[color_plane].y;
 }
 
 static u32 intel_adjust_tile_offset(int *x, int *y,
@@ -2511,6 +2500,82 @@ bool is_ccs_modifier(u64 modifier)
 	       modifier == I915_FORMAT_MOD_Yf_TILED_CCS;
 }
 
+static
+u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
+			      u32 pixel_format, u64 modifier)
+{
+	struct intel_crtc *crtc;
+	struct intel_plane *plane;
+
+	/*
+	 * We assume the primary plane for pipe A has
+	 * the highest stride limits of them all.
+	 */
+	crtc = intel_get_crtc_for_pipe(dev_priv, PIPE_A);
+	plane = to_intel_plane(crtc->base.primary);
+
+	return plane->max_stride(plane, pixel_format, modifier,
+				 DRM_MODE_ROTATE_0);
+}
+
+static
+u32 intel_fb_max_stride(struct drm_i915_private *dev_priv,
+			u32 pixel_format, u64 modifier)
+{
+	return intel_plane_fb_max_stride(dev_priv, pixel_format, modifier);
+}
+
+static u32
+intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane)
+{
+	struct drm_i915_private *dev_priv = to_i915(fb->dev);
+
+	if (fb->modifier == DRM_FORMAT_MOD_LINEAR) {
+		u32 max_stride = intel_plane_fb_max_stride(dev_priv,
+							   fb->format->format,
+							   fb->modifier);
+
+		/*
+		 * To make remapping with linear generally feasible
+		 * we need the stride to be page aligned.
+		 */
+		if (fb->pitches[color_plane] > max_stride)
+			return intel_tile_size(dev_priv);
+		else
+			return 64;
+	} else {
+		return intel_tile_width_bytes(fb, color_plane);
+	}
+}
+
+static bool intel_plane_needs_remap(const struct intel_plane_state *plane_state)
+{
+	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
+	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+	const struct drm_framebuffer *fb = plane_state->base.fb;
+	unsigned int rotation = plane_state->base.rotation;
+	u32 stride, max_stride;
+
+	/* We don't want to deal with remapping with cursors */
+	if (plane->id == PLANE_CURSOR)
+		return false;
+
+	/* No fence for the remapped vma */
+	if (INTEL_GEN(dev_priv) < 4)
+		return false;
+
+	/* New CCS hash mode makes remapping impossible */
+	if (is_ccs_modifier(fb->modifier))
+		return false;
+
+	/* FIXME other color planes? */
+	stride = intel_fb_pitch(fb, 0, rotation);
+	max_stride = plane->max_stride(plane, fb->format->format,
+				       fb->modifier, rotation);
+
+	return stride > max_stride;
+}
+
 static int
 intel_fill_fb_info(struct drm_i915_private *dev_priv,
 		   struct drm_framebuffer *fb)
@@ -2676,6 +2741,182 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv,
 	return 0;
 }
 
+static void
+intel_plane_remap_gtt(struct intel_plane_state *plane_state)
+{
+	struct drm_i915_private *dev_priv =
+		to_i915(plane_state->base.plane->dev);
+	struct drm_framebuffer *fb = plane_state->base.fb;
+	struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
+	struct intel_rotation_info *info = &plane_state->view.rotated;
+	unsigned int rotation = plane_state->base.rotation;
+	int i, num_planes = fb->format->num_planes;
+	unsigned int tile_size = intel_tile_size(dev_priv);
+	unsigned int tile_width, tile_height;
+	unsigned int aligned_x, aligned_y;
+	unsigned int aligned_w, aligned_h;
+	unsigned int src_x, src_y;
+	unsigned int src_w, src_h;
+	unsigned int x, y;
+	u32 gtt_offset = 0;
+
+	memset(&plane_state->view, 0, sizeof(plane_state->view));
+	plane_state->view.type = drm_rotation_90_or_270(rotation) ?
+		I915_GGTT_VIEW_ROTATED : I915_GGTT_VIEW_REMAPPED;
+
+	src_x = plane_state->base.src.x1 >> 16;
+	src_y = plane_state->base.src.y1 >> 16;
+	src_w = drm_rect_width(&plane_state->base.src) >> 16;
+	src_h = drm_rect_height(&plane_state->base.src) >> 16;
+
+	WARN_ON(is_ccs_modifier(fb->modifier));
+
+	/* Align our viewport start to tile boundary */
+	intel_tile_dims(fb, 0, &tile_width, &tile_height);
+
+	x = src_x & (tile_width - 1);
+	y = src_y & (tile_height - 1);
+
+	aligned_x = src_x - x;
+	aligned_y = src_y - y;
+
+	aligned_w = x + src_w;
+	aligned_h = y + src_h;
+
+	/* Make src coordinates relative to the aligned viewport */
+	drm_rect_translate(&plane_state->base.src,
+			   -(aligned_x << 16), -(aligned_y << 16));
+
+	/* Rotate src coordinates to match rotated GTT view */
+	if (drm_rotation_90_or_270(rotation))
+		drm_rect_rotate(&plane_state->base.src,
+				aligned_w << 16, aligned_h << 16,
+				DRM_MODE_ROTATE_270);
+
+	for (i = 0; i < num_planes; i++) {
+		unsigned int hsub = i ? fb->format->hsub : 1;
+		unsigned int vsub = i ? fb->format->vsub : 1;
+		unsigned int cpp = fb->format->cpp[i];
+		unsigned int width, height;
+		unsigned int pitch_tiles;
+		unsigned int x, y;
+		u32 offset;
+
+		intel_tile_dims(fb, i, &tile_width, &tile_height);
+
+		x = aligned_x / hsub;
+		y = aligned_y / vsub;
+		width = aligned_w / hsub;
+		height = aligned_h / vsub;
+
+		/*
+		 * First pixel of the aligned src viewport
+		 * from the start of the normal gtt mapping.
+		 */
+		x += intel_fb->normal[i].x;
+		y += intel_fb->normal[i].y;
+
+		offset = intel_compute_aligned_offset(dev_priv, &x, &y,
+						      fb, i, fb->pitches[i],
+						      DRM_MODE_ROTATE_0, tile_size);
+		offset /= tile_size;
+
+		info->plane[i].offset = offset;
+		info->plane[i].stride = DIV_ROUND_UP(fb->pitches[i],
+						     tile_width * cpp);
+		info->plane[i].width = DIV_ROUND_UP(x + width, tile_width);
+		info->plane[i].height = DIV_ROUND_UP(y + height, tile_height);
+
+		if (drm_rotation_90_or_270(rotation)) {
+			struct drm_rect r;
+
+			/* rotate the x/y offsets to match the GTT view */
+			r.x1 = x;
+			r.y1 = y;
+			r.x2 = x + width;
+			r.y2 = y + height;
+			drm_rect_rotate(&r,
+					info->plane[i].width * tile_width,
+					info->plane[i].height * tile_height,
+					DRM_MODE_ROTATE_270);
+			x = r.x1;
+			y = r.y1;
+
+			pitch_tiles = info->plane[i].height;
+			plane_state->color_plane[i].stride = pitch_tiles * tile_height;
+
+			/* rotate the tile dimensions to match the GTT view */
+			swap(tile_width, tile_height);
+		} else {
+			pitch_tiles = info->plane[i].width;
+			plane_state->color_plane[i].stride = pitch_tiles * tile_width * cpp;
+		}
+
+		/*
+		 * We only keep the x/y offsets, so push all of the
+		 * gtt offset into the x/y offsets.
+		 */
+		intel_adjust_tile_offset(&x, &y,
+					 tile_width, tile_height,
+					 tile_size, pitch_tiles,
+					 gtt_offset * tile_size, 0);
+
+		gtt_offset += info->plane[i].width * info->plane[i].height;
+
+		plane_state->color_plane[i].offset = 0;
+		plane_state->color_plane[i].x = x;
+		plane_state->color_plane[i].y = y;
+	}
+}
+
+static int
+intel_plane_compute_gtt(struct intel_plane_state *plane_state)
+{
+	const struct intel_framebuffer *fb =
+		to_intel_framebuffer(plane_state->base.fb);
+	unsigned int rotation = plane_state->base.rotation;
+	int i, num_planes = fb->base.format->num_planes;
+	int ret;
+
+	if (intel_plane_needs_remap(plane_state)) {
+		intel_plane_remap_gtt(plane_state);
+
+		/* Remapping should take care of this always */
+		ret = intel_plane_check_stride(plane_state);
+		if (WARN_ON(ret))
+			return ret;
+
+		return 0;
+	}
+
+	intel_fill_fb_ggtt_view(&plane_state->view, &fb->base, rotation);
+
+	for (i = 0; i < num_planes; i++) {
+		plane_state->color_plane[i].stride = intel_fb_pitch(&fb->base, i, rotation);
+		plane_state->color_plane[i].offset = 0;
+
+		if (drm_rotation_90_or_270(rotation)) {
+			plane_state->color_plane[i].x = fb->rotated[i].x;
+			plane_state->color_plane[i].y = fb->rotated[i].y;
+		} else {
+			plane_state->color_plane[i].x = fb->normal[i].x;
+			plane_state->color_plane[i].y = fb->normal[i].y;
+		}
+	}
+
+	/* Rotate src coordinates to match rotated GTT view */
+	if (drm_rotation_90_or_270(rotation))
+		drm_rect_rotate(&plane_state->base.src,
+				fb->base.width << 16, fb->base.height << 16,
+				DRM_MODE_ROTATE_270);
+
+	ret = intel_plane_check_stride(plane_state);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
 static int i9xx_format_to_fourcc(int format)
 {
 	switch (format) {
@@ -3171,26 +3412,12 @@ static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state)
 int skl_check_plane_surface(struct intel_plane_state *plane_state)
 {
 	const struct drm_framebuffer *fb = plane_state->base.fb;
-	unsigned int rotation = plane_state->base.rotation;
 	int ret;
 
-	intel_fill_fb_ggtt_view(&plane_state->view, fb, rotation);
-	plane_state->color_plane[0].stride = intel_fb_pitch(fb, 0, rotation);
-	plane_state->color_plane[1].stride = intel_fb_pitch(fb, 1, rotation);
-
-	ret = intel_plane_check_stride(plane_state);
+	ret = intel_plane_compute_gtt(plane_state);
 	if (ret)
 		return ret;
 
-	if (!plane_state->base.visible)
-		return 0;
-
-	/* Rotate src coordinates to match rotated GTT view */
-	if (drm_rotation_90_or_270(rotation))
-		drm_rect_rotate(&plane_state->base.src,
-				fb->width << 16, fb->height << 16,
-				DRM_MODE_ROTATE_270);
-
 	/*
 	 * Handle the AUX surface first since
 	 * the main surface setup depends on it.
@@ -3312,20 +3539,17 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
 {
 	struct drm_i915_private *dev_priv =
 		to_i915(plane_state->base.plane->dev);
-	const struct drm_framebuffer *fb = plane_state->base.fb;
-	unsigned int rotation = plane_state->base.rotation;
-	int src_x = plane_state->base.src.x1 >> 16;
-	int src_y = plane_state->base.src.y1 >> 16;
+	int src_x, src_y;
 	u32 offset;
 	int ret;
 
-	intel_fill_fb_ggtt_view(&plane_state->view, fb, rotation);
-	plane_state->color_plane[0].stride = intel_fb_pitch(fb, 0, rotation);
-
-	ret = intel_plane_check_stride(plane_state);
+	ret = intel_plane_compute_gtt(plane_state);
 	if (ret)
 		return ret;
 
+	src_x = plane_state->base.src.x1 >> 16;
+	src_y = plane_state->base.src.y1 >> 16;
+
 	intel_add_fb_offsets(&src_x, &src_y, plane_state, 0);
 
 	if (INTEL_GEN(dev_priv) >= 4)
@@ -3336,6 +3560,7 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
 
 	/* HSW/BDW do this automagically in hardware */
 	if (!IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv)) {
+		unsigned int rotation = plane_state->base.rotation;
 		int src_w = drm_rect_width(&plane_state->base.src) >> 16;
 		int src_h = drm_rect_height(&plane_state->base.src) >> 16;
 
@@ -3503,15 +3728,6 @@ static bool i9xx_plane_get_hw_state(struct intel_plane *plane,
 	return ret;
 }
 
-static u32
-intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane)
-{
-	if (fb->modifier == DRM_FORMAT_MOD_LINEAR)
-		return 64;
-	else
-		return intel_tile_width_bytes(fb, color_plane);
-}
-
 static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id)
 {
 	struct drm_device *dev = intel_crtc->base.dev;
@@ -9720,16 +9936,11 @@ static bool intel_cursor_size_ok(const struct intel_plane_state *plane_state)
 
 static int intel_cursor_check_surface(struct intel_plane_state *plane_state)
 {
-	const struct drm_framebuffer *fb = plane_state->base.fb;
-	unsigned int rotation = plane_state->base.rotation;
 	int src_x, src_y;
 	u32 offset;
 	int ret;
 
-	intel_fill_fb_ggtt_view(&plane_state->view, fb, rotation);
-	plane_state->color_plane[0].stride = intel_fb_pitch(fb, 0, rotation);
-
-	ret = intel_plane_check_stride(plane_state);
+	ret = intel_plane_compute_gtt(plane_state);
 	if (ret)
 		return ret;
 
@@ -14473,24 +14684,6 @@ static const struct drm_framebuffer_funcs intel_fb_funcs = {
 	.dirty = intel_user_framebuffer_dirty,
 };
 
-static
-u32 intel_fb_pitch_limit(struct drm_i915_private *dev_priv,
-			 uint64_t fb_modifier, uint32_t pixel_format)
-{
-	struct intel_crtc *crtc;
-	struct intel_plane *plane;
-
-	/*
-	 * We assume the primary plane for pipe A has
-	 * the highest stride limits of them all.
-	 */
-	crtc = intel_get_crtc_for_pipe(dev_priv, PIPE_A);
-	plane = to_intel_plane(crtc->base.primary);
-
-	return plane->max_stride(plane, pixel_format, fb_modifier,
-				 DRM_MODE_ROTATE_0);
-}
-
 static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
 				  struct drm_i915_gem_object *obj,
 				  struct drm_mode_fb_cmd2 *mode_cmd)
@@ -14498,7 +14691,7 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
 	struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
 	struct drm_framebuffer *fb = &intel_fb->base;
 	struct drm_format_name_buf format_name;
-	u32 pitch_limit;
+	u32 max_stride;
 	unsigned int tiling, stride;
 	int ret = -EINVAL;
 	int i;
@@ -14569,13 +14762,13 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
 		goto err;
 	}
 
-	pitch_limit = intel_fb_pitch_limit(dev_priv, mode_cmd->modifier[0],
-					   mode_cmd->pixel_format);
-	if (mode_cmd->pitches[0] > pitch_limit) {
+	max_stride = intel_fb_max_stride(dev_priv, mode_cmd->modifier[0],
+					 mode_cmd->pixel_format);
+	if (mode_cmd->pitches[0] > max_stride) {
 		DRM_DEBUG_KMS("%s pitch (%u) must be at most %d\n",
 			      mode_cmd->modifier[0] != DRM_FORMAT_MOD_LINEAR ?
 			      "tiled" : "linear",
-			      mode_cmd->pitches[0], pitch_limit);
+			      mode_cmd->pitches[0], max_stride);
 		goto err;
 	}
 
-- 
2.16.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v3 7/8] drm/i915: Bump gen4+ fb stride limit to 256KiB
  2018-09-25 19:37 [PATCH v3 0/8] drm/i915: GTT remapping for display Ville Syrjala
                   ` (5 preceding siblings ...)
  2018-09-25 19:37 ` [PATCH v3 6/8] drm/i915: Overcome display engine stride limits via GTT remapping Ville Syrjala
@ 2018-09-25 19:37 ` Ville Syrjala
  2018-09-25 20:13   ` Chris Wilson
  2018-09-25 19:37 ` [PATCH v3 8/8] drm/i915: Bump gen7+ fb size limits to 16kx16k Ville Syrjala
                   ` (9 subsequent siblings)
  16 siblings, 1 reply; 62+ messages in thread
From: Ville Syrjala @ 2018-09-25 19:37 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

With gtt remapping plugged in we can simply raise the stride
limit on gen4+. Let's just arbitraily pick 256 KiB as the limit.

No remapping CCS because the virtual address of each page actually
matters due to the new hash mode
(WaCompressedResourceDisplayNewHashMode:skl,kbl etc.), and no remapping
on gen2/3 due to lack of fence on the remapped vma.

v2: Rebase due to is_ccs_modifier()

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index eca873653fea..d533a6086169 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2522,6 +2522,19 @@ static
 u32 intel_fb_max_stride(struct drm_i915_private *dev_priv,
 			u32 pixel_format, u64 modifier)
 {
+	/*
+	 * Arbitrary limit for gen4+. We can deal with any page
+	 * aligned stride via GTT remapping. Gen2/3 need a fence
+	 * for tiled scanout which the remapped vma won't have,
+	 * so we don't allow remapping on those platforms.
+	 *
+	 * Also the new hash mode we use for CCS isn't compatible
+	 * with remapping as the virtual address of the pages
+	 * affects the compressed data.
+	 */
+	if (INTEL_GEN(dev_priv) >= 4 && !is_ccs_modifier(modifier))
+		return 256*1024;
+
 	return intel_plane_fb_max_stride(dev_priv, pixel_format, modifier);
 }
 
-- 
2.16.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v3 8/8] drm/i915: Bump gen7+ fb size limits to 16kx16k
  2018-09-25 19:37 [PATCH v3 0/8] drm/i915: GTT remapping for display Ville Syrjala
                   ` (6 preceding siblings ...)
  2018-09-25 19:37 ` [PATCH v3 7/8] drm/i915: Bump gen4+ fb stride limit to 256KiB Ville Syrjala
@ 2018-09-25 19:37 ` Ville Syrjala
  2018-09-25 19:59   ` Chris Wilson
  2018-09-25 20:05 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: GTT remapping for display Patchwork
                   ` (8 subsequent siblings)
  16 siblings, 1 reply; 62+ messages in thread
From: Ville Syrjala @ 2018-09-25 19:37 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

With gtt remapping in place we can use arbitrarily large
framebuffers. Let's bump the limits to 16kx16k on gen7+.
The limit was chosen to match the maximum 2D surface size
of the 3D engine.

With the remapping we could easily go higher than that for the
display engine. However the modesetting ddx will blindly assume
it can handle whatever is reported via kms. The oversized
buffer dimensions are not caught by glamor nor Mesa until
finally an assert will trip when genxml attempts to pack the
SURFACE_STATE. So we pick a safe limit to avoid the X server
from crashing (or potentially misbehaving if the genxml asserts
are compiled out).

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index d533a6086169..241b9f6cbb76 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -15524,16 +15524,22 @@ int intel_modeset_init(struct drm_device *dev)
 		}
 	}
 
-	/* maximum framebuffer dimensions */
-	if (IS_GEN2(dev_priv)) {
-		dev->mode_config.max_width = 2048;
-		dev->mode_config.max_height = 2048;
+	/*
+	 * Maximum framebuffer dimensions, chosen to match
+	 * the maximum render engine surface size on gen4+.
+	 */
+	if (INTEL_GEN(dev_priv) >= 7) {
+		dev->mode_config.max_width = 16384;
+		dev->mode_config.max_height = 16384;
+	} else if (INTEL_GEN(dev_priv) >= 4) {
+		dev->mode_config.max_width = 8192;
+		dev->mode_config.max_height = 8192;
 	} else if (IS_GEN3(dev_priv)) {
 		dev->mode_config.max_width = 4096;
 		dev->mode_config.max_height = 4096;
 	} else {
-		dev->mode_config.max_width = 8192;
-		dev->mode_config.max_height = 8192;
+		dev->mode_config.max_width = 2048;
+		dev->mode_config.max_height = 2048;
 	}
 
 	if (IS_I845G(dev_priv) || IS_I865G(dev_priv)) {
-- 
2.16.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 8/8] drm/i915: Bump gen7+ fb size limits to 16kx16k
  2018-09-25 19:37 ` [PATCH v3 8/8] drm/i915: Bump gen7+ fb size limits to 16kx16k Ville Syrjala
@ 2018-09-25 19:59   ` Chris Wilson
  2018-09-26  9:25     ` Ville Syrjälä
  0 siblings, 1 reply; 62+ messages in thread
From: Chris Wilson @ 2018-09-25 19:59 UTC (permalink / raw)
  To: Ville Syrjala, intel-gfx

Quoting Ville Syrjala (2018-09-25 20:37:14)
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> With gtt remapping in place we can use arbitrarily large
> framebuffers. Let's bump the limits to 16kx16k on gen7+.
> The limit was chosen to match the maximum 2D surface size
> of the 3D engine.
> 
> With the remapping we could easily go higher than that for the
> display engine. However the modesetting ddx will blindly assume
> it can handle whatever is reported via kms. The oversized
> buffer dimensions are not caught by glamor nor Mesa until
> finally an assert will trip when genxml attempts to pack the
> SURFACE_STATE. So we pick a safe limit to avoid the X server
> from crashing (or potentially misbehaving if the genxml asserts
> are compiled out).
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 18 ++++++++++++------
>  1 file changed, 12 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index d533a6086169..241b9f6cbb76 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -15524,16 +15524,22 @@ int intel_modeset_init(struct drm_device *dev)
>                 }
>         }
>  
> -       /* maximum framebuffer dimensions */
> -       if (IS_GEN2(dev_priv)) {
> -               dev->mode_config.max_width = 2048;
> -               dev->mode_config.max_height = 2048;
> +       /*
> +        * Maximum framebuffer dimensions, chosen to match
> +        * the maximum render engine surface size on gen4+.
> +        */
> +       if (INTEL_GEN(dev_priv) >= 7) {
> +               dev->mode_config.max_width = 16384;
> +               dev->mode_config.max_height = 16384;
> +       } else if (INTEL_GEN(dev_priv) >= 4) {
> +               dev->mode_config.max_width = 8192;
> +               dev->mode_config.max_height = 8192;
>         } else if (IS_GEN3(dev_priv)) {
>                 dev->mode_config.max_width = 4096;
>                 dev->mode_config.max_height = 4096;

You have the same problem on gen3 then. 3D pipeline is restricted to 2k.
Different rules for different gen. :(
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* ✗ Fi.CI.CHECKPATCH: warning for drm/i915: GTT remapping for display
  2018-09-25 19:37 [PATCH v3 0/8] drm/i915: GTT remapping for display Ville Syrjala
                   ` (7 preceding siblings ...)
  2018-09-25 19:37 ` [PATCH v3 8/8] drm/i915: Bump gen7+ fb size limits to 16kx16k Ville Syrjala
@ 2018-09-25 20:05 ` Patchwork
  2018-09-25 20:08 ` ✗ Fi.CI.SPARSE: " Patchwork
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 62+ messages in thread
From: Patchwork @ 2018-09-25 20:05 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: GTT remapping for display
URL   : https://patchwork.freedesktop.org/series/50165/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
fd6c4b3fa1e9 drm/i915: Make sure fb gtt offsets stay within 32bits
dafb1135ed8c drm/i915: Decouple SKL stride units from intel_fb_stride_alignment()
96eb024e5885 drm/i915: Add a new "remapped" gtt_view
-:190: CHECK:SPACING: spaces preferred around that '*' (ctx:VxV)
#190: FILE: drivers/gpu/drm/i915/i915_gem_gtt.h:193:
+	BUILD_BUG_ON(sizeof(struct intel_remapped_info) != 9*sizeof(unsigned int));
 	                                                    ^

total: 0 errors, 0 warnings, 1 checks, 248 lines checked
fa6cf412dafd drm/i915/selftests: Add mock selftest for remapped vmas
-:111: WARNING:SUSPECT_CODE_INDENT: suspect code indent for conditional statements (8, 8)
#111: FILE: drivers/gpu/drm/i915/selftests/i915_vma.c:493:
+	for (t = types; *t; t++) {
 	for (a = planes; a->width; a++) {

-:129: WARNING:DEEP_INDENTATION: Too many leading tabs - consider code refactoring
#129: FILE: drivers/gpu/drm/i915/selftests/i915_vma.c:554:
+						if (view.type == I915_GGTT_VIEW_ROTATED)

-:130: WARNING:LONG_LINE: line over 100 characters
#130: FILE: drivers/gpu/drm/i915/selftests/i915_vma.c:555:
+							sg = assert_rotated(obj, &view.rotated, n, sg);

-:131: WARNING:DEEP_INDENTATION: Too many leading tabs - consider code refactoring
#131: FILE: drivers/gpu/drm/i915/selftests/i915_vma.c:556:
+						else

-:132: WARNING:LONG_LINE: line over 100 characters
#132: FILE: drivers/gpu/drm/i915/selftests/i915_vma.c:557:
+							sg = assert_remapped(obj, &view.remapped, n, sg);

total: 0 errors, 5 warnings, 0 checks, 124 lines checked
762ba8d98203 drm/i915/selftests: Add live vma selftest
43dcb570fdec drm/i915: Overcome display engine stride limits via GTT remapping
8b2eedbf6d7d drm/i915: Bump gen4+ fb stride limit to 256KiB
-:40: CHECK:SPACING: spaces preferred around that '*' (ctx:VxV)
#40: FILE: drivers/gpu/drm/i915/intel_display.c:2536:
+		return 256*1024;
 		          ^

total: 0 errors, 0 warnings, 1 checks, 19 lines checked
0dea7c2d42cf drm/i915: Bump gen7+ fb size limits to 16kx16k

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* ✗ Fi.CI.SPARSE: warning for drm/i915: GTT remapping for display
  2018-09-25 19:37 [PATCH v3 0/8] drm/i915: GTT remapping for display Ville Syrjala
                   ` (8 preceding siblings ...)
  2018-09-25 20:05 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: GTT remapping for display Patchwork
@ 2018-09-25 20:08 ` Patchwork
  2018-09-25 20:30 ` ✓ Fi.CI.BAT: success " Patchwork
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 62+ messages in thread
From: Patchwork @ 2018-09-25 20:08 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: GTT remapping for display
URL   : https://patchwork.freedesktop.org/series/50165/
State : warning

== Summary ==

$ dim sparse origin/drm-tip
Commit: drm/i915: Make sure fb gtt offsets stay within 32bits
+drivers/gpu/drm/i915/intel_display.c:2416:13: error: undefined identifier '__builtin_add_overflow_p'
+drivers/gpu/drm/i915/intel_display.c:2416:13: warning: call with no type!

Commit: drm/i915: Decouple SKL stride units from intel_fb_stride_alignment()
Okay!

Commit: drm/i915: Add a new "remapped" gtt_view
+./include/linux/mm.h:592:13: error: not a function <noident>

Commit: drm/i915/selftests: Add mock selftest for remapped vmas
Okay!

Commit: drm/i915/selftests: Add live vma selftest
Okay!

Commit: drm/i915: Overcome display engine stride limits via GTT remapping
Okay!

Commit: drm/i915: Bump gen4+ fb stride limit to 256KiB
Okay!

Commit: drm/i915: Bump gen7+ fb size limits to 16kx16k
Okay!

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 7/8] drm/i915: Bump gen4+ fb stride limit to 256KiB
  2018-09-25 19:37 ` [PATCH v3 7/8] drm/i915: Bump gen4+ fb stride limit to 256KiB Ville Syrjala
@ 2018-09-25 20:13   ` Chris Wilson
  2018-09-28 19:19     ` Ville Syrjälä
  0 siblings, 1 reply; 62+ messages in thread
From: Chris Wilson @ 2018-09-25 20:13 UTC (permalink / raw)
  To: Ville Syrjala, intel-gfx

Quoting Ville Syrjala (2018-09-25 20:37:13)
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> With gtt remapping plugged in we can simply raise the stride
> limit on gen4+. Let's just arbitraily pick 256 KiB as the limit.
> 
> No remapping CCS because the virtual address of each page actually
> matters due to the new hash mode
> (WaCompressedResourceDisplayNewHashMode:skl,kbl etc.), and no remapping
> on gen2/3 due to lack of fence on the remapped vma.
> 
> v2: Rebase due to is_ccs_modifier()
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index eca873653fea..d533a6086169 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2522,6 +2522,19 @@ static
>  u32 intel_fb_max_stride(struct drm_i915_private *dev_priv,
>                         u32 pixel_format, u64 modifier)
>  {
> +       /*
> +        * Arbitrary limit for gen4+. We can deal with any page
> +        * aligned stride via GTT remapping. Gen2/3 need a fence
> +        * for tiled scanout which the remapped vma won't have,
> +        * so we don't allow remapping on those platforms.
> +        *
> +        * Also the new hash mode we use for CCS isn't compatible
> +        * with remapping as the virtual address of the pages
> +        * affects the compressed data.
> +        */
> +       if (INTEL_GEN(dev_priv) >= 4 && !is_ccs_modifier(modifier))
> +               return 256*1024;

Worth using SZ_256K ?
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 5/8] drm/i915/selftests: Add live vma selftest
  2018-09-25 19:37 ` [PATCH v3 5/8] drm/i915/selftests: Add live vma selftest Ville Syrjala
@ 2018-09-25 20:19   ` Chris Wilson
  2018-09-25 20:40   ` Chris Wilson
  2018-10-23 16:03   ` [PATCH v4 " Ville Syrjala
  2 siblings, 0 replies; 62+ messages in thread
From: Chris Wilson @ 2018-09-25 20:19 UTC (permalink / raw)
  To: Ville Syrjala, intel-gfx

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
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 4/8] drm/i915/selftests: Add mock selftest for remapped vmas
  2018-09-25 19:37 ` [PATCH v3 4/8] drm/i915/selftests: Add mock selftest for remapped vmas Ville Syrjala
@ 2018-09-25 20:22   ` Chris Wilson
  2018-09-26  9:28     ` Ville Syrjälä
  2018-10-23 16:03   ` [PATCH v4 " Ville Syrjala
  1 sibling, 1 reply; 62+ messages in thread
From: Chris Wilson @ 2018-09-25 20:22 UTC (permalink / raw)
  To: Ville Syrjala, intel-gfx

Quoting Ville Syrjala (2018-09-25 20:37:10)
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Extend the rotated vma mock selftest to cover remapped vmas as
> well.
> 
> TODO: reindent the loops I guess? Left like this for now to
> ease review
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/selftests/i915_vma.c | 70 ++++++++++++++++++++++++++++---
>  1 file changed, 65 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c
> index 4fc49c27f13c..6e84e5cc93a0 100644
> --- a/drivers/gpu/drm/i915/selftests/i915_vma.c
> +++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
> @@ -58,7 +58,7 @@ static bool assert_vma(struct i915_vma *vma,
>  static struct i915_vma *
>  checked_vma_instance(struct drm_i915_gem_object *obj,
>                      struct i915_address_space *vm,
> -                    struct i915_ggtt_view *view)
> +                    const struct i915_ggtt_view *view)
>  {
>         struct i915_vma *vma;
>         bool ok = true;
> @@ -395,13 +395,63 @@ assert_rotated(struct drm_i915_gem_object *obj,
>         return sg;
>  }
>  
> +static unsigned long remapped_index(const struct intel_remapped_info *r,
> +                                   unsigned int n,
> +                                   unsigned int x,
> +                                   unsigned int y)
> +{
> +       return (r->plane[n].stride * y +
> +               r->plane[n].offset + x);
> +}
> +
> +static struct scatterlist *
> +assert_remapped(struct drm_i915_gem_object *obj,
> +               const struct intel_remapped_info *r, unsigned int n,
> +               struct scatterlist *sg)
> +{
> +       unsigned int x, y;
> +
> +       for (y = 0; y < r->plane[n].height; y++) {
> +               for (x = 0; x < r->plane[n].width; x++) {
> +                       unsigned long src_idx;
> +                       dma_addr_t src;
> +
> +                       if (!sg) {
> +                               pr_err("Invalid sg table: too short at plane %d, (%d, %d)!\n",
> +                                      n, x, y);
> +                               return ERR_PTR(-EINVAL);
> +                       }
> +
> +                       src_idx = remapped_index(r, n, x, y);
> +                       src = i915_gem_object_get_dma_address(obj, src_idx);
> +
> +                       if (sg_dma_len(sg) != PAGE_SIZE) {
> +                               pr_err("Invalid sg.length, found %d, expected %lu for remapped page (%d, %d) [src index %lu]\n",
> +                                      sg_dma_len(sg), PAGE_SIZE,
> +                                      x, y, src_idx);
> +                               return ERR_PTR(-EINVAL);
> +                       }
> +
> +                       if (sg_dma_address(sg) != src) {
> +                               pr_err("Invalid address for remapped page (%d, %d) [src index %lu]\n",
> +                                      x, y, src_idx);
> +                               return ERR_PTR(-EINVAL);
> +                       }
> +
> +                       sg = sg_next(sg);
> +               }
> +       }
> +
> +       return sg;
> +}
> +
>  static unsigned int rotated_size(const struct intel_remapped_plane_info *a,
>                                  const struct intel_remapped_plane_info *b)
>  {
>         return a->width * a->height + b->width * b->height;
>  }
>  
> -static int igt_vma_rotate(void *arg)
> +static int igt_vma_rotate_remap(void *arg)
>  {
>         struct drm_i915_private *i915 = arg;
>         struct i915_address_space *vm = &i915->ggtt.vm;
> @@ -424,6 +474,11 @@ static int igt_vma_rotate(void *arg)
>                 { .width = 6, .height = 4, .stride = 6 },
>                 { }
>         }, *a, *b;
> +       enum i915_ggtt_view_type types[] = {
> +               I915_GGTT_VIEW_ROTATED,
> +               I915_GGTT_VIEW_REMAPPED,
> +               0,
> +       }, *t;
>         const unsigned int max_pages = 64;
>         int err = -ENOMEM;
>  
> @@ -435,6 +490,7 @@ static int igt_vma_rotate(void *arg)
>         if (IS_ERR(obj))
>                 goto out;
>  
> +       for (t = types; *t; t++) {
>         for (a = planes; a->width; a++) {
>                 for (b = planes + ARRAY_SIZE(planes); b-- != planes; ) {
>                         struct i915_ggtt_view view;
> @@ -445,7 +501,7 @@ static int igt_vma_rotate(void *arg)
>                         GEM_BUG_ON(max_offset > max_pages);
>                         max_offset = max_pages - max_offset;
>  
> -                       view.type = I915_GGTT_VIEW_ROTATED;
> +                       view.type = *t;
>                         view.rotated.plane[0] = *a;
>                         view.rotated.plane[1] = *b;
>  
> @@ -495,7 +551,10 @@ static int igt_vma_rotate(void *arg)
>  
>                                         sg = vma->pages->sgl;
>                                         for (n = 0; n < ARRAY_SIZE(view.rotated.plane); n++) {
> -                                               sg = assert_rotated(obj, &view.rotated, n, sg);
> +                                               if (view.type == I915_GGTT_VIEW_ROTATED)
> +                                                       sg = assert_rotated(obj, &view.rotated, n, sg);
> +                                               else
> +                                                       sg = assert_remapped(obj, &view.remapped, n, sg);
>                                                 if (IS_ERR(sg)) {
>                                                         pr_err("Inconsistent VMA pages for plane %d: [(%d, %d, %d, %d), (%d, %d, %d, %d)]\n", n,

Looks ok, but we need to include the remap type in the error statement
if we either want to decypher what may have gone wrong. I see the
assert callbacks do include the hint, but adding an extra "%s" here may
help.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 1/8] drm/i915: Make sure fb gtt offsets stay within 32bits
  2018-09-25 19:37 ` [PATCH v3 1/8] drm/i915: Make sure fb gtt offsets stay within 32bits Ville Syrjala
@ 2018-09-25 20:29   ` Chris Wilson
  2018-09-26  9:27     ` Ville Syrjälä
  2018-10-23 16:02   ` [PATCH v4 " Ville Syrjala
  1 sibling, 1 reply; 62+ messages in thread
From: Chris Wilson @ 2018-09-25 20:29 UTC (permalink / raw)
  To: Ville Syrjala, intel-gfx

Quoting Ville Syrjala (2018-09-25 20:37:07)
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Let's try to make sure the fb offset computations never hit
> an integer overflow by making sure the entire fb stays
> below 32bits. framebuffer_check() in the core already does
> the same check, but as it doesn't know about tiling some things
> can slip through. Repeat the check in the driver with tiling
> taken into account.
> 
> v2: Use add_overflows() after massaging it to work for me (Chris)

Oh, it had fallen out of use.
 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_utils.h    |  8 ++++----
>  drivers/gpu/drm/i915/intel_display.c | 18 +++++++++++++++++-
>  2 files changed, 21 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h
> index 395dd2511568..c43ec993fa90 100644
> --- a/drivers/gpu/drm/i915/i915_utils.h
> +++ b/drivers/gpu/drm/i915/i915_utils.h
> @@ -44,13 +44,13 @@
>                              __stringify(x), (long)(x))
>  
>  #if defined(GCC_VERSION) && GCC_VERSION >= 70000
> -#define add_overflows(A, B) \
> -       __builtin_add_overflow_p((A), (B), (typeof((A) + (B)))0)
> +#define add_overflows(A, B, C) \
> +       __builtin_add_overflow_p((A), (B), (C))
>  #else
> -#define add_overflows(A, B) ({ \
> +#define add_overflows(A, B, C) ({ \
>         typeof(A) a = (A); \
>         typeof(B) b = (B); \
> -       a + b < a; \
> +       (typeof(C))(a + b) < a; \
>  })
>  #endif
>  
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 4c5c2b39e65c..a3ae24e03316 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2400,10 +2400,26 @@ static int intel_fb_offset_to_xy(int *x, int *y,
>                                  int color_plane)
>  {
>         struct drm_i915_private *dev_priv = to_i915(fb->dev);
> +       unsigned int height;
>  
>         if (fb->modifier != DRM_FORMAT_MOD_LINEAR &&
> -           fb->offsets[color_plane] % intel_tile_size(dev_priv))
> +           fb->offsets[color_plane] % intel_tile_size(dev_priv)) {
> +               DRM_DEBUG_KMS("Misaligned offset 0x%08x for color plane %d\n",
> +                             fb->offsets[color_plane], color_plane);
>                 return -EINVAL;
> +       }
> +
> +       height = drm_framebuffer_plane_height(fb->height, fb, color_plane);
> +       height = ALIGN(height, intel_tile_height(fb, color_plane));
> +
> +       /* Catch potential overflows early */
> +       if (add_overflows(mul_u32_u32(height, fb->pitches[color_plane]),
> +                         fb->offsets[color_plane], (u32)0)) {

Should we just pass type? Atm we aren't using the value for anything.
Then it would be add_overflows_t(a, b, T) with the obvious wrapping for
add_overflows(a, b). Although to be consistent with min_t, perhaps
add_overflows_t(T, a, b).
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* ✓ Fi.CI.BAT: success for drm/i915: GTT remapping for display
  2018-09-25 19:37 [PATCH v3 0/8] drm/i915: GTT remapping for display Ville Syrjala
                   ` (9 preceding siblings ...)
  2018-09-25 20:08 ` ✗ Fi.CI.SPARSE: " Patchwork
@ 2018-09-25 20:30 ` Patchwork
  2018-09-25 21:21 ` ✓ Fi.CI.IGT: " Patchwork
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 62+ messages in thread
From: Patchwork @ 2018-09-25 20:30 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: GTT remapping for display
URL   : https://patchwork.freedesktop.org/series/50165/
State : success

== Summary ==

= CI Bug Log - changes from CI_DRM_4875 -> Patchwork_10279 =

== Summary - WARNING ==

  Minor unknown changes coming with Patchwork_10279 need to be verified
  manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_10279, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: https://patchwork.freedesktop.org/api/1.0/series/50165/revisions/1/mbox/

== Possible new issues ==

  Here are the unknown changes that may have been introduced in Patchwork_10279:

  === IGT changes ===

    ==== Possible regressions ====

    {igt@drv_selftest@live_vma}:
      fi-whl-u:           NOTRUN -> INCOMPLETE
      fi-ilk-650:         NOTRUN -> INCOMPLETE
      fi-bsw-n3050:       NOTRUN -> INCOMPLETE
      fi-hsw-4770:        NOTRUN -> INCOMPLETE
      fi-skl-iommu:       NOTRUN -> INCOMPLETE
      fi-cnl-u:           NOTRUN -> INCOMPLETE
      fi-kbl-7567u:       NOTRUN -> INCOMPLETE
      fi-ivb-3770:        NOTRUN -> INCOMPLETE
      fi-hsw-peppy:       NOTRUN -> INCOMPLETE
      fi-icl-u:           NOTRUN -> INCOMPLETE
      fi-kbl-x1275:       NOTRUN -> INCOMPLETE
      fi-hsw-4770r:       NOTRUN -> INCOMPLETE
      fi-skl-caroline:    NOTRUN -> INCOMPLETE
      fi-kbl-7560u:       NOTRUN -> INCOMPLETE
      fi-skl-6700hq:      NOTRUN -> INCOMPLETE
      fi-skl-6700k2:      NOTRUN -> INCOMPLETE
      fi-blb-e6850:       NOTRUN -> INCOMPLETE
      fi-cfl-8700k:       NOTRUN -> INCOMPLETE
      fi-skl-6600u:       NOTRUN -> INCOMPLETE
      fi-bsw-kefka:       NOTRUN -> INCOMPLETE
      fi-bwr-2160:        NOTRUN -> INCOMPLETE
      fi-kbl-r:           NOTRUN -> INCOMPLETE
      fi-skl-6770hq:      NOTRUN -> INCOMPLETE
      fi-cfl-8109u:       NOTRUN -> INCOMPLETE
      fi-cfl-s3:          NOTRUN -> INCOMPLETE
      fi-gdg-551:         NOTRUN -> INCOMPLETE
      fi-snb-2600:        NOTRUN -> INCOMPLETE

    
    ==== Warnings ====

    igt@drv_selftest@live_coherency:
      fi-bwr-2160:        PASS -> SKIP +8
      fi-kbl-r:           PASS -> SKIP +8
      fi-skl-6770hq:      PASS -> SKIP +8
      fi-byt-n2820:       PASS -> SKIP +8
      fi-snb-2600:        PASS -> SKIP +8
      fi-ilk-650:         PASS -> SKIP +8

    igt@drv_selftest@live_contexts:
      fi-cfl-s3:          PASS -> SKIP +8
      fi-bdw-gvtdvm:      PASS -> SKIP +8

    igt@drv_selftest@live_evict:
      fi-skl-gvtdvm:      PASS -> SKIP +8
      fi-bsw-kefka:       PASS -> SKIP +8
      fi-kbl-x1275:       PASS -> SKIP +8

    igt@drv_selftest@live_execlists:
      fi-skl-caroline:    PASS -> SKIP +8
      fi-cfl-8700k:       PASS -> SKIP +8
      fi-glk-j4005:       PASS -> SKIP +8

    igt@drv_selftest@live_gem:
      fi-whl-u:           PASS -> SKIP +8
      fi-skl-6600u:       PASS -> SKIP +8
      fi-kbl-7560u:       PASS -> SKIP +8
      fi-skl-iommu:       PASS -> SKIP +8
      fi-elk-e7500:       PASS -> SKIP +8
      fi-skl-6700k2:      PASS -> SKIP +8

    igt@drv_selftest@live_gtt:
      fi-byt-clapper:     PASS -> SKIP +8
      fi-gdg-551:         PASS -> SKIP +8
      fi-skl-6700hq:      PASS -> SKIP +8
      fi-bxt-j4205:       PASS -> SKIP +8

    igt@drv_selftest@live_guc:
      fi-hsw-peppy:       PASS -> SKIP +8
      fi-cnl-u:           PASS -> SKIP +8
      fi-kbl-7567u:       PASS -> SKIP +8
      fi-skl-guc:         PASS -> SKIP +8
      fi-cfl-guc:         PASS -> SKIP +8
      fi-icl-u:           PASS -> SKIP +8
      fi-bsw-n3050:       PASS -> SKIP +8
      fi-ivb-3770:        PASS -> SKIP +8
      fi-bxt-dsi:         PASS -> SKIP +8
      fi-hsw-4770:        PASS -> SKIP +8

    igt@drv_selftest@live_hangcheck:
      fi-snb-2520m:       PASS -> SKIP +8
      fi-hsw-4770r:       PASS -> SKIP +8

    igt@drv_selftest@live_hugepages:
      fi-glk-dsi:         PASS -> SKIP +8
      fi-cfl-8109u:       PASS -> SKIP +8
      fi-blb-e6850:       PASS -> SKIP +8

    
== Known issues ==

  Here are the changes found in Patchwork_10279 that come from known issues:

  === IGT changes ===

    ==== Issues hit ====

    {igt@drv_selftest@live_vma}:
      fi-bdw-gvtdvm:      NOTRUN -> INCOMPLETE (fdo#105600)
      fi-bxt-j4205:       NOTRUN -> INCOMPLETE (fdo#103927)
      fi-glk-j4005:       NOTRUN -> INCOMPLETE (k.org#198133, fdo#103359)
      fi-glk-dsi:         NOTRUN -> INCOMPLETE (k.org#198133, fdo#103359)
      fi-snb-2520m:       NOTRUN -> INCOMPLETE (fdo#103713)
      fi-skl-gvtdvm:      NOTRUN -> INCOMPLETE (fdo#105600)
      fi-cfl-guc:         NOTRUN -> INCOMPLETE (fdo#106693)
      fi-skl-guc:         NOTRUN -> INCOMPLETE (fdo#106693)
      fi-elk-e7500:       NOTRUN -> INCOMPLETE (fdo#103989)
      fi-kbl-guc:         NOTRUN -> INCOMPLETE (fdo#106693)
      fi-byt-n2820:       NOTRUN -> INCOMPLETE (fdo#102657)
      fi-byt-clapper:     NOTRUN -> INCOMPLETE (fdo#102657)
      fi-bxt-dsi:         NOTRUN -> INCOMPLETE (fdo#103927)

    igt@gem_exec_suspend@basic-s3:
      fi-bdw-samus:       PASS -> INCOMPLETE (fdo#107773)
      fi-kbl-soraka:      NOTRUN -> INCOMPLETE (fdo#107556, fdo#107774)

    
    ==== Possible fixes ====

    igt@gem_exec_suspend@basic-s3:
      fi-kbl-guc:         INCOMPLETE (fdo#106693) -> PASS

    
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  fdo#102657 https://bugs.freedesktop.org/show_bug.cgi?id=102657
  fdo#103359 https://bugs.freedesktop.org/show_bug.cgi?id=103359
  fdo#103713 https://bugs.freedesktop.org/show_bug.cgi?id=103713
  fdo#103927 https://bugs.freedesktop.org/show_bug.cgi?id=103927
  fdo#103989 https://bugs.freedesktop.org/show_bug.cgi?id=103989
  fdo#105600 https://bugs.freedesktop.org/show_bug.cgi?id=105600
  fdo#106693 https://bugs.freedesktop.org/show_bug.cgi?id=106693
  fdo#107556 https://bugs.freedesktop.org/show_bug.cgi?id=107556
  fdo#107773 https://bugs.freedesktop.org/show_bug.cgi?id=107773
  fdo#107774 https://bugs.freedesktop.org/show_bug.cgi?id=107774
  k.org#198133 https://bugzilla.kernel.org/show_bug.cgi?id=198133


== Participating hosts (47 -> 43) ==

  Additional (1): fi-kbl-soraka 
  Missing    (5): fi-bsw-cyan fi-ilk-m540 fi-byt-squawks fi-icl-u2 fi-hsw-4200u 


== Build changes ==

    * Linux: CI_DRM_4875 -> Patchwork_10279

  CI_DRM_4875: 5f099906779ca138ecc32e0c6b4b2860b71716f4 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_4650: a6e21812d100dce68450727e79fc09e0c0033683 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_10279: 0dea7c2d42cf26a561e014b8b0786500da0835f9 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

0dea7c2d42cf drm/i915: Bump gen7+ fb size limits to 16kx16k
8b2eedbf6d7d drm/i915: Bump gen4+ fb stride limit to 256KiB
43dcb570fdec drm/i915: Overcome display engine stride limits via GTT remapping
762ba8d98203 drm/i915/selftests: Add live vma selftest
fa6cf412dafd drm/i915/selftests: Add mock selftest for remapped vmas
96eb024e5885 drm/i915: Add a new "remapped" gtt_view
dafb1135ed8c drm/i915: Decouple SKL stride units from intel_fb_stride_alignment()
fd6c4b3fa1e9 drm/i915: Make sure fb gtt offsets stay within 32bits

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_10279/issues.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 5/8] drm/i915/selftests: Add live vma selftest
  2018-09-25 19:37 ` [PATCH v3 5/8] drm/i915/selftests: Add live vma selftest Ville Syrjala
  2018-09-25 20:19   ` Chris Wilson
@ 2018-09-25 20:40   ` Chris Wilson
  2018-09-26  9:33     ` Ville Syrjälä
  2018-10-23 16:03   ` [PATCH v4 " Ville Syrjala
  2 siblings, 1 reply; 62+ messages in thread
From: Chris Wilson @ 2018-09-25 20:40 UTC (permalink / raw)
  To: Ville Syrjala, intel-gfx

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
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* ✓ Fi.CI.IGT: success for drm/i915: GTT remapping for display
  2018-09-25 19:37 [PATCH v3 0/8] drm/i915: GTT remapping for display Ville Syrjala
                   ` (10 preceding siblings ...)
  2018-09-25 20:30 ` ✓ Fi.CI.BAT: success " Patchwork
@ 2018-09-25 21:21 ` Patchwork
  2018-10-23 16:21 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: GTT remapping for display (rev5) Patchwork
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 62+ messages in thread
From: Patchwork @ 2018-09-25 21:21 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: GTT remapping for display
URL   : https://patchwork.freedesktop.org/series/50165/
State : success

== Summary ==

= CI Bug Log - changes from CI_DRM_4875_full -> Patchwork_10279_full =

== Summary - WARNING ==

  Minor unknown changes coming with Patchwork_10279_full need to be verified
  manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_10279_full, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  

== Possible new issues ==

  Here are the unknown changes that may have been introduced in Patchwork_10279_full:

  === IGT changes ===

    ==== Warnings ====

    igt@drv_selftest@live_coherency:
      shard-kbl:          PASS -> SKIP +8
      shard-apl:          PASS -> SKIP +8

    igt@drv_selftest@live_gem:
      shard-hsw:          PASS -> SKIP +8
      shard-glk:          PASS -> SKIP +8

    
== Known issues ==

  Here are the changes found in Patchwork_10279_full that come from known issues:

  === IGT changes ===

    ==== Issues hit ====

    {igt@drv_selftest@live_vma}:
      shard-glk:          NOTRUN -> INCOMPLETE (k.org#198133, fdo#103359)
      shard-hsw:          NOTRUN -> INCOMPLETE (fdo#103540)
      shard-kbl:          NOTRUN -> INCOMPLETE (fdo#103665)
      shard-apl:          NOTRUN -> INCOMPLETE (fdo#103927)

    igt@kms_busy@extended-modeset-hang-newfb-with-reset-render-b:
      shard-snb:          NOTRUN -> DMESG-WARN (fdo#107956) +1

    igt@kms_setmode@basic:
      shard-apl:          PASS -> FAIL (fdo#99912)
      shard-snb:          NOTRUN -> FAIL (fdo#99912)

    
    ==== Possible fixes ====

    igt@kms_busy@extended-modeset-hang-newfb-with-reset-render-b:
      shard-hsw:          DMESG-WARN (fdo#107956) -> PASS

    igt@kms_busy@extended-pageflip-modeset-hang-oldfb-render-b:
      shard-apl:          DMESG-WARN (fdo#107956) -> PASS

    igt@kms_cursor_legacy@cursora-vs-flipa-toggle:
      shard-glk:          DMESG-WARN (fdo#105763, fdo#106538) -> PASS +1

    igt@kms_flip@flip-vs-expired-vblank:
      shard-glk:          FAIL (fdo#105363) -> PASS

    
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  fdo#103359 https://bugs.freedesktop.org/show_bug.cgi?id=103359
  fdo#103540 https://bugs.freedesktop.org/show_bug.cgi?id=103540
  fdo#103665 https://bugs.freedesktop.org/show_bug.cgi?id=103665
  fdo#103927 https://bugs.freedesktop.org/show_bug.cgi?id=103927
  fdo#105363 https://bugs.freedesktop.org/show_bug.cgi?id=105363
  fdo#105763 https://bugs.freedesktop.org/show_bug.cgi?id=105763
  fdo#106538 https://bugs.freedesktop.org/show_bug.cgi?id=106538
  fdo#107956 https://bugs.freedesktop.org/show_bug.cgi?id=107956
  fdo#99912 https://bugs.freedesktop.org/show_bug.cgi?id=99912
  k.org#198133 https://bugzilla.kernel.org/show_bug.cgi?id=198133


== Participating hosts (6 -> 5) ==

  Missing    (1): shard-skl 


== Build changes ==

    * Linux: CI_DRM_4875 -> Patchwork_10279

  CI_DRM_4875: 5f099906779ca138ecc32e0c6b4b2860b71716f4 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_4650: a6e21812d100dce68450727e79fc09e0c0033683 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_10279: 0dea7c2d42cf26a561e014b8b0786500da0835f9 @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_10279/shards.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 3/8] drm/i915: Add a new "remapped" gtt_view
  2018-09-25 19:37 ` [PATCH v3 3/8] drm/i915: Add a new "remapped" gtt_view Ville Syrjala
@ 2018-09-26  7:50   ` Tvrtko Ursulin
  2018-10-01 15:03     ` Ville Syrjälä
  2018-10-23 16:02   ` [PATCH v4 " Ville Syrjala
  1 sibling, 1 reply; 62+ messages in thread
From: Tvrtko Ursulin @ 2018-09-26  7:50 UTC (permalink / raw)
  To: Ville Syrjala, intel-gfx


On 25/09/2018 20:37, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> To overcome display engine stride limits we'll want to remap the
> pages in the GTT. To that end we need a new gtt_view type which
> is just like the "rotated" type except not rotated.
> 
> v2: Use intel_remapped_plane_info base type
>      s/unused/unused_mbz/ (Chris)
>      Separate BUILD_BUG_ON()s (Chris)
>      Use I915_GTT_PAGE_SIZE (Chris)
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>   drivers/gpu/drm/i915/i915_debugfs.c       | 12 ++++
>   drivers/gpu/drm/i915/i915_gem_gtt.c       | 91 +++++++++++++++++++++++++++++++
>   drivers/gpu/drm/i915/i915_gem_gtt.h       | 25 +++++++--
>   drivers/gpu/drm/i915/i915_vma.c           |  6 +-
>   drivers/gpu/drm/i915/i915_vma.h           |  3 +
>   drivers/gpu/drm/i915/intel_display.c      | 11 ++++
>   drivers/gpu/drm/i915/intel_drv.h          |  1 +
>   drivers/gpu/drm/i915/selftests/i915_vma.c |  6 +-
>   8 files changed, 147 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index b4744a68cd88..edb9f6f3c0cf 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -196,6 +196,18 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
>   					   vma->ggtt_view.rotated.plane[1].offset);
>   				break;
>   
> +			case I915_GGTT_VIEW_REMAPPED:
> +				seq_printf(m, ", remapped [(%ux%u, stride=%u, offset=%u), (%ux%u, stride=%u, offset=%u)]",
> +					   vma->ggtt_view.remapped.plane[0].width,
> +					   vma->ggtt_view.remapped.plane[0].height,
> +					   vma->ggtt_view.remapped.plane[0].stride,
> +					   vma->ggtt_view.remapped.plane[0].offset,
> +					   vma->ggtt_view.remapped.plane[1].width,
> +					   vma->ggtt_view.remapped.plane[1].height,
> +					   vma->ggtt_view.remapped.plane[1].stride,
> +					   vma->ggtt_view.remapped.plane[1].offset);
> +				break;
> +
>   			default:
>   				MISSING_CASE(vma->ggtt_view.type);
>   				break;
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index f6c7ab413081..e4d49c345c81 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -3798,6 +3798,92 @@ intel_rotate_pages(struct intel_rotation_info *rot_info,
>   	return ERR_PTR(ret);
>   }
>   
> +static struct scatterlist *
> +remap_pages(const dma_addr_t *in, unsigned int offset,
> +	    unsigned int width, unsigned int height,
> +	    unsigned int stride,
> +	    struct sg_table *st, struct scatterlist *sg)
> +{
> +	unsigned int column, row;
> +
> +	for (row = 0; row < height; row++) {
> +		for (column = 0; column < width; column++) {
> +			st->nents++;
> +			/* We don't need the pages, but need to initialize
> +			 * the entries so the sg list can be happily traversed.
> +			 * The only thing we need are DMA addresses.
> +			 */
> +			sg_set_page(sg, NULL, I915_GTT_PAGE_SIZE, 0);
> +			sg_dma_address(sg) = in[offset + column];
> +			sg_dma_len(sg) = I915_GTT_PAGE_SIZE;
> +			sg = sg_next(sg);

For this type of remapping you could I think potentially get some 
decreased memory use benefits by coalescing the consecutive addresses 
into single sg entries. If I understood correctly what it's doing at 
least.. Since framebuffers could have a good chance to have been 
initially allocated in larger than page size chunks.

If you decide to do that, then...

> +		}
> +		offset += stride;
> +	}
> +
> +	return sg;
> +}
> +
> +static noinline struct sg_table *
> +intel_remap_pages(struct intel_remapped_info *rem_info,
> +		  struct drm_i915_gem_object *obj)
> +{
> +	const unsigned long n_pages = obj->base.size / I915_GTT_PAGE_SIZE;
> +	unsigned int size = intel_remapped_info_size(rem_info);
> +	struct sgt_iter sgt_iter;
> +	dma_addr_t dma_addr;
> +	unsigned long i;
> +	dma_addr_t *page_addr_list;
> +	struct sg_table *st;
> +	struct scatterlist *sg;
> +	int ret = -ENOMEM;
> +
> +	/* Allocate a temporary list of source pages for random access. */
> +	page_addr_list = kvmalloc_array(n_pages,
> +					sizeof(dma_addr_t),
> +					GFP_KERNEL);
> +	if (!page_addr_list)
> +		return ERR_PTR(ret);
> +
> +	/* Allocate target SG list. */
> +	st = kmalloc(sizeof(*st), GFP_KERNEL);
> +	if (!st)
> +		goto err_st_alloc;
> +
> +	ret = sg_alloc_table(st, size, GFP_KERNEL);
> +	if (ret)
> +		goto err_sg_alloc;
> +
> +	/* Populate source page list from the object. */
> +	i = 0;
> +	for_each_sgt_dma(dma_addr, sgt_iter, obj->mm.pages)
> +		page_addr_list[i++] = dma_addr;
> +
> +	GEM_BUG_ON(i != n_pages);
> +	st->nents = 0;
> +	sg = st->sgl;
> +
> +	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
> +		sg = remap_pages(page_addr_list, rem_info->plane[i].offset,
> +				 rem_info->plane[i].width, rem_info->plane[i].height,
> +				 rem_info->plane[i].stride, st, sg);
> +	}
> +
> +	kvfree(page_addr_list);
> +

... put i915_sg_trim here to lose the trailing end of unused sg entries.

One more thing, do you really need random access for this 
transformation? Or you could walk the sg list as it is? Just if you hit 
a too long chunk you need to copy a trimmed version over and know where 
to continue for the next row. If doable it would be better than having 
to kvmalloc_array.

Regards,

Tvrtko

> +	return st;
> +
> +err_sg_alloc:
> +	kfree(st);
> +err_st_alloc:
> +	kvfree(page_addr_list);
> +
> +	DRM_DEBUG_DRIVER("Failed to create remapped mapping for object size %zu! (%ux%u tiles, %u pages)\n",
> +			 obj->base.size, rem_info->plane[0].width, rem_info->plane[0].height, size);
> +
> +	return ERR_PTR(ret);
> +}
> +
>   static noinline struct sg_table *
>   intel_partial_pages(const struct i915_ggtt_view *view,
>   		    struct drm_i915_gem_object *obj)
> @@ -3874,6 +3960,11 @@ i915_get_ggtt_vma_pages(struct i915_vma *vma)
>   			intel_rotate_pages(&vma->ggtt_view.rotated, vma->obj);
>   		break;
>   
> +	case I915_GGTT_VIEW_REMAPPED:
> +		vma->pages =
> +			intel_remap_pages(&vma->ggtt_view.remapped, vma->obj);
> +		break;
> +
>   	case I915_GGTT_VIEW_PARTIAL:
>   		vma->pages = intel_partial_pages(&vma->ggtt_view, vma->obj);
>   		break;
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
> index 7e2af5f4f39b..69a22f57e6ca 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.h
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
> @@ -160,11 +160,18 @@ typedef u64 gen8_ppgtt_pml4e_t;
>   
>   struct sg_table;
>   
> +struct intel_remapped_plane_info {
> +	/* in gtt pages */
> +	unsigned int width, height, stride, offset;
> +} __packed;
> +
> +struct intel_remapped_info {
> +	struct intel_remapped_plane_info plane[2];
> +	unsigned int unused_mbz;
> +} __packed;
> +
>   struct intel_rotation_info {
> -	struct intel_rotation_plane_info {
> -		/* tiles */
> -		unsigned int width, height, stride, offset;
> -	} plane[2];
> +	struct intel_remapped_plane_info plane[2];
>   } __packed;
>   
>   struct intel_partial_info {
> @@ -176,12 +183,20 @@ enum i915_ggtt_view_type {
>   	I915_GGTT_VIEW_NORMAL = 0,
>   	I915_GGTT_VIEW_ROTATED = sizeof(struct intel_rotation_info),
>   	I915_GGTT_VIEW_PARTIAL = sizeof(struct intel_partial_info),
> +	I915_GGTT_VIEW_REMAPPED = sizeof(struct intel_remapped_info),
>   };
>   
>   static inline void assert_i915_gem_gtt_types(void)
>   {
>   	BUILD_BUG_ON(sizeof(struct intel_rotation_info) != 8*sizeof(unsigned int));
>   	BUILD_BUG_ON(sizeof(struct intel_partial_info) != sizeof(u64) + sizeof(unsigned int));
> +	BUILD_BUG_ON(sizeof(struct intel_remapped_info) != 9*sizeof(unsigned int));
> +
> +	/* Check that rotation/remapped shares offsets for simplicity */
> +	BUILD_BUG_ON(offsetof(struct intel_remapped_info, plane[0]) !=
> +		     offsetof(struct intel_rotation_info, plane[0]));
> +	BUILD_BUG_ON(offsetofend(struct intel_remapped_info, plane[1]) !=
> +		     offsetofend(struct intel_rotation_info, plane[1]));
>   
>   	/* As we encode the size of each branch inside the union into its type,
>   	 * we have to be careful that each branch has a unique size.
> @@ -190,6 +205,7 @@ static inline void assert_i915_gem_gtt_types(void)
>   	case I915_GGTT_VIEW_NORMAL:
>   	case I915_GGTT_VIEW_PARTIAL:
>   	case I915_GGTT_VIEW_ROTATED:
> +	case I915_GGTT_VIEW_REMAPPED:
>   		/* gcc complains if these are identical cases */
>   		break;
>   	}
> @@ -201,6 +217,7 @@ struct i915_ggtt_view {
>   		/* Members need to contain no holes/padding */
>   		struct intel_partial_info partial;
>   		struct intel_rotation_info rotated;
> +		struct intel_remapped_info remapped;
>   	};
>   };
>   
> diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
> index 31efc971a3a8..1793c702ab94 100644
> --- a/drivers/gpu/drm/i915/i915_vma.c
> +++ b/drivers/gpu/drm/i915/i915_vma.c
> @@ -164,6 +164,9 @@ vma_create(struct drm_i915_gem_object *obj,
>   		} else if (view->type == I915_GGTT_VIEW_ROTATED) {
>   			vma->size = intel_rotation_info_size(&view->rotated);
>   			vma->size <<= PAGE_SHIFT;
> +		} else if (view->type == I915_GGTT_VIEW_REMAPPED) {
> +			vma->size = intel_remapped_info_size(&view->remapped);
> +			vma->size <<= PAGE_SHIFT;
>   		}
>   	}
>   
> @@ -464,7 +467,8 @@ void __i915_vma_set_map_and_fenceable(struct i915_vma *vma)
>   	 * Explicitly disable for rotated VMA since the display does not
>   	 * need the fence and the VMA is not accessible to other users.
>   	 */
> -	if (vma->ggtt_view.type == I915_GGTT_VIEW_ROTATED)
> +	if (vma->ggtt_view.type == I915_GGTT_VIEW_ROTATED ||
> +	    vma->ggtt_view.type == I915_GGTT_VIEW_REMAPPED)
>   		return;
>   
>   	fenceable = (vma->node.size >= vma->fence_size &&
> diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
> index 4f7c1c7599f4..64cf029c028a 100644
> --- a/drivers/gpu/drm/i915/i915_vma.h
> +++ b/drivers/gpu/drm/i915/i915_vma.h
> @@ -265,8 +265,11 @@ i915_vma_compare(struct i915_vma *vma,
>   	 */
>   	BUILD_BUG_ON(I915_GGTT_VIEW_NORMAL >= I915_GGTT_VIEW_PARTIAL);
>   	BUILD_BUG_ON(I915_GGTT_VIEW_PARTIAL >= I915_GGTT_VIEW_ROTATED);
> +	BUILD_BUG_ON(I915_GGTT_VIEW_ROTATED >= I915_GGTT_VIEW_REMAPPED);
>   	BUILD_BUG_ON(offsetof(typeof(*view), rotated) !=
>   		     offsetof(typeof(*view), partial));
> +	BUILD_BUG_ON(offsetof(typeof(*view), rotated) !=
> +		     offsetof(typeof(*view), remapped));
>   	return memcmp(&vma->ggtt_view.partial, &view->partial, view->type);
>   }
>   
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 1fe5cf3ed062..4f9f519ccd46 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2006,6 +2006,17 @@ unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info
>   	return size;
>   }
>   
> +unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info)
> +{
> +	unsigned int size = 0;
> +	int i;
> +
> +	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++)
> +		size += rem_info->plane[i].width * rem_info->plane[i].height;
> +
> +	return size;
> +}
> +
>   static void
>   intel_fill_fb_ggtt_view(struct i915_ggtt_view *view,
>   			const struct drm_framebuffer *fb,
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 4fcba99d12c0..a88a16b74f24 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1503,6 +1503,7 @@ unsigned int intel_fb_xy_to_linear(int x, int y,
>   void intel_add_fb_offsets(int *x, int *y,
>   			  const struct intel_plane_state *state, int plane);
>   unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info);
> +unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info);
>   bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv);
>   void intel_mark_busy(struct drm_i915_private *dev_priv);
>   void intel_mark_idle(struct drm_i915_private *dev_priv);
> diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c
> index ffa74290e054..4fc49c27f13c 100644
> --- a/drivers/gpu/drm/i915/selftests/i915_vma.c
> +++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
> @@ -395,8 +395,8 @@ assert_rotated(struct drm_i915_gem_object *obj,
>   	return sg;
>   }
>   
> -static unsigned int rotated_size(const struct intel_rotation_plane_info *a,
> -				 const struct intel_rotation_plane_info *b)
> +static unsigned int rotated_size(const struct intel_remapped_plane_info *a,
> +				 const struct intel_remapped_plane_info *b)
>   {
>   	return a->width * a->height + b->width * b->height;
>   }
> @@ -406,7 +406,7 @@ static int igt_vma_rotate(void *arg)
>   	struct drm_i915_private *i915 = arg;
>   	struct i915_address_space *vm = &i915->ggtt.vm;
>   	struct drm_i915_gem_object *obj;
> -	const struct intel_rotation_plane_info planes[] = {
> +	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 },
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 8/8] drm/i915: Bump gen7+ fb size limits to 16kx16k
  2018-09-25 19:59   ` Chris Wilson
@ 2018-09-26  9:25     ` Ville Syrjälä
  0 siblings, 0 replies; 62+ messages in thread
From: Ville Syrjälä @ 2018-09-26  9:25 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

On Tue, Sep 25, 2018 at 08:59:03PM +0100, Chris Wilson wrote:
> Quoting Ville Syrjala (2018-09-25 20:37:14)
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > With gtt remapping in place we can use arbitrarily large
> > framebuffers. Let's bump the limits to 16kx16k on gen7+.
> > The limit was chosen to match the maximum 2D surface size
> > of the 3D engine.
> > 
> > With the remapping we could easily go higher than that for the
> > display engine. However the modesetting ddx will blindly assume
> > it can handle whatever is reported via kms. The oversized
> > buffer dimensions are not caught by glamor nor Mesa until
> > finally an assert will trip when genxml attempts to pack the
> > SURFACE_STATE. So we pick a safe limit to avoid the X server
> > from crashing (or potentially misbehaving if the genxml asserts
> > are compiled out).
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_display.c | 18 ++++++++++++------
> >  1 file changed, 12 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index d533a6086169..241b9f6cbb76 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -15524,16 +15524,22 @@ int intel_modeset_init(struct drm_device *dev)
> >                 }
> >         }
> >  
> > -       /* maximum framebuffer dimensions */
> > -       if (IS_GEN2(dev_priv)) {
> > -               dev->mode_config.max_width = 2048;
> > -               dev->mode_config.max_height = 2048;
> > +       /*
> > +        * Maximum framebuffer dimensions, chosen to match
> > +        * the maximum render engine surface size on gen4+.
> > +        */
> > +       if (INTEL_GEN(dev_priv) >= 7) {
> > +               dev->mode_config.max_width = 16384;
> > +               dev->mode_config.max_height = 16384;
> > +       } else if (INTEL_GEN(dev_priv) >= 4) {
> > +               dev->mode_config.max_width = 8192;
> > +               dev->mode_config.max_height = 8192;
> >         } else if (IS_GEN3(dev_priv)) {
> >                 dev->mode_config.max_width = 4096;
> >                 dev->mode_config.max_height = 4096;
> 
> You have the same problem on gen3 then. 3D pipeline is restricted to 2k.
> Different rules for different gen. :(

Yeah. That is a bit annoying. It's a pre-existing condition though
so I think we can safely assume that no one wants to use glamor
on gen3. Also IIRC Mesa/i915 has a sw fallback for this so at
least it shouldn't totally explode if someone did try it.

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 1/8] drm/i915: Make sure fb gtt offsets stay within 32bits
  2018-09-25 20:29   ` Chris Wilson
@ 2018-09-26  9:27     ` Ville Syrjälä
  2018-09-26 20:09       ` Chris Wilson
  0 siblings, 1 reply; 62+ messages in thread
From: Ville Syrjälä @ 2018-09-26  9:27 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

On Tue, Sep 25, 2018 at 09:29:44PM +0100, Chris Wilson wrote:
> Quoting Ville Syrjala (2018-09-25 20:37:07)
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Let's try to make sure the fb offset computations never hit
> > an integer overflow by making sure the entire fb stays
> > below 32bits. framebuffer_check() in the core already does
> > the same check, but as it doesn't know about tiling some things
> > can slip through. Repeat the check in the driver with tiling
> > taken into account.
> > 
> > v2: Use add_overflows() after massaging it to work for me (Chris)
> 
> Oh, it had fallen out of use.
>  
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_utils.h    |  8 ++++----
> >  drivers/gpu/drm/i915/intel_display.c | 18 +++++++++++++++++-
> >  2 files changed, 21 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h
> > index 395dd2511568..c43ec993fa90 100644
> > --- a/drivers/gpu/drm/i915/i915_utils.h
> > +++ b/drivers/gpu/drm/i915/i915_utils.h
> > @@ -44,13 +44,13 @@
> >                              __stringify(x), (long)(x))
> >  
> >  #if defined(GCC_VERSION) && GCC_VERSION >= 70000
> > -#define add_overflows(A, B) \
> > -       __builtin_add_overflow_p((A), (B), (typeof((A) + (B)))0)
> > +#define add_overflows(A, B, C) \
> > +       __builtin_add_overflow_p((A), (B), (C))
> >  #else
> > -#define add_overflows(A, B) ({ \
> > +#define add_overflows(A, B, C) ({ \
> >         typeof(A) a = (A); \
> >         typeof(B) b = (B); \
> > -       a + b < a; \
> > +       (typeof(C))(a + b) < a; \
> >  })
> >  #endif
> >  
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 4c5c2b39e65c..a3ae24e03316 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -2400,10 +2400,26 @@ static int intel_fb_offset_to_xy(int *x, int *y,
> >                                  int color_plane)
> >  {
> >         struct drm_i915_private *dev_priv = to_i915(fb->dev);
> > +       unsigned int height;
> >  
> >         if (fb->modifier != DRM_FORMAT_MOD_LINEAR &&
> > -           fb->offsets[color_plane] % intel_tile_size(dev_priv))
> > +           fb->offsets[color_plane] % intel_tile_size(dev_priv)) {
> > +               DRM_DEBUG_KMS("Misaligned offset 0x%08x for color plane %d\n",
> > +                             fb->offsets[color_plane], color_plane);
> >                 return -EINVAL;
> > +       }
> > +
> > +       height = drm_framebuffer_plane_height(fb->height, fb, color_plane);
> > +       height = ALIGN(height, intel_tile_height(fb, color_plane));
> > +
> > +       /* Catch potential overflows early */
> > +       if (add_overflows(mul_u32_u32(height, fb->pitches[color_plane]),
> > +                         fb->offsets[color_plane], (u32)0)) {
> 
> Should we just pass type? Atm we aren't using the value for anything.
> Then it would be add_overflows_t(a, b, T) with the obvious wrapping for
> add_overflows(a, b). Although to be consistent with min_t, perhaps
> add_overflows_t(T, a, b).

Indeed, that does seem a bit more consistent with existing stuff.

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 4/8] drm/i915/selftests: Add mock selftest for remapped vmas
  2018-09-25 20:22   ` Chris Wilson
@ 2018-09-26  9:28     ` Ville Syrjälä
  0 siblings, 0 replies; 62+ messages in thread
From: Ville Syrjälä @ 2018-09-26  9:28 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

On Tue, Sep 25, 2018 at 09:22:34PM +0100, Chris Wilson wrote:
> Quoting Ville Syrjala (2018-09-25 20:37:10)
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Extend the rotated vma mock selftest to cover remapped vmas as
> > well.
> > 
> > TODO: reindent the loops I guess? Left like this for now to
> > ease review
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/selftests/i915_vma.c | 70 ++++++++++++++++++++++++++++---
> >  1 file changed, 65 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c
> > index 4fc49c27f13c..6e84e5cc93a0 100644
> > --- a/drivers/gpu/drm/i915/selftests/i915_vma.c
> > +++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
> > @@ -58,7 +58,7 @@ static bool assert_vma(struct i915_vma *vma,
> >  static struct i915_vma *
> >  checked_vma_instance(struct drm_i915_gem_object *obj,
> >                      struct i915_address_space *vm,
> > -                    struct i915_ggtt_view *view)
> > +                    const struct i915_ggtt_view *view)
> >  {
> >         struct i915_vma *vma;
> >         bool ok = true;
> > @@ -395,13 +395,63 @@ assert_rotated(struct drm_i915_gem_object *obj,
> >         return sg;
> >  }
> >  
> > +static unsigned long remapped_index(const struct intel_remapped_info *r,
> > +                                   unsigned int n,
> > +                                   unsigned int x,
> > +                                   unsigned int y)
> > +{
> > +       return (r->plane[n].stride * y +
> > +               r->plane[n].offset + x);
> > +}
> > +
> > +static struct scatterlist *
> > +assert_remapped(struct drm_i915_gem_object *obj,
> > +               const struct intel_remapped_info *r, unsigned int n,
> > +               struct scatterlist *sg)
> > +{
> > +       unsigned int x, y;
> > +
> > +       for (y = 0; y < r->plane[n].height; y++) {
> > +               for (x = 0; x < r->plane[n].width; x++) {
> > +                       unsigned long src_idx;
> > +                       dma_addr_t src;
> > +
> > +                       if (!sg) {
> > +                               pr_err("Invalid sg table: too short at plane %d, (%d, %d)!\n",
> > +                                      n, x, y);
> > +                               return ERR_PTR(-EINVAL);
> > +                       }
> > +
> > +                       src_idx = remapped_index(r, n, x, y);
> > +                       src = i915_gem_object_get_dma_address(obj, src_idx);
> > +
> > +                       if (sg_dma_len(sg) != PAGE_SIZE) {
> > +                               pr_err("Invalid sg.length, found %d, expected %lu for remapped page (%d, %d) [src index %lu]\n",
> > +                                      sg_dma_len(sg), PAGE_SIZE,
> > +                                      x, y, src_idx);
> > +                               return ERR_PTR(-EINVAL);
> > +                       }
> > +
> > +                       if (sg_dma_address(sg) != src) {
> > +                               pr_err("Invalid address for remapped page (%d, %d) [src index %lu]\n",
> > +                                      x, y, src_idx);
> > +                               return ERR_PTR(-EINVAL);
> > +                       }
> > +
> > +                       sg = sg_next(sg);
> > +               }
> > +       }
> > +
> > +       return sg;
> > +}
> > +
> >  static unsigned int rotated_size(const struct intel_remapped_plane_info *a,
> >                                  const struct intel_remapped_plane_info *b)
> >  {
> >         return a->width * a->height + b->width * b->height;
> >  }
> >  
> > -static int igt_vma_rotate(void *arg)
> > +static int igt_vma_rotate_remap(void *arg)
> >  {
> >         struct drm_i915_private *i915 = arg;
> >         struct i915_address_space *vm = &i915->ggtt.vm;
> > @@ -424,6 +474,11 @@ static int igt_vma_rotate(void *arg)
> >                 { .width = 6, .height = 4, .stride = 6 },
> >                 { }
> >         }, *a, *b;
> > +       enum i915_ggtt_view_type types[] = {
> > +               I915_GGTT_VIEW_ROTATED,
> > +               I915_GGTT_VIEW_REMAPPED,
> > +               0,
> > +       }, *t;
> >         const unsigned int max_pages = 64;
> >         int err = -ENOMEM;
> >  
> > @@ -435,6 +490,7 @@ static int igt_vma_rotate(void *arg)
> >         if (IS_ERR(obj))
> >                 goto out;
> >  
> > +       for (t = types; *t; t++) {
> >         for (a = planes; a->width; a++) {
> >                 for (b = planes + ARRAY_SIZE(planes); b-- != planes; ) {
> >                         struct i915_ggtt_view view;
> > @@ -445,7 +501,7 @@ static int igt_vma_rotate(void *arg)
> >                         GEM_BUG_ON(max_offset > max_pages);
> >                         max_offset = max_pages - max_offset;
> >  
> > -                       view.type = I915_GGTT_VIEW_ROTATED;
> > +                       view.type = *t;
> >                         view.rotated.plane[0] = *a;
> >                         view.rotated.plane[1] = *b;
> >  
> > @@ -495,7 +551,10 @@ static int igt_vma_rotate(void *arg)
> >  
> >                                         sg = vma->pages->sgl;
> >                                         for (n = 0; n < ARRAY_SIZE(view.rotated.plane); n++) {
> > -                                               sg = assert_rotated(obj, &view.rotated, n, sg);
> > +                                               if (view.type == I915_GGTT_VIEW_ROTATED)
> > +                                                       sg = assert_rotated(obj, &view.rotated, n, sg);
> > +                                               else
> > +                                                       sg = assert_remapped(obj, &view.remapped, n, sg);
> >                                                 if (IS_ERR(sg)) {
> >                                                         pr_err("Inconsistent VMA pages for plane %d: [(%d, %d, %d, %d), (%d, %d, %d, %d)]\n", n,
> 
> Looks ok, but we need to include the remap type in the error statement
> if we either want to decypher what may have gone wrong. I see the
> assert callbacks do include the hint, but adding an extra "%s" here may
> help.

I thought I had it there already. Must have dropped it
accidentally. I'll add it back.

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 5/8] drm/i915/selftests: Add live vma selftest
  2018-09-25 20:40   ` Chris Wilson
@ 2018-09-26  9:33     ` Ville Syrjälä
  0 siblings, 0 replies; 62+ messages in thread
From: Ville Syrjälä @ 2018-09-26  9:33 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

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

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 1/8] drm/i915: Make sure fb gtt offsets stay within 32bits
  2018-09-26  9:27     ` Ville Syrjälä
@ 2018-09-26 20:09       ` Chris Wilson
  2018-09-27 12:24         ` Ville Syrjälä
  0 siblings, 1 reply; 62+ messages in thread
From: Chris Wilson @ 2018-09-26 20:09 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

Quoting Ville Syrjälä (2018-09-26 10:27:40)
> On Tue, Sep 25, 2018 at 09:29:44PM +0100, Chris Wilson wrote:
> > Quoting Ville Syrjala (2018-09-25 20:37:07)
> > > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > +       /* Catch potential overflows early */
> > > +       if (add_overflows(mul_u32_u32(height, fb->pitches[color_plane]),
> > > +                         fb->offsets[color_plane], (u32)0)) {
> > 
> > Should we just pass type? Atm we aren't using the value for anything.
> > Then it would be add_overflows_t(a, b, T) with the obvious wrapping for
> > add_overflows(a, b). Although to be consistent with min_t, perhaps
> > add_overflows_t(T, a, b).
> 
> Indeed, that does seem a bit more consistent with existing stuff.

To further upset the apple cart, I spotted there is now a
include/linux/overflows.h which does everything completely different.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 1/8] drm/i915: Make sure fb gtt offsets stay within 32bits
  2018-09-26 20:09       ` Chris Wilson
@ 2018-09-27 12:24         ` Ville Syrjälä
  0 siblings, 0 replies; 62+ messages in thread
From: Ville Syrjälä @ 2018-09-27 12:24 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

On Wed, Sep 26, 2018 at 09:09:31PM +0100, Chris Wilson wrote:
> Quoting Ville Syrjälä (2018-09-26 10:27:40)
> > On Tue, Sep 25, 2018 at 09:29:44PM +0100, Chris Wilson wrote:
> > > Quoting Ville Syrjala (2018-09-25 20:37:07)
> > > > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > +       /* Catch potential overflows early */
> > > > +       if (add_overflows(mul_u32_u32(height, fb->pitches[color_plane]),
> > > > +                         fb->offsets[color_plane], (u32)0)) {
> > > 
> > > Should we just pass type? Atm we aren't using the value for anything.
> > > Then it would be add_overflows_t(a, b, T) with the obvious wrapping for
> > > add_overflows(a, b). Although to be consistent with min_t, perhaps
> > > add_overflows_t(T, a, b).
> > 
> > Indeed, that does seem a bit more consistent with existing stuff.
> 
> To further upset the apple cart, I spotted there is now a
> include/linux/overflows.h which does everything completely different.

Yeah. That one seems to enforce that the type of both operands is the
same which means to use it here I'd have to do the mul overflow check
separately. Also no __builtin_foo_p() used so would need to
actually store the result somewhere.

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 7/8] drm/i915: Bump gen4+ fb stride limit to 256KiB
  2018-09-25 20:13   ` Chris Wilson
@ 2018-09-28 19:19     ` Ville Syrjälä
  0 siblings, 0 replies; 62+ messages in thread
From: Ville Syrjälä @ 2018-09-28 19:19 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

On Tue, Sep 25, 2018 at 09:13:41PM +0100, Chris Wilson wrote:
> Quoting Ville Syrjala (2018-09-25 20:37:13)
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > With gtt remapping plugged in we can simply raise the stride
> > limit on gen4+. Let's just arbitraily pick 256 KiB as the limit.
> > 
> > No remapping CCS because the virtual address of each page actually
> > matters due to the new hash mode
> > (WaCompressedResourceDisplayNewHashMode:skl,kbl etc.), and no remapping
> > on gen2/3 due to lack of fence on the remapped vma.
> > 
> > v2: Rebase due to is_ccs_modifier()
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_display.c | 13 +++++++++++++
> >  1 file changed, 13 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index eca873653fea..d533a6086169 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -2522,6 +2522,19 @@ static
> >  u32 intel_fb_max_stride(struct drm_i915_private *dev_priv,
> >                         u32 pixel_format, u64 modifier)
> >  {
> > +       /*
> > +        * Arbitrary limit for gen4+. We can deal with any page
> > +        * aligned stride via GTT remapping. Gen2/3 need a fence
> > +        * for tiled scanout which the remapped vma won't have,
> > +        * so we don't allow remapping on those platforms.
> > +        *
> > +        * Also the new hash mode we use for CCS isn't compatible
> > +        * with remapping as the virtual address of the pages
> > +        * affects the compressed data.
> > +        */
> > +       if (INTEL_GEN(dev_priv) >= 4 && !is_ccs_modifier(modifier))
> > +               return 256*1024;
> 
> Worth using SZ_256K ?

That question prompted me to try a mass conversion. Managed to trick
cocci to do it more or less. Unfortunately it was a bit too greedy
and converted non-pot sizes as well. Not sure how much the SZ_ things
are worth due to that reason.

I couldn't get cocci to do what I wanted with ## so had to resort
to python. I get the impression that ## only works with identifiers.
Here's what I ended with in case anyone wants to evaluate for
themselves:

@find_m@
constant old_m =~ "^[0-9]*$";
@@
old_m * 1024 * 1024

@script:python rename_m@
input << find_m.old_m;
new_m;
@@
def do_rename_m(name):
    return "SZ_" + name + "M"
coccinelle.new_m = cocci.make_ident(do_rename_m(input))
print coccinelle.new_m

@@
constant find_m.old_m;
identifier rename_m.new_m;
@@
- old_m * 1024 * 1024
+ new_m

@find_k@
constant old_k =~ "^[0-9]*$";
@@
old_k * 1024

@@
@@
- 1024 * 1024
+ SZ_1M

@script:python rename_k@
input << find_k.old_k;
new_k;
@@
def do_rename_k(name):
    return "SZ_" + name + "K"
coccinelle.new_k = cocci.make_ident(do_rename_k(input))
print coccinelle.new_k

@@
constant find_k.old_k;
identifier rename_k.new_k;
@@
- old_k * 1024
+ new_k

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 3/8] drm/i915: Add a new "remapped" gtt_view
  2018-09-26  7:50   ` Tvrtko Ursulin
@ 2018-10-01 15:03     ` Ville Syrjälä
  2018-10-01 15:12       ` Chris Wilson
  0 siblings, 1 reply; 62+ messages in thread
From: Ville Syrjälä @ 2018-10-01 15:03 UTC (permalink / raw)
  To: Tvrtko Ursulin; +Cc: intel-gfx

On Wed, Sep 26, 2018 at 08:50:25AM +0100, Tvrtko Ursulin wrote:
> 
> On 25/09/2018 20:37, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > To overcome display engine stride limits we'll want to remap the
> > pages in the GTT. To that end we need a new gtt_view type which
> > is just like the "rotated" type except not rotated.
> > 
> > v2: Use intel_remapped_plane_info base type
> >      s/unused/unused_mbz/ (Chris)
> >      Separate BUILD_BUG_ON()s (Chris)
> >      Use I915_GTT_PAGE_SIZE (Chris)
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >   drivers/gpu/drm/i915/i915_debugfs.c       | 12 ++++
> >   drivers/gpu/drm/i915/i915_gem_gtt.c       | 91 +++++++++++++++++++++++++++++++
> >   drivers/gpu/drm/i915/i915_gem_gtt.h       | 25 +++++++--
> >   drivers/gpu/drm/i915/i915_vma.c           |  6 +-
> >   drivers/gpu/drm/i915/i915_vma.h           |  3 +
> >   drivers/gpu/drm/i915/intel_display.c      | 11 ++++
> >   drivers/gpu/drm/i915/intel_drv.h          |  1 +
> >   drivers/gpu/drm/i915/selftests/i915_vma.c |  6 +-
> >   8 files changed, 147 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> > index b4744a68cd88..edb9f6f3c0cf 100644
> > --- a/drivers/gpu/drm/i915/i915_debugfs.c
> > +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> > @@ -196,6 +196,18 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
> >   					   vma->ggtt_view.rotated.plane[1].offset);
> >   				break;
> >   
> > +			case I915_GGTT_VIEW_REMAPPED:
> > +				seq_printf(m, ", remapped [(%ux%u, stride=%u, offset=%u), (%ux%u, stride=%u, offset=%u)]",
> > +					   vma->ggtt_view.remapped.plane[0].width,
> > +					   vma->ggtt_view.remapped.plane[0].height,
> > +					   vma->ggtt_view.remapped.plane[0].stride,
> > +					   vma->ggtt_view.remapped.plane[0].offset,
> > +					   vma->ggtt_view.remapped.plane[1].width,
> > +					   vma->ggtt_view.remapped.plane[1].height,
> > +					   vma->ggtt_view.remapped.plane[1].stride,
> > +					   vma->ggtt_view.remapped.plane[1].offset);
> > +				break;
> > +
> >   			default:
> >   				MISSING_CASE(vma->ggtt_view.type);
> >   				break;
> > diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> > index f6c7ab413081..e4d49c345c81 100644
> > --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> > +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> > @@ -3798,6 +3798,92 @@ intel_rotate_pages(struct intel_rotation_info *rot_info,
> >   	return ERR_PTR(ret);
> >   }
> >   
> > +static struct scatterlist *
> > +remap_pages(const dma_addr_t *in, unsigned int offset,
> > +	    unsigned int width, unsigned int height,
> > +	    unsigned int stride,
> > +	    struct sg_table *st, struct scatterlist *sg)
> > +{
> > +	unsigned int column, row;
> > +
> > +	for (row = 0; row < height; row++) {
> > +		for (column = 0; column < width; column++) {
> > +			st->nents++;
> > +			/* We don't need the pages, but need to initialize
> > +			 * the entries so the sg list can be happily traversed.
> > +			 * The only thing we need are DMA addresses.
> > +			 */
> > +			sg_set_page(sg, NULL, I915_GTT_PAGE_SIZE, 0);
> > +			sg_dma_address(sg) = in[offset + column];
> > +			sg_dma_len(sg) = I915_GTT_PAGE_SIZE;
> > +			sg = sg_next(sg);
> 
> For this type of remapping you could I think potentially get some 
> decreased memory use benefits by coalescing the consecutive addresses 
> into single sg entries. If I understood correctly what it's doing at 
> least.. Since framebuffers could have a good chance to have been 
> initially allocated in larger than page size chunks.
> 
> If you decide to do that, then...
> 
> > +		}
> > +		offset += stride;
> > +	}
> > +
> > +	return sg;
> > +}
> > +
> > +static noinline struct sg_table *
> > +intel_remap_pages(struct intel_remapped_info *rem_info,
> > +		  struct drm_i915_gem_object *obj)
> > +{
> > +	const unsigned long n_pages = obj->base.size / I915_GTT_PAGE_SIZE;
> > +	unsigned int size = intel_remapped_info_size(rem_info);
> > +	struct sgt_iter sgt_iter;
> > +	dma_addr_t dma_addr;
> > +	unsigned long i;
> > +	dma_addr_t *page_addr_list;
> > +	struct sg_table *st;
> > +	struct scatterlist *sg;
> > +	int ret = -ENOMEM;
> > +
> > +	/* Allocate a temporary list of source pages for random access. */
> > +	page_addr_list = kvmalloc_array(n_pages,
> > +					sizeof(dma_addr_t),
> > +					GFP_KERNEL);
> > +	if (!page_addr_list)
> > +		return ERR_PTR(ret);
> > +
> > +	/* Allocate target SG list. */
> > +	st = kmalloc(sizeof(*st), GFP_KERNEL);
> > +	if (!st)
> > +		goto err_st_alloc;
> > +
> > +	ret = sg_alloc_table(st, size, GFP_KERNEL);
> > +	if (ret)
> > +		goto err_sg_alloc;
> > +
> > +	/* Populate source page list from the object. */
> > +	i = 0;
> > +	for_each_sgt_dma(dma_addr, sgt_iter, obj->mm.pages)
> > +		page_addr_list[i++] = dma_addr;
> > +
> > +	GEM_BUG_ON(i != n_pages);
> > +	st->nents = 0;
> > +	sg = st->sgl;
> > +
> > +	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
> > +		sg = remap_pages(page_addr_list, rem_info->plane[i].offset,
> > +				 rem_info->plane[i].width, rem_info->plane[i].height,
> > +				 rem_info->plane[i].stride, st, sg);
> > +	}
> > +
> > +	kvfree(page_addr_list);
> > +
> 
> ... put i915_sg_trim here to lose the trailing end of unused sg entries.

Yeah, I guess that makes sense.

> 
> One more thing, do you really need random access for this 
> transformation? Or you could walk the sg list as it is? Just if you hit 
> a too long chunk you need to copy a trimmed version over and know where 
> to continue for the next row. If doable it would be better than having 
> to kvmalloc_array.

I think Chris suggested just using i915_gem_object_get_dma_address()
here. But I'm not sure why we're not using it for rotate_pages()
as well.

> 
> Regards,
> 
> Tvrtko
> 
> > +	return st;
> > +
> > +err_sg_alloc:
> > +	kfree(st);
> > +err_st_alloc:
> > +	kvfree(page_addr_list);
> > +
> > +	DRM_DEBUG_DRIVER("Failed to create remapped mapping for object size %zu! (%ux%u tiles, %u pages)\n",
> > +			 obj->base.size, rem_info->plane[0].width, rem_info->plane[0].height, size);
> > +
> > +	return ERR_PTR(ret);
> > +}
> > +
> >   static noinline struct sg_table *
> >   intel_partial_pages(const struct i915_ggtt_view *view,
> >   		    struct drm_i915_gem_object *obj)
> > @@ -3874,6 +3960,11 @@ i915_get_ggtt_vma_pages(struct i915_vma *vma)
> >   			intel_rotate_pages(&vma->ggtt_view.rotated, vma->obj);
> >   		break;
> >   
> > +	case I915_GGTT_VIEW_REMAPPED:
> > +		vma->pages =
> > +			intel_remap_pages(&vma->ggtt_view.remapped, vma->obj);
> > +		break;
> > +
> >   	case I915_GGTT_VIEW_PARTIAL:
> >   		vma->pages = intel_partial_pages(&vma->ggtt_view, vma->obj);
> >   		break;
> > diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
> > index 7e2af5f4f39b..69a22f57e6ca 100644
> > --- a/drivers/gpu/drm/i915/i915_gem_gtt.h
> > +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
> > @@ -160,11 +160,18 @@ typedef u64 gen8_ppgtt_pml4e_t;
> >   
> >   struct sg_table;
> >   
> > +struct intel_remapped_plane_info {
> > +	/* in gtt pages */
> > +	unsigned int width, height, stride, offset;
> > +} __packed;
> > +
> > +struct intel_remapped_info {
> > +	struct intel_remapped_plane_info plane[2];
> > +	unsigned int unused_mbz;
> > +} __packed;
> > +
> >   struct intel_rotation_info {
> > -	struct intel_rotation_plane_info {
> > -		/* tiles */
> > -		unsigned int width, height, stride, offset;
> > -	} plane[2];
> > +	struct intel_remapped_plane_info plane[2];
> >   } __packed;
> >   
> >   struct intel_partial_info {
> > @@ -176,12 +183,20 @@ enum i915_ggtt_view_type {
> >   	I915_GGTT_VIEW_NORMAL = 0,
> >   	I915_GGTT_VIEW_ROTATED = sizeof(struct intel_rotation_info),
> >   	I915_GGTT_VIEW_PARTIAL = sizeof(struct intel_partial_info),
> > +	I915_GGTT_VIEW_REMAPPED = sizeof(struct intel_remapped_info),
> >   };
> >   
> >   static inline void assert_i915_gem_gtt_types(void)
> >   {
> >   	BUILD_BUG_ON(sizeof(struct intel_rotation_info) != 8*sizeof(unsigned int));
> >   	BUILD_BUG_ON(sizeof(struct intel_partial_info) != sizeof(u64) + sizeof(unsigned int));
> > +	BUILD_BUG_ON(sizeof(struct intel_remapped_info) != 9*sizeof(unsigned int));
> > +
> > +	/* Check that rotation/remapped shares offsets for simplicity */
> > +	BUILD_BUG_ON(offsetof(struct intel_remapped_info, plane[0]) !=
> > +		     offsetof(struct intel_rotation_info, plane[0]));
> > +	BUILD_BUG_ON(offsetofend(struct intel_remapped_info, plane[1]) !=
> > +		     offsetofend(struct intel_rotation_info, plane[1]));
> >   
> >   	/* As we encode the size of each branch inside the union into its type,
> >   	 * we have to be careful that each branch has a unique size.
> > @@ -190,6 +205,7 @@ static inline void assert_i915_gem_gtt_types(void)
> >   	case I915_GGTT_VIEW_NORMAL:
> >   	case I915_GGTT_VIEW_PARTIAL:
> >   	case I915_GGTT_VIEW_ROTATED:
> > +	case I915_GGTT_VIEW_REMAPPED:
> >   		/* gcc complains if these are identical cases */
> >   		break;
> >   	}
> > @@ -201,6 +217,7 @@ struct i915_ggtt_view {
> >   		/* Members need to contain no holes/padding */
> >   		struct intel_partial_info partial;
> >   		struct intel_rotation_info rotated;
> > +		struct intel_remapped_info remapped;
> >   	};
> >   };
> >   
> > diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
> > index 31efc971a3a8..1793c702ab94 100644
> > --- a/drivers/gpu/drm/i915/i915_vma.c
> > +++ b/drivers/gpu/drm/i915/i915_vma.c
> > @@ -164,6 +164,9 @@ vma_create(struct drm_i915_gem_object *obj,
> >   		} else if (view->type == I915_GGTT_VIEW_ROTATED) {
> >   			vma->size = intel_rotation_info_size(&view->rotated);
> >   			vma->size <<= PAGE_SHIFT;
> > +		} else if (view->type == I915_GGTT_VIEW_REMAPPED) {
> > +			vma->size = intel_remapped_info_size(&view->remapped);
> > +			vma->size <<= PAGE_SHIFT;
> >   		}
> >   	}
> >   
> > @@ -464,7 +467,8 @@ void __i915_vma_set_map_and_fenceable(struct i915_vma *vma)
> >   	 * Explicitly disable for rotated VMA since the display does not
> >   	 * need the fence and the VMA is not accessible to other users.
> >   	 */
> > -	if (vma->ggtt_view.type == I915_GGTT_VIEW_ROTATED)
> > +	if (vma->ggtt_view.type == I915_GGTT_VIEW_ROTATED ||
> > +	    vma->ggtt_view.type == I915_GGTT_VIEW_REMAPPED)
> >   		return;
> >   
> >   	fenceable = (vma->node.size >= vma->fence_size &&
> > diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
> > index 4f7c1c7599f4..64cf029c028a 100644
> > --- a/drivers/gpu/drm/i915/i915_vma.h
> > +++ b/drivers/gpu/drm/i915/i915_vma.h
> > @@ -265,8 +265,11 @@ i915_vma_compare(struct i915_vma *vma,
> >   	 */
> >   	BUILD_BUG_ON(I915_GGTT_VIEW_NORMAL >= I915_GGTT_VIEW_PARTIAL);
> >   	BUILD_BUG_ON(I915_GGTT_VIEW_PARTIAL >= I915_GGTT_VIEW_ROTATED);
> > +	BUILD_BUG_ON(I915_GGTT_VIEW_ROTATED >= I915_GGTT_VIEW_REMAPPED);
> >   	BUILD_BUG_ON(offsetof(typeof(*view), rotated) !=
> >   		     offsetof(typeof(*view), partial));
> > +	BUILD_BUG_ON(offsetof(typeof(*view), rotated) !=
> > +		     offsetof(typeof(*view), remapped));
> >   	return memcmp(&vma->ggtt_view.partial, &view->partial, view->type);
> >   }
> >   
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 1fe5cf3ed062..4f9f519ccd46 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -2006,6 +2006,17 @@ unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info
> >   	return size;
> >   }
> >   
> > +unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info)
> > +{
> > +	unsigned int size = 0;
> > +	int i;
> > +
> > +	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++)
> > +		size += rem_info->plane[i].width * rem_info->plane[i].height;
> > +
> > +	return size;
> > +}
> > +
> >   static void
> >   intel_fill_fb_ggtt_view(struct i915_ggtt_view *view,
> >   			const struct drm_framebuffer *fb,
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index 4fcba99d12c0..a88a16b74f24 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -1503,6 +1503,7 @@ unsigned int intel_fb_xy_to_linear(int x, int y,
> >   void intel_add_fb_offsets(int *x, int *y,
> >   			  const struct intel_plane_state *state, int plane);
> >   unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info);
> > +unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info);
> >   bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv);
> >   void intel_mark_busy(struct drm_i915_private *dev_priv);
> >   void intel_mark_idle(struct drm_i915_private *dev_priv);
> > diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c
> > index ffa74290e054..4fc49c27f13c 100644
> > --- a/drivers/gpu/drm/i915/selftests/i915_vma.c
> > +++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
> > @@ -395,8 +395,8 @@ assert_rotated(struct drm_i915_gem_object *obj,
> >   	return sg;
> >   }
> >   
> > -static unsigned int rotated_size(const struct intel_rotation_plane_info *a,
> > -				 const struct intel_rotation_plane_info *b)
> > +static unsigned int rotated_size(const struct intel_remapped_plane_info *a,
> > +				 const struct intel_remapped_plane_info *b)
> >   {
> >   	return a->width * a->height + b->width * b->height;
> >   }
> > @@ -406,7 +406,7 @@ static int igt_vma_rotate(void *arg)
> >   	struct drm_i915_private *i915 = arg;
> >   	struct i915_address_space *vm = &i915->ggtt.vm;
> >   	struct drm_i915_gem_object *obj;
> > -	const struct intel_rotation_plane_info planes[] = {
> > +	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 },
> > 

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 3/8] drm/i915: Add a new "remapped" gtt_view
  2018-10-01 15:03     ` Ville Syrjälä
@ 2018-10-01 15:12       ` Chris Wilson
  2018-10-01 15:27         ` Ville Syrjälä
  2018-10-01 15:35         ` Tvrtko Ursulin
  0 siblings, 2 replies; 62+ messages in thread
From: Chris Wilson @ 2018-10-01 15:12 UTC (permalink / raw)
  To: Tvrtko Ursulin, Ville Syrjälä; +Cc: intel-gfx

Quoting Ville Syrjälä (2018-10-01 16:03:30)
> On Wed, Sep 26, 2018 at 08:50:25AM +0100, Tvrtko Ursulin wrote:
> > 
> > On 25/09/2018 20:37, Ville Syrjala wrote:
> > One more thing, do you really need random access for this 
> > transformation? Or you could walk the sg list as it is? Just if you hit 
> > a too long chunk you need to copy a trimmed version over and know where 
> > to continue for the next row. If doable it would be better than having 
> > to kvmalloc_array.
> 
> I think Chris suggested just using i915_gem_object_get_dma_address()
> here. But I'm not sure why we're not using it for rotate_pages()
> as well.

Tvrtko is opposed to populating the obj->mm.pages cache with no defined
release point. I say the mempressure and shrinker should to the right
thing, but it's a big if.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 3/8] drm/i915: Add a new "remapped" gtt_view
  2018-10-01 15:12       ` Chris Wilson
@ 2018-10-01 15:27         ` Ville Syrjälä
  2018-10-01 15:37           ` Chris Wilson
  2018-10-01 15:38           ` Tvrtko Ursulin
  2018-10-01 15:35         ` Tvrtko Ursulin
  1 sibling, 2 replies; 62+ messages in thread
From: Ville Syrjälä @ 2018-10-01 15:27 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

On Mon, Oct 01, 2018 at 04:12:09PM +0100, Chris Wilson wrote:
> Quoting Ville Syrjälä (2018-10-01 16:03:30)
> > On Wed, Sep 26, 2018 at 08:50:25AM +0100, Tvrtko Ursulin wrote:
> > > 
> > > On 25/09/2018 20:37, Ville Syrjala wrote:
> > > One more thing, do you really need random access for this 
> > > transformation? Or you could walk the sg list as it is? Just if you hit 
> > > a too long chunk you need to copy a trimmed version over and know where 
> > > to continue for the next row. If doable it would be better than having 
> > > to kvmalloc_array.
> > 
> > I think Chris suggested just using i915_gem_object_get_dma_address()
> > here. But I'm not sure why we're not using it for rotate_pages()
> > as well.
> 
> Tvrtko is opposed to populating the obj->mm.pages cache with no defined
> release point. I say the mempressure and shrinker should to the right
> thing, but it's a big if.

OK.

Well, looks to me like i915_gem_object_get_dma_address() is the
only convenient looking thing for iterating the pages without
arowning the code in irrelevant details about sgs and whatnot.
I suppose it should be possible to write some helpers that avoid
all that and don't need the temp array, but I'm not really
motivated enough to do that myself.

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 3/8] drm/i915: Add a new "remapped" gtt_view
  2018-10-01 15:12       ` Chris Wilson
  2018-10-01 15:27         ` Ville Syrjälä
@ 2018-10-01 15:35         ` Tvrtko Ursulin
  1 sibling, 0 replies; 62+ messages in thread
From: Tvrtko Ursulin @ 2018-10-01 15:35 UTC (permalink / raw)
  To: Chris Wilson, Ville Syrjälä; +Cc: intel-gfx


On 01/10/2018 16:12, Chris Wilson wrote:
> Quoting Ville Syrjälä (2018-10-01 16:03:30)
>> On Wed, Sep 26, 2018 at 08:50:25AM +0100, Tvrtko Ursulin wrote:
>>>
>>> On 25/09/2018 20:37, Ville Syrjala wrote:
>>> One more thing, do you really need random access for this
>>> transformation? Or you could walk the sg list as it is? Just if you hit
>>> a too long chunk you need to copy a trimmed version over and know where
>>> to continue for the next row. If doable it would be better than having
>>> to kvmalloc_array.
>>
>> I think Chris suggested just using i915_gem_object_get_dma_address()
>> here. But I'm not sure why we're not using it for rotate_pages()
>> as well.
> 
> Tvrtko is opposed to populating the obj->mm.pages cache with no defined
> release point. I say the mempressure and shrinker should to the right
> thing, but it's a big if.

Wasn't there some compromise we agreed last time? Like that you would 
just add an API to drop the cache? So users like this one and rotation, 
where it is known to be very unlikely the cache would be used again, 
would be able to drop it immediately after remapping?

But maybe you had an argument that the cache could be used after all? So 
pread/pwrite on framebuffers likely? Relocations wouldn't be. Is there 
something else?

Maybe we should resolve this since it's been going for a very long time. :)

Regards,

Tvrtko
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 3/8] drm/i915: Add a new "remapped" gtt_view
  2018-10-01 15:27         ` Ville Syrjälä
@ 2018-10-01 15:37           ` Chris Wilson
  2018-10-01 15:48             ` Tvrtko Ursulin
  2018-10-01 15:38           ` Tvrtko Ursulin
  1 sibling, 1 reply; 62+ messages in thread
From: Chris Wilson @ 2018-10-01 15:37 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

Quoting Ville Syrjälä (2018-10-01 16:27:43)
> On Mon, Oct 01, 2018 at 04:12:09PM +0100, Chris Wilson wrote:
> > Quoting Ville Syrjälä (2018-10-01 16:03:30)
> > > On Wed, Sep 26, 2018 at 08:50:25AM +0100, Tvrtko Ursulin wrote:
> > > > 
> > > > On 25/09/2018 20:37, Ville Syrjala wrote:
> > > > One more thing, do you really need random access for this 
> > > > transformation? Or you could walk the sg list as it is? Just if you hit 
> > > > a too long chunk you need to copy a trimmed version over and know where 
> > > > to continue for the next row. If doable it would be better than having 
> > > > to kvmalloc_array.
> > > 
> > > I think Chris suggested just using i915_gem_object_get_dma_address()
> > > here. But I'm not sure why we're not using it for rotate_pages()
> > > as well.
> > 
> > Tvrtko is opposed to populating the obj->mm.pages cache with no defined
> > release point. I say the mempressure and shrinker should to the right
> > thing, but it's a big if.
> 
> OK.
> 
> Well, looks to me like i915_gem_object_get_dma_address() is the
> only convenient looking thing for iterating the pages without
> arowning the code in irrelevant details about sgs and whatnot.
> I suppose it should be possible to write some helpers that avoid
> all that and don't need the temp array, but I'm not really
> motivated enough to do that myself.

Keep it simple and use get_dma_address(). We can find ways to throw away
the cache later if need be.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 3/8] drm/i915: Add a new "remapped" gtt_view
  2018-10-01 15:27         ` Ville Syrjälä
  2018-10-01 15:37           ` Chris Wilson
@ 2018-10-01 15:38           ` Tvrtko Ursulin
  1 sibling, 0 replies; 62+ messages in thread
From: Tvrtko Ursulin @ 2018-10-01 15:38 UTC (permalink / raw)
  To: Ville Syrjälä, Chris Wilson; +Cc: intel-gfx


On 01/10/2018 16:27, Ville Syrjälä wrote:
> On Mon, Oct 01, 2018 at 04:12:09PM +0100, Chris Wilson wrote:
>> Quoting Ville Syrjälä (2018-10-01 16:03:30)
>>> On Wed, Sep 26, 2018 at 08:50:25AM +0100, Tvrtko Ursulin wrote:
>>>>
>>>> On 25/09/2018 20:37, Ville Syrjala wrote:
>>>> One more thing, do you really need random access for this
>>>> transformation? Or you could walk the sg list as it is? Just if you hit
>>>> a too long chunk you need to copy a trimmed version over and know where
>>>> to continue for the next row. If doable it would be better than having
>>>> to kvmalloc_array.
>>>
>>> I think Chris suggested just using i915_gem_object_get_dma_address()
>>> here. But I'm not sure why we're not using it for rotate_pages()
>>> as well.
>>
>> Tvrtko is opposed to populating the obj->mm.pages cache with no defined
>> release point. I say the mempressure and shrinker should to the right
>> thing, but it's a big if.
> 
> OK.
> 
> Well, looks to me like i915_gem_object_get_dma_address() is the
> only convenient looking thing for iterating the pages without
> arowning the code in irrelevant details about sgs and whatnot.
> I suppose it should be possible to write some helpers that avoid
> all that and don't need the temp array, but I'm not really
> motivated enough to do that myself.

That's fine by me, I primarily suggested you could coalesce and trim 
when done.

Regards,

Tvrtko
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 3/8] drm/i915: Add a new "remapped" gtt_view
  2018-10-01 15:37           ` Chris Wilson
@ 2018-10-01 15:48             ` Tvrtko Ursulin
  2018-10-05 18:42               ` Ville Syrjälä
  0 siblings, 1 reply; 62+ messages in thread
From: Tvrtko Ursulin @ 2018-10-01 15:48 UTC (permalink / raw)
  To: Chris Wilson, Ville Syrjälä; +Cc: intel-gfx


On 01/10/2018 16:37, Chris Wilson wrote:
> Quoting Ville Syrjälä (2018-10-01 16:27:43)
>> On Mon, Oct 01, 2018 at 04:12:09PM +0100, Chris Wilson wrote:
>>> Quoting Ville Syrjälä (2018-10-01 16:03:30)
>>>> On Wed, Sep 26, 2018 at 08:50:25AM +0100, Tvrtko Ursulin wrote:
>>>>>
>>>>> On 25/09/2018 20:37, Ville Syrjala wrote:
>>>>> One more thing, do you really need random access for this
>>>>> transformation? Or you could walk the sg list as it is? Just if you hit
>>>>> a too long chunk you need to copy a trimmed version over and know where
>>>>> to continue for the next row. If doable it would be better than having
>>>>> to kvmalloc_array.
>>>>
>>>> I think Chris suggested just using i915_gem_object_get_dma_address()
>>>> here. But I'm not sure why we're not using it for rotate_pages()
>>>> as well.
>>>
>>> Tvrtko is opposed to populating the obj->mm.pages cache with no defined
>>> release point. I say the mempressure and shrinker should to the right
>>> thing, but it's a big if.
>>
>> OK.
>>
>> Well, looks to me like i915_gem_object_get_dma_address() is the
>> only convenient looking thing for iterating the pages without
>> arowning the code in irrelevant details about sgs and whatnot.
>> I suppose it should be possible to write some helpers that avoid
>> all that and don't need the temp array, but I'm not really
>> motivated enough to do that myself.
> 
> Keep it simple and use get_dma_address(). We can find ways to throw away
> the cache later if need be.

I'd do it straight away. I think cache for a large framebuffer, the kind 
which needs remapping could be quite big! Even the more fragmented 
memory the bigger the cache, and so if it sticks around pointlessly for 
the lifetime of the framebuffer it is a double whammy.

Regards,

Tvrtko
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 3/8] drm/i915: Add a new "remapped" gtt_view
  2018-10-01 15:48             ` Tvrtko Ursulin
@ 2018-10-05 18:42               ` Ville Syrjälä
  2018-10-09  8:24                 ` Tvrtko Ursulin
  0 siblings, 1 reply; 62+ messages in thread
From: Ville Syrjälä @ 2018-10-05 18:42 UTC (permalink / raw)
  To: Tvrtko Ursulin; +Cc: intel-gfx

On Mon, Oct 01, 2018 at 04:48:21PM +0100, Tvrtko Ursulin wrote:
> 
> On 01/10/2018 16:37, Chris Wilson wrote:
> > Quoting Ville Syrjälä (2018-10-01 16:27:43)
> >> On Mon, Oct 01, 2018 at 04:12:09PM +0100, Chris Wilson wrote:
> >>> Quoting Ville Syrjälä (2018-10-01 16:03:30)
> >>>> On Wed, Sep 26, 2018 at 08:50:25AM +0100, Tvrtko Ursulin wrote:
> >>>>>
> >>>>> On 25/09/2018 20:37, Ville Syrjala wrote:
> >>>>> One more thing, do you really need random access for this
> >>>>> transformation? Or you could walk the sg list as it is? Just if you hit
> >>>>> a too long chunk you need to copy a trimmed version over and know where
> >>>>> to continue for the next row. If doable it would be better than having
> >>>>> to kvmalloc_array.
> >>>>
> >>>> I think Chris suggested just using i915_gem_object_get_dma_address()
> >>>> here. But I'm not sure why we're not using it for rotate_pages()
> >>>> as well.
> >>>
> >>> Tvrtko is opposed to populating the obj->mm.pages cache with no defined
> >>> release point. I say the mempressure and shrinker should to the right
> >>> thing, but it's a big if.
> >>
> >> OK.
> >>
> >> Well, looks to me like i915_gem_object_get_dma_address() is the
> >> only convenient looking thing for iterating the pages without
> >> arowning the code in irrelevant details about sgs and whatnot.
> >> I suppose it should be possible to write some helpers that avoid
> >> all that and don't need the temp array, but I'm not really
> >> motivated enough to do that myself.
> > 
> > Keep it simple and use get_dma_address(). We can find ways to throw away
> > the cache later if need be.
> 
> I'd do it straight away. I think cache for a large framebuffer, the kind 
> which needs remapping could be quite big! Even the more fragmented 
> memory the bigger the cache, and so if it sticks around pointlessly for 
> the lifetime of the framebuffer it is a double whammy.

The tree is indexed with the ggtt offset so memory fragmentation
shouldn't matter I think. Or did I totally miss something?

The relative overhead should be highest for a single page object
(576/4096 = ~15%). For big objects it should be something around
.2% AFAICS.

The shrinker can throw the cache out for non-pinned fbs. Looks
like it does consider all fbs active so it tries not to kick
them out as the first thing though. For pinned fbs the cache
would remain allocated forever however.

Keeping the cache around should be great for panning within
large remapped fbs. Although I suppose that panning isn't a
very common use case these days

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 3/8] drm/i915: Add a new "remapped" gtt_view
  2018-10-05 18:42               ` Ville Syrjälä
@ 2018-10-09  8:24                 ` Tvrtko Ursulin
  2018-10-09  8:41                   ` Chris Wilson
  2018-10-09 11:54                   ` Ville Syrjälä
  0 siblings, 2 replies; 62+ messages in thread
From: Tvrtko Ursulin @ 2018-10-09  8:24 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx


On 05/10/2018 19:42, Ville Syrjälä wrote:
> On Mon, Oct 01, 2018 at 04:48:21PM +0100, Tvrtko Ursulin wrote:
>>
>> On 01/10/2018 16:37, Chris Wilson wrote:
>>> Quoting Ville Syrjälä (2018-10-01 16:27:43)
>>>> On Mon, Oct 01, 2018 at 04:12:09PM +0100, Chris Wilson wrote:
>>>>> Quoting Ville Syrjälä (2018-10-01 16:03:30)
>>>>>> On Wed, Sep 26, 2018 at 08:50:25AM +0100, Tvrtko Ursulin wrote:
>>>>>>>
>>>>>>> On 25/09/2018 20:37, Ville Syrjala wrote:
>>>>>>> One more thing, do you really need random access for this
>>>>>>> transformation? Or you could walk the sg list as it is? Just if you hit
>>>>>>> a too long chunk you need to copy a trimmed version over and know where
>>>>>>> to continue for the next row. If doable it would be better than having
>>>>>>> to kvmalloc_array.
>>>>>>
>>>>>> I think Chris suggested just using i915_gem_object_get_dma_address()
>>>>>> here. But I'm not sure why we're not using it for rotate_pages()
>>>>>> as well.
>>>>>
>>>>> Tvrtko is opposed to populating the obj->mm.pages cache with no defined
>>>>> release point. I say the mempressure and shrinker should to the right
>>>>> thing, but it's a big if.
>>>>
>>>> OK.
>>>>
>>>> Well, looks to me like i915_gem_object_get_dma_address() is the
>>>> only convenient looking thing for iterating the pages without
>>>> arowning the code in irrelevant details about sgs and whatnot.
>>>> I suppose it should be possible to write some helpers that avoid
>>>> all that and don't need the temp array, but I'm not really
>>>> motivated enough to do that myself.
>>>
>>> Keep it simple and use get_dma_address(). We can find ways to throw away
>>> the cache later if need be.
>>
>> I'd do it straight away. I think cache for a large framebuffer, the kind
>> which needs remapping could be quite big! Even the more fragmented
>> memory the bigger the cache, and so if it sticks around pointlessly for
>> the lifetime of the framebuffer it is a double whammy.
> 
> The tree is indexed with the ggtt offset so memory fragmentation
> shouldn't matter I think. Or did I totally miss something?

I think it is indexed by page index, but the number of tree entries 
depends on the number of sg chunks, which in turn depends on the system 
memory fragmentation. Consecutive pages are stored as "exceptional" 
entries so that is more efficient IIRC, but TBH I don't remember how 
many of those it can store before it needs a new tree node. Anyways, if 
I am not completely mistaken then the tree metadata size is proportional 
to backing store fragmentation, and secondary proportional to object 
size. (Due exceptional entry spill.)

> The relative overhead should be highest for a single page object
> (576/4096 = ~15%). For big objects it should be something around
> .2% AFAICS.

It is a bit annoying since radix tree does not have a helper to tell us 
the number of allocated nodes. I don't remember how I measure this last 
time.. Will try to recall.

> 
> The shrinker can throw the cache out for non-pinned fbs. Looks
> like it does consider all fbs active so it tries not to kick
> them out as the first thing though. For pinned fbs the cache
> would remain allocated forever however.
> 
> Keeping the cache around should be great for panning within
> large remapped fbs. Although I suppose that panning isn't a
> very common use case these days

We could just export __i915_gem_object_reset_page_iter, and look at the 
required locking when used from rotate/remap and I'd be happy to start 
with. But okay, let me first try to recall/re-measure how big are these 
trees...

Regards,

Tvrtko



_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 3/8] drm/i915: Add a new "remapped" gtt_view
  2018-10-09  8:24                 ` Tvrtko Ursulin
@ 2018-10-09  8:41                   ` Chris Wilson
  2018-10-09 11:54                   ` Ville Syrjälä
  1 sibling, 0 replies; 62+ messages in thread
From: Chris Wilson @ 2018-10-09  8:41 UTC (permalink / raw)
  To: Ville Syrjälä, Tvrtko Ursulin; +Cc: intel-gfx

Quoting Tvrtko Ursulin (2018-10-09 09:24:33)
> 
> On 05/10/2018 19:42, Ville Syrjälä wrote:
> > On Mon, Oct 01, 2018 at 04:48:21PM +0100, Tvrtko Ursulin wrote:
> >>
> >> On 01/10/2018 16:37, Chris Wilson wrote:
> >>> Quoting Ville Syrjälä (2018-10-01 16:27:43)
> >>>> On Mon, Oct 01, 2018 at 04:12:09PM +0100, Chris Wilson wrote:
> >>>>> Quoting Ville Syrjälä (2018-10-01 16:03:30)
> >>>>>> On Wed, Sep 26, 2018 at 08:50:25AM +0100, Tvrtko Ursulin wrote:
> >>>>>>>
> >>>>>>> On 25/09/2018 20:37, Ville Syrjala wrote:
> >>>>>>> One more thing, do you really need random access for this
> >>>>>>> transformation? Or you could walk the sg list as it is? Just if you hit
> >>>>>>> a too long chunk you need to copy a trimmed version over and know where
> >>>>>>> to continue for the next row. If doable it would be better than having
> >>>>>>> to kvmalloc_array.
> >>>>>>
> >>>>>> I think Chris suggested just using i915_gem_object_get_dma_address()
> >>>>>> here. But I'm not sure why we're not using it for rotate_pages()
> >>>>>> as well.
> >>>>>
> >>>>> Tvrtko is opposed to populating the obj->mm.pages cache with no defined
> >>>>> release point. I say the mempressure and shrinker should to the right
> >>>>> thing, but it's a big if.
> >>>>
> >>>> OK.
> >>>>
> >>>> Well, looks to me like i915_gem_object_get_dma_address() is the
> >>>> only convenient looking thing for iterating the pages without
> >>>> arowning the code in irrelevant details about sgs and whatnot.
> >>>> I suppose it should be possible to write some helpers that avoid
> >>>> all that and don't need the temp array, but I'm not really
> >>>> motivated enough to do that myself.
> >>>
> >>> Keep it simple and use get_dma_address(). We can find ways to throw away
> >>> the cache later if need be.
> >>
> >> I'd do it straight away. I think cache for a large framebuffer, the kind
> >> which needs remapping could be quite big! Even the more fragmented
> >> memory the bigger the cache, and so if it sticks around pointlessly for
> >> the lifetime of the framebuffer it is a double whammy.
> > 
> > The tree is indexed with the ggtt offset so memory fragmentation
> > shouldn't matter I think. Or did I totally miss something?
> 
> I think it is indexed by page index, but the number of tree entries 
> depends on the number of sg chunks, which in turn depends on the system 
> memory fragmentation. Consecutive pages are stored as "exceptional" 
> entries so that is more efficient IIRC, but TBH I don't remember how 
> many of those it can store before it needs a new tree node. Anyways, if 
> I am not completely mistaken then the tree metadata size is proportional 
> to backing store fragmentation, and secondary proportional to object 
> size. (Due exceptional entry spill.)
> 
> > The relative overhead should be highest for a single page object
> > (576/4096 = ~15%). For big objects it should be something around
> > .2% AFAICS.
> 
> It is a bit annoying since radix tree does not have a helper to tell us 
> the number of allocated nodes. I don't remember how I measure this last 
> time.. Will try to recall.
> 
> > 
> > The shrinker can throw the cache out for non-pinned fbs. Looks
> > like it does consider all fbs active so it tries not to kick
> > them out as the first thing though. For pinned fbs the cache
> > would remain allocated forever however.
> > 
> > Keeping the cache around should be great for panning within
> > large remapped fbs. Although I suppose that panning isn't a
> > very common use case these days
> 
> We could just export __i915_gem_object_reset_page_iter, and look at the 
> required locking when used from rotate/remap and I'd be happy to start 
> with. But okay, let me first try to recall/re-measure how big are these 
> trees...

Also, the should soon be a generic radix tree implementation so we
should be free to swap out the tagged nodes for a more streamline tree.

But seriously, the sole argument is that you dislike the caching and you
even argue against the caching in situations like this where the cache
will be reused! (Since we need to remap each crtc into the single fb.)

We can't even randomly call reset_page_iter unless you know you own the
iter (since it's common to everyone who has a pin_pages). Revoking
unpinned pages under mempressure, i.e. the default shrinker behaviour,
seems satisfactory.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 3/8] drm/i915: Add a new "remapped" gtt_view
  2018-10-09  8:24                 ` Tvrtko Ursulin
  2018-10-09  8:41                   ` Chris Wilson
@ 2018-10-09 11:54                   ` Ville Syrjälä
  2018-10-10  7:04                     ` Tvrtko Ursulin
  1 sibling, 1 reply; 62+ messages in thread
From: Ville Syrjälä @ 2018-10-09 11:54 UTC (permalink / raw)
  To: Tvrtko Ursulin; +Cc: intel-gfx

On Tue, Oct 09, 2018 at 09:24:33AM +0100, Tvrtko Ursulin wrote:
> 
> On 05/10/2018 19:42, Ville Syrjälä wrote:
> > On Mon, Oct 01, 2018 at 04:48:21PM +0100, Tvrtko Ursulin wrote:
> >>
> >> On 01/10/2018 16:37, Chris Wilson wrote:
> >>> Quoting Ville Syrjälä (2018-10-01 16:27:43)
> >>>> On Mon, Oct 01, 2018 at 04:12:09PM +0100, Chris Wilson wrote:
> >>>>> Quoting Ville Syrjälä (2018-10-01 16:03:30)
> >>>>>> On Wed, Sep 26, 2018 at 08:50:25AM +0100, Tvrtko Ursulin wrote:
> >>>>>>>
> >>>>>>> On 25/09/2018 20:37, Ville Syrjala wrote:
> >>>>>>> One more thing, do you really need random access for this
> >>>>>>> transformation? Or you could walk the sg list as it is? Just if you hit
> >>>>>>> a too long chunk you need to copy a trimmed version over and know where
> >>>>>>> to continue for the next row. If doable it would be better than having
> >>>>>>> to kvmalloc_array.
> >>>>>>
> >>>>>> I think Chris suggested just using i915_gem_object_get_dma_address()
> >>>>>> here. But I'm not sure why we're not using it for rotate_pages()
> >>>>>> as well.
> >>>>>
> >>>>> Tvrtko is opposed to populating the obj->mm.pages cache with no defined
> >>>>> release point. I say the mempressure and shrinker should to the right
> >>>>> thing, but it's a big if.
> >>>>
> >>>> OK.
> >>>>
> >>>> Well, looks to me like i915_gem_object_get_dma_address() is the
> >>>> only convenient looking thing for iterating the pages without
> >>>> arowning the code in irrelevant details about sgs and whatnot.
> >>>> I suppose it should be possible to write some helpers that avoid
> >>>> all that and don't need the temp array, but I'm not really
> >>>> motivated enough to do that myself.
> >>>
> >>> Keep it simple and use get_dma_address(). We can find ways to throw away
> >>> the cache later if need be.
> >>
> >> I'd do it straight away. I think cache for a large framebuffer, the kind
> >> which needs remapping could be quite big! Even the more fragmented
> >> memory the bigger the cache, and so if it sticks around pointlessly for
> >> the lifetime of the framebuffer it is a double whammy.
> > 
> > The tree is indexed with the ggtt offset so memory fragmentation
> > shouldn't matter I think. Or did I totally miss something?
> 
> I think it is indexed by page index, but the number of tree entries 
> depends on the number of sg chunks, which in turn depends on the system 
> memory fragmentation. Consecutive pages are stored as "exceptional" 
> entries so that is more efficient IIRC,

Didn't look any more efficient to me. It's still one page per slot
AFAICS. The exceptional entry just tells you where to find the start
of the current sg chunk.

> but TBH I don't remember how 
> many of those it can store before it needs a new tree node. Anyways, if 
> I am not completely mistaken then the tree metadata size is proportional 
> to backing store fragmentation, and secondary proportional to object 
> size. (Due exceptional entry spill.)
> 
> > The relative overhead should be highest for a single page object
> > (576/4096 = ~15%). For big objects it should be something around
> > .2% AFAICS.
> 
> It is a bit annoying since radix tree does not have a helper to tell us 
> the number of allocated nodes. I don't remember how I measure this last 
> time.. Will try to recall.

I wrote myself a helper to count the nodes and that seems to
agree with my back of the envelope calculations.

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 3/8] drm/i915: Add a new "remapped" gtt_view
  2018-10-09 11:54                   ` Ville Syrjälä
@ 2018-10-10  7:04                     ` Tvrtko Ursulin
  0 siblings, 0 replies; 62+ messages in thread
From: Tvrtko Ursulin @ 2018-10-10  7:04 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx


On 09/10/2018 12:54, Ville Syrjälä wrote:
> On Tue, Oct 09, 2018 at 09:24:33AM +0100, Tvrtko Ursulin wrote:
>>
>> On 05/10/2018 19:42, Ville Syrjälä wrote:
>>> On Mon, Oct 01, 2018 at 04:48:21PM +0100, Tvrtko Ursulin wrote:
>>>>
>>>> On 01/10/2018 16:37, Chris Wilson wrote:
>>>>> Quoting Ville Syrjälä (2018-10-01 16:27:43)
>>>>>> On Mon, Oct 01, 2018 at 04:12:09PM +0100, Chris Wilson wrote:
>>>>>>> Quoting Ville Syrjälä (2018-10-01 16:03:30)
>>>>>>>> On Wed, Sep 26, 2018 at 08:50:25AM +0100, Tvrtko Ursulin wrote:
>>>>>>>>>
>>>>>>>>> On 25/09/2018 20:37, Ville Syrjala wrote:
>>>>>>>>> One more thing, do you really need random access for this
>>>>>>>>> transformation? Or you could walk the sg list as it is? Just if you hit
>>>>>>>>> a too long chunk you need to copy a trimmed version over and know where
>>>>>>>>> to continue for the next row. If doable it would be better than having
>>>>>>>>> to kvmalloc_array.
>>>>>>>>
>>>>>>>> I think Chris suggested just using i915_gem_object_get_dma_address()
>>>>>>>> here. But I'm not sure why we're not using it for rotate_pages()
>>>>>>>> as well.
>>>>>>>
>>>>>>> Tvrtko is opposed to populating the obj->mm.pages cache with no defined
>>>>>>> release point. I say the mempressure and shrinker should to the right
>>>>>>> thing, but it's a big if.
>>>>>>
>>>>>> OK.
>>>>>>
>>>>>> Well, looks to me like i915_gem_object_get_dma_address() is the
>>>>>> only convenient looking thing for iterating the pages without
>>>>>> arowning the code in irrelevant details about sgs and whatnot.
>>>>>> I suppose it should be possible to write some helpers that avoid
>>>>>> all that and don't need the temp array, but I'm not really
>>>>>> motivated enough to do that myself.
>>>>>
>>>>> Keep it simple and use get_dma_address(). We can find ways to throw away
>>>>> the cache later if need be.
>>>>
>>>> I'd do it straight away. I think cache for a large framebuffer, the kind
>>>> which needs remapping could be quite big! Even the more fragmented
>>>> memory the bigger the cache, and so if it sticks around pointlessly for
>>>> the lifetime of the framebuffer it is a double whammy.
>>>
>>> The tree is indexed with the ggtt offset so memory fragmentation
>>> shouldn't matter I think. Or did I totally miss something?
>>
>> I think it is indexed by page index, but the number of tree entries
>> depends on the number of sg chunks, which in turn depends on the system
>> memory fragmentation. Consecutive pages are stored as "exceptional"
>> entries so that is more efficient IIRC,
> 
> Didn't look any more efficient to me. It's still one page per slot
> AFAICS. The exceptional entry just tells you where to find the start
> of the current sg chunk.
> 
>> but TBH I don't remember how
>> many of those it can store before it needs a new tree node. Anyways, if
>> I am not completely mistaken then the tree metadata size is proportional
>> to backing store fragmentation, and secondary proportional to object
>> size. (Due exceptional entry spill.)
>>
>>> The relative overhead should be highest for a single page object
>>> (576/4096 = ~15%). For big objects it should be something around
>>> .2% AFAICS.
>>
>> It is a bit annoying since radix tree does not have a helper to tell us
>> the number of allocated nodes. I don't remember how I measure this last
>> time.. Will try to recall.
> 
> I wrote myself a helper to count the nodes and that seems to
> agree with my back of the envelope calculations.

How many sg chunks and then radix nodes for some typical framebuffer did 
that show? Or maybe not typical but the one which will require 
remapping. Did you measure after a fresh boot only or also on a bit of a 
memory constrained system (some memory pressure should equal more 
fragmentation)?

If not even that shows the cache size as significant, then I guess my 
worries that large framebuffers would be sufficiently fragmented for 
this to be much more were unfounded, so feel free to go with it.

Regards,

Tvrtko
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v4 1/8] drm/i915: Make sure fb gtt offsets stay within 32bits
  2018-09-25 19:37 ` [PATCH v3 1/8] drm/i915: Make sure fb gtt offsets stay within 32bits Ville Syrjala
  2018-09-25 20:29   ` Chris Wilson
@ 2018-10-23 16:02   ` Ville Syrjala
  2018-10-23 18:49     ` Chris Wilson
  1 sibling, 1 reply; 62+ messages in thread
From: Ville Syrjala @ 2018-10-23 16:02 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Let's try to make sure the fb offset computations never hit
an integer overflow by making sure the entire fb stays
below 32bits. framebuffer_check() in the core already does
the same check, but as it doesn't know about tiling some things
can slip through. Repeat the check in the driver with tiling
taken into account.

v2: Use add_overflows() after massaging it to work for me (Chris)
v3: Call it add_overflow_t() to match min_t() & co. (Chris)

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_utils.h    | 11 +++++++----
 drivers/gpu/drm/i915/intel_display.c | 18 +++++++++++++++++-
 2 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h
index 5858a43e19da..9726df37c4c4 100644
--- a/drivers/gpu/drm/i915/i915_utils.h
+++ b/drivers/gpu/drm/i915/i915_utils.h
@@ -44,16 +44,19 @@
 			     __stringify(x), (long)(x))
 
 #if defined(GCC_VERSION) && GCC_VERSION >= 70000
-#define add_overflows(A, B) \
-	__builtin_add_overflow_p((A), (B), (typeof((A) + (B)))0)
+#define add_overflows_t(T, A, B) \
+	__builtin_add_overflow_p((A), (B), (T)0)
 #else
-#define add_overflows(A, B) ({ \
+#define add_overflows_t(T, A, B) ({ \
 	typeof(A) a = (A); \
 	typeof(B) b = (B); \
-	a + b < a; \
+	(T)(a + b) < a; \
 })
 #endif
 
+#define add_overflows(A, B) \
+	add_overflows_t(typeof((A) + (B)), (A), (B))
+
 #define range_overflows(start, size, max) ({ \
 	typeof(start) start__ = (start); \
 	typeof(size) size__ = (size); \
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 969d22ca8dcd..e520facc23e1 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2351,10 +2351,26 @@ static int intel_fb_offset_to_xy(int *x, int *y,
 				 int color_plane)
 {
 	struct drm_i915_private *dev_priv = to_i915(fb->dev);
+	unsigned int height;
 
 	if (fb->modifier != DRM_FORMAT_MOD_LINEAR &&
-	    fb->offsets[color_plane] % intel_tile_size(dev_priv))
+	    fb->offsets[color_plane] % intel_tile_size(dev_priv)) {
+		DRM_DEBUG_KMS("Misaligned offset 0x%08x for color plane %d\n",
+			      fb->offsets[color_plane], color_plane);
 		return -EINVAL;
+	}
+
+	height = drm_framebuffer_plane_height(fb->height, fb, color_plane);
+	height = ALIGN(height, intel_tile_height(fb, color_plane));
+
+	/* Catch potential overflows early */
+	if (add_overflows_t(u32, mul_u32_u32(height, fb->pitches[color_plane]),
+			    fb->offsets[color_plane])) {
+		DRM_DEBUG_KMS("Bad offset 0x%08x or pitch %d for color plane %d\n",
+			      fb->offsets[color_plane], fb->pitches[color_plane],
+			      color_plane);
+		return -ERANGE;
+	}
 
 	*x = 0;
 	*y = 0;
-- 
2.18.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v4 3/8] drm/i915: Add a new "remapped" gtt_view
  2018-09-25 19:37 ` [PATCH v3 3/8] drm/i915: Add a new "remapped" gtt_view Ville Syrjala
  2018-09-26  7:50   ` Tvrtko Ursulin
@ 2018-10-23 16:02   ` Ville Syrjala
  2018-10-23 18:56     ` Chris Wilson
  2018-10-26  9:19     ` Tvrtko Ursulin
  1 sibling, 2 replies; 62+ messages in thread
From: Ville Syrjala @ 2018-10-23 16:02 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

To overcome display engine stride limits we'll want to remap the
pages in the GTT. To that end we need a new gtt_view type which
is just like the "rotated" type except not rotated.

v2: Use intel_remapped_plane_info base type
    s/unused/unused_mbz/ (Chris)
    Separate BUILD_BUG_ON()s (Chris)
    Use I915_GTT_PAGE_SIZE (Chris)
v3: Use i915_gem_object_get_dma_address() (Chris)
    Trim the sg (Tvrtko)

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c       | 12 ++++
 drivers/gpu/drm/i915/i915_gem_gtt.c       | 74 +++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_gem_gtt.h       | 25 ++++++--
 drivers/gpu/drm/i915/i915_vma.c           |  6 +-
 drivers/gpu/drm/i915/i915_vma.h           |  3 +
 drivers/gpu/drm/i915/intel_display.c      | 11 ++++
 drivers/gpu/drm/i915/intel_drv.h          |  1 +
 drivers/gpu/drm/i915/selftests/i915_vma.c |  6 +-
 8 files changed, 130 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 5b37d5f8e132..ce019126304d 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -196,6 +196,18 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
 					   vma->ggtt_view.rotated.plane[1].offset);
 				break;
 
+			case I915_GGTT_VIEW_REMAPPED:
+				seq_printf(m, ", remapped [(%ux%u, stride=%u, offset=%u), (%ux%u, stride=%u, offset=%u)]",
+					   vma->ggtt_view.remapped.plane[0].width,
+					   vma->ggtt_view.remapped.plane[0].height,
+					   vma->ggtt_view.remapped.plane[0].stride,
+					   vma->ggtt_view.remapped.plane[0].offset,
+					   vma->ggtt_view.remapped.plane[1].width,
+					   vma->ggtt_view.remapped.plane[1].height,
+					   vma->ggtt_view.remapped.plane[1].stride,
+					   vma->ggtt_view.remapped.plane[1].offset);
+				break;
+
 			default:
 				MISSING_CASE(vma->ggtt_view.type);
 				break;
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 98d9a1eb1ed2..d0e50b584ebd 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -3705,6 +3705,75 @@ intel_rotate_pages(struct intel_rotation_info *rot_info,
 	return ERR_PTR(ret);
 }
 
+static struct scatterlist *
+remap_pages(struct drm_i915_gem_object *obj, unsigned int offset,
+	    unsigned int width, unsigned int height,
+	    unsigned int stride,
+	    struct sg_table *st, struct scatterlist *sg)
+{
+	unsigned int column, row;
+
+	for (row = 0; row < height; row++) {
+		for (column = 0; column < width; column++) {
+			st->nents++;
+			/* We don't need the pages, but need to initialize
+			 * the entries so the sg list can be happily traversed.
+			 * The only thing we need are DMA addresses.
+			 */
+			sg_set_page(sg, NULL, I915_GTT_PAGE_SIZE, 0);
+			sg_dma_address(sg) =
+				i915_gem_object_get_dma_address(obj, offset + column);
+			sg_dma_len(sg) = I915_GTT_PAGE_SIZE;
+			sg = sg_next(sg);
+		}
+		offset += stride;
+	}
+
+	return sg;
+}
+
+static noinline struct sg_table *
+intel_remap_pages(struct intel_remapped_info *rem_info,
+		  struct drm_i915_gem_object *obj)
+{
+	unsigned int size = intel_remapped_info_size(rem_info);
+	struct sg_table *st;
+	struct scatterlist *sg;
+	int ret = -ENOMEM;
+	int i;
+
+	/* Allocate target SG list. */
+	st = kmalloc(sizeof(*st), GFP_KERNEL);
+	if (!st)
+		goto err_st_alloc;
+
+	ret = sg_alloc_table(st, size, GFP_KERNEL);
+	if (ret)
+		goto err_sg_alloc;
+
+	st->nents = 0;
+	sg = st->sgl;
+
+	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
+		sg = remap_pages(obj, rem_info->plane[i].offset,
+				 rem_info->plane[i].width, rem_info->plane[i].height,
+				 rem_info->plane[i].stride, st, sg);
+	}
+
+	i915_sg_trim(st);
+
+	return st;
+
+err_sg_alloc:
+	kfree(st);
+err_st_alloc:
+
+	DRM_DEBUG_DRIVER("Failed to create remapped mapping for object size %zu! (%ux%u tiles, %u pages)\n",
+			 obj->base.size, rem_info->plane[0].width, rem_info->plane[0].height, size);
+
+	return ERR_PTR(ret);
+}
+
 static noinline struct sg_table *
 intel_partial_pages(const struct i915_ggtt_view *view,
 		    struct drm_i915_gem_object *obj)
@@ -3783,6 +3852,11 @@ i915_get_ggtt_vma_pages(struct i915_vma *vma)
 			intel_rotate_pages(&vma->ggtt_view.rotated, vma->obj);
 		break;
 
+	case I915_GGTT_VIEW_REMAPPED:
+		vma->pages =
+			intel_remap_pages(&vma->ggtt_view.remapped, vma->obj);
+		break;
+
 	case I915_GGTT_VIEW_PARTIAL:
 		vma->pages = intel_partial_pages(&vma->ggtt_view, vma->obj);
 		break;
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 7e2af5f4f39b..69a22f57e6ca 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -160,11 +160,18 @@ typedef u64 gen8_ppgtt_pml4e_t;
 
 struct sg_table;
 
+struct intel_remapped_plane_info {
+	/* in gtt pages */
+	unsigned int width, height, stride, offset;
+} __packed;
+
+struct intel_remapped_info {
+	struct intel_remapped_plane_info plane[2];
+	unsigned int unused_mbz;
+} __packed;
+
 struct intel_rotation_info {
-	struct intel_rotation_plane_info {
-		/* tiles */
-		unsigned int width, height, stride, offset;
-	} plane[2];
+	struct intel_remapped_plane_info plane[2];
 } __packed;
 
 struct intel_partial_info {
@@ -176,12 +183,20 @@ enum i915_ggtt_view_type {
 	I915_GGTT_VIEW_NORMAL = 0,
 	I915_GGTT_VIEW_ROTATED = sizeof(struct intel_rotation_info),
 	I915_GGTT_VIEW_PARTIAL = sizeof(struct intel_partial_info),
+	I915_GGTT_VIEW_REMAPPED = sizeof(struct intel_remapped_info),
 };
 
 static inline void assert_i915_gem_gtt_types(void)
 {
 	BUILD_BUG_ON(sizeof(struct intel_rotation_info) != 8*sizeof(unsigned int));
 	BUILD_BUG_ON(sizeof(struct intel_partial_info) != sizeof(u64) + sizeof(unsigned int));
+	BUILD_BUG_ON(sizeof(struct intel_remapped_info) != 9*sizeof(unsigned int));
+
+	/* Check that rotation/remapped shares offsets for simplicity */
+	BUILD_BUG_ON(offsetof(struct intel_remapped_info, plane[0]) !=
+		     offsetof(struct intel_rotation_info, plane[0]));
+	BUILD_BUG_ON(offsetofend(struct intel_remapped_info, plane[1]) !=
+		     offsetofend(struct intel_rotation_info, plane[1]));
 
 	/* As we encode the size of each branch inside the union into its type,
 	 * we have to be careful that each branch has a unique size.
@@ -190,6 +205,7 @@ static inline void assert_i915_gem_gtt_types(void)
 	case I915_GGTT_VIEW_NORMAL:
 	case I915_GGTT_VIEW_PARTIAL:
 	case I915_GGTT_VIEW_ROTATED:
+	case I915_GGTT_VIEW_REMAPPED:
 		/* gcc complains if these are identical cases */
 		break;
 	}
@@ -201,6 +217,7 @@ struct i915_ggtt_view {
 		/* Members need to contain no holes/padding */
 		struct intel_partial_info partial;
 		struct intel_rotation_info rotated;
+		struct intel_remapped_info remapped;
 	};
 };
 
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 82652c3d1bed..2070e44eaa03 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -164,6 +164,9 @@ vma_create(struct drm_i915_gem_object *obj,
 		} else if (view->type == I915_GGTT_VIEW_ROTATED) {
 			vma->size = intel_rotation_info_size(&view->rotated);
 			vma->size <<= PAGE_SHIFT;
+		} else if (view->type == I915_GGTT_VIEW_REMAPPED) {
+			vma->size = intel_remapped_info_size(&view->remapped);
+			vma->size <<= PAGE_SHIFT;
 		}
 	}
 
@@ -464,7 +467,8 @@ void __i915_vma_set_map_and_fenceable(struct i915_vma *vma)
 	 * Explicitly disable for rotated VMA since the display does not
 	 * need the fence and the VMA is not accessible to other users.
 	 */
-	if (vma->ggtt_view.type == I915_GGTT_VIEW_ROTATED)
+	if (vma->ggtt_view.type == I915_GGTT_VIEW_ROTATED ||
+	    vma->ggtt_view.type == I915_GGTT_VIEW_REMAPPED)
 		return;
 
 	fenceable = (vma->node.size >= vma->fence_size &&
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 4f7c1c7599f4..64cf029c028a 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -265,8 +265,11 @@ i915_vma_compare(struct i915_vma *vma,
 	 */
 	BUILD_BUG_ON(I915_GGTT_VIEW_NORMAL >= I915_GGTT_VIEW_PARTIAL);
 	BUILD_BUG_ON(I915_GGTT_VIEW_PARTIAL >= I915_GGTT_VIEW_ROTATED);
+	BUILD_BUG_ON(I915_GGTT_VIEW_ROTATED >= I915_GGTT_VIEW_REMAPPED);
 	BUILD_BUG_ON(offsetof(typeof(*view), rotated) !=
 		     offsetof(typeof(*view), partial));
+	BUILD_BUG_ON(offsetof(typeof(*view), rotated) !=
+		     offsetof(typeof(*view), remapped));
 	return memcmp(&vma->ggtt_view.partial, &view->partial, view->type);
 }
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8a0b477a69d3..41f7e0795b14 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1957,6 +1957,17 @@ unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info
 	return size;
 }
 
+unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info)
+{
+	unsigned int size = 0;
+	int i;
+
+	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++)
+		size += rem_info->plane[i].width * rem_info->plane[i].height;
+
+	return size;
+}
+
 static void
 intel_fill_fb_ggtt_view(struct i915_ggtt_view *view,
 			const struct drm_framebuffer *fb,
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 0e9a926fca04..6993eff5dfaf 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1523,6 +1523,7 @@ unsigned int intel_fb_xy_to_linear(int x, int y,
 void intel_add_fb_offsets(int *x, int *y,
 			  const struct intel_plane_state *state, int plane);
 unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info);
+unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info);
 bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv);
 void intel_mark_busy(struct drm_i915_private *dev_priv);
 void intel_mark_idle(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c
index ffa74290e054..4fc49c27f13c 100644
--- a/drivers/gpu/drm/i915/selftests/i915_vma.c
+++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
@@ -395,8 +395,8 @@ assert_rotated(struct drm_i915_gem_object *obj,
 	return sg;
 }
 
-static unsigned int rotated_size(const struct intel_rotation_plane_info *a,
-				 const struct intel_rotation_plane_info *b)
+static unsigned int rotated_size(const struct intel_remapped_plane_info *a,
+				 const struct intel_remapped_plane_info *b)
 {
 	return a->width * a->height + b->width * b->height;
 }
@@ -406,7 +406,7 @@ static int igt_vma_rotate(void *arg)
 	struct drm_i915_private *i915 = arg;
 	struct i915_address_space *vm = &i915->ggtt.vm;
 	struct drm_i915_gem_object *obj;
-	const struct intel_rotation_plane_info planes[] = {
+	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 },
-- 
2.18.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v4 4/8] drm/i915/selftests: Add mock selftest for remapped vmas
  2018-09-25 19:37 ` [PATCH v3 4/8] drm/i915/selftests: Add mock selftest for remapped vmas Ville Syrjala
  2018-09-25 20:22   ` Chris Wilson
@ 2018-10-23 16:03   ` Ville Syrjala
  2018-10-23 19:02     ` Chris Wilson
  1 sibling, 1 reply; 62+ messages in thread
From: Ville Syrjala @ 2018-10-23 16:03 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Extend the rotated vma mock selftest to cover remapped vmas as
well.

TODO: reindent the loops I guess? Left like this for now to
ease review

v2: Include the vma type in the error message (Chris)

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/selftests/i915_vma.c | 74 +++++++++++++++++++++--
 1 file changed, 68 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c
index 4fc49c27f13c..64c5055c83f9 100644
--- a/drivers/gpu/drm/i915/selftests/i915_vma.c
+++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
@@ -58,7 +58,7 @@ static bool assert_vma(struct i915_vma *vma,
 static struct i915_vma *
 checked_vma_instance(struct drm_i915_gem_object *obj,
 		     struct i915_address_space *vm,
-		     struct i915_ggtt_view *view)
+		     const struct i915_ggtt_view *view)
 {
 	struct i915_vma *vma;
 	bool ok = true;
@@ -395,13 +395,63 @@ assert_rotated(struct drm_i915_gem_object *obj,
 	return sg;
 }
 
+static unsigned long remapped_index(const struct intel_remapped_info *r,
+				    unsigned int n,
+				    unsigned int x,
+				    unsigned int y)
+{
+	return (r->plane[n].stride * y +
+		r->plane[n].offset + x);
+}
+
+static struct scatterlist *
+assert_remapped(struct drm_i915_gem_object *obj,
+		const struct intel_remapped_info *r, unsigned int n,
+		struct scatterlist *sg)
+{
+	unsigned int x, y;
+
+	for (y = 0; y < r->plane[n].height; y++) {
+		for (x = 0; x < r->plane[n].width; x++) {
+			unsigned long src_idx;
+			dma_addr_t src;
+
+			if (!sg) {
+				pr_err("Invalid sg table: too short at plane %d, (%d, %d)!\n",
+				       n, x, y);
+				return ERR_PTR(-EINVAL);
+			}
+
+			src_idx = remapped_index(r, n, x, y);
+			src = i915_gem_object_get_dma_address(obj, src_idx);
+
+			if (sg_dma_len(sg) != PAGE_SIZE) {
+				pr_err("Invalid sg.length, found %d, expected %lu for remapped page (%d, %d) [src index %lu]\n",
+				       sg_dma_len(sg), PAGE_SIZE,
+				       x, y, src_idx);
+				return ERR_PTR(-EINVAL);
+			}
+
+			if (sg_dma_address(sg) != src) {
+				pr_err("Invalid address for remapped page (%d, %d) [src index %lu]\n",
+				       x, y, src_idx);
+				return ERR_PTR(-EINVAL);
+			}
+
+			sg = sg_next(sg);
+		}
+	}
+
+	return sg;
+}
+
 static unsigned int rotated_size(const struct intel_remapped_plane_info *a,
 				 const struct intel_remapped_plane_info *b)
 {
 	return a->width * a->height + b->width * b->height;
 }
 
-static int igt_vma_rotate(void *arg)
+static int igt_vma_rotate_remap(void *arg)
 {
 	struct drm_i915_private *i915 = arg;
 	struct i915_address_space *vm = &i915->ggtt.vm;
@@ -424,6 +474,11 @@ static int igt_vma_rotate(void *arg)
 		{ .width = 6, .height = 4, .stride = 6 },
 		{ }
 	}, *a, *b;
+	enum i915_ggtt_view_type types[] = {
+		I915_GGTT_VIEW_ROTATED,
+		I915_GGTT_VIEW_REMAPPED,
+		0,
+	}, *t;
 	const unsigned int max_pages = 64;
 	int err = -ENOMEM;
 
@@ -435,6 +490,7 @@ static int igt_vma_rotate(void *arg)
 	if (IS_ERR(obj))
 		goto out;
 
+	for (t = types; *t; t++) {
 	for (a = planes; a->width; a++) {
 		for (b = planes + ARRAY_SIZE(planes); b-- != planes; ) {
 			struct i915_ggtt_view view;
@@ -445,7 +501,7 @@ static int igt_vma_rotate(void *arg)
 			GEM_BUG_ON(max_offset > max_pages);
 			max_offset = max_pages - max_offset;
 
-			view.type = I915_GGTT_VIEW_ROTATED;
+			view.type = *t;
 			view.rotated.plane[0] = *a;
 			view.rotated.plane[1] = *b;
 
@@ -495,9 +551,14 @@ static int igt_vma_rotate(void *arg)
 
 					sg = vma->pages->sgl;
 					for (n = 0; n < ARRAY_SIZE(view.rotated.plane); n++) {
-						sg = assert_rotated(obj, &view.rotated, n, sg);
+						if (view.type == I915_GGTT_VIEW_ROTATED)
+							sg = assert_rotated(obj, &view.rotated, n, sg);
+						else
+							sg = assert_remapped(obj, &view.remapped, n, sg);
 						if (IS_ERR(sg)) {
-							pr_err("Inconsistent VMA pages for plane %d: [(%d, %d, %d, %d), (%d, %d, %d, %d)]\n", n,
+							pr_err("Inconsistent %s VMA pages for plane %d: [(%d, %d, %d, %d), (%d, %d, %d, %d)]\n",
+							       view.type == I915_GGTT_VIEW_ROTATED ?
+							       "rotated" : "remapped", n,
 							       view.rotated.plane[0].width,
 							       view.rotated.plane[0].height,
 							       view.rotated.plane[0].stride,
@@ -516,6 +577,7 @@ static int igt_vma_rotate(void *arg)
 			}
 		}
 	}
+	}
 
 out_object:
 	i915_gem_object_put(obj);
@@ -719,7 +781,7 @@ int i915_vma_mock_selftests(void)
 	static const struct i915_subtest tests[] = {
 		SUBTEST(igt_vma_create),
 		SUBTEST(igt_vma_pin1),
-		SUBTEST(igt_vma_rotate),
+		SUBTEST(igt_vma_rotate_remap),
 		SUBTEST(igt_vma_partial),
 	};
 	struct drm_i915_private *i915;
-- 
2.18.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v4 5/8] drm/i915/selftests: Add live vma selftest
  2018-09-25 19:37 ` [PATCH v3 5/8] drm/i915/selftests: Add live vma selftest Ville Syrjala
  2018-09-25 20:19   ` Chris Wilson
  2018-09-25 20:40   ` Chris Wilson
@ 2018-10-23 16:03   ` Ville Syrjala
  2018-10-23 19:05     ` Chris Wilson
  2 siblings, 1 reply; 62+ messages in thread
From: Ville Syrjala @ 2018-10-23 16:03 UTC (permalink / raw)
  To: intel-gfx

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.

v2: Grab rpm reference (Chris)
    GEM_BUG_ON(view.type not as expected) (Chris)
    Allow CAN_FENCE for rotated/remapped vmas (Chris)
    Update intel_plane_uses_fence() to ask for a fence
    only for normal vmas on gen4+

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_vma.c               |   8 -
 drivers/gpu/drm/i915/intel_display.c          |   4 +-
 .../drm/i915/selftests/i915_live_selftests.h  |   1 +
 drivers/gpu/drm/i915/selftests/i915_vma.c     | 140 ++++++++++++++++++
 4 files changed, 144 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 2070e44eaa03..6fe0749dec32 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -463,14 +463,6 @@ void __i915_vma_set_map_and_fenceable(struct i915_vma *vma)
 	GEM_BUG_ON(!i915_vma_is_ggtt(vma));
 	GEM_BUG_ON(!vma->fence_size);
 
-	/*
-	 * Explicitly disable for rotated VMA since the display does not
-	 * need the fence and the VMA is not accessible to other users.
-	 */
-	if (vma->ggtt_view.type == I915_GGTT_VIEW_ROTATED ||
-	    vma->ggtt_view.type == I915_GGTT_VIEW_REMAPPED)
-		return;
-
 	fenceable = (vma->node.size >= vma->fence_size &&
 		     IS_ALIGNED(vma->node.start, vma->fence_alignment));
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 41f7e0795b14..582e8d192abd 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2037,7 +2037,9 @@ static bool intel_plane_uses_fence(const struct intel_plane_state *plane_state)
 	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 
-	return INTEL_GEN(dev_priv) < 4 || plane->has_fbc;
+	return INTEL_GEN(dev_priv) < 4 ||
+		(plane->has_fbc &&
+		 plane_state->view.type == I915_GGTT_VIEW_NORMAL);
 }
 
 struct i915_vma *
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 64c5055c83f9..208629057839 100644
--- a/drivers/gpu/drm/i915/selftests/i915_vma.c
+++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
@@ -799,3 +799,143 @@ 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);
+
+	intel_runtime_pm_get(i915);
+
+	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;
+			}
+
+			GEM_BUG_ON(vma->ggtt_view.type != *t);
+
+			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->ggtt_view.type != I915_GGTT_VIEW_NORMAL);
+
+			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:
+	intel_runtime_pm_put(i915);
+	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);
+}
-- 
2.18.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* ✗ Fi.CI.CHECKPATCH: warning for drm/i915: GTT remapping for display (rev5)
  2018-09-25 19:37 [PATCH v3 0/8] drm/i915: GTT remapping for display Ville Syrjala
                   ` (11 preceding siblings ...)
  2018-09-25 21:21 ` ✓ Fi.CI.IGT: " Patchwork
@ 2018-10-23 16:21 ` Patchwork
  2018-10-23 16:24 ` ✗ Fi.CI.SPARSE: " Patchwork
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 62+ messages in thread
From: Patchwork @ 2018-10-23 16:21 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: GTT remapping for display (rev5)
URL   : https://patchwork.freedesktop.org/series/50165/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
7ecc46df21aa drm/i915: Make sure fb gtt offsets stay within 32bits
-:44: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'B' - possible side-effects?
#44: FILE: drivers/gpu/drm/i915/i915_utils.h:57:
+#define add_overflows(A, B) \
+	add_overflows_t(typeof((A) + (B)), (A), (B))

total: 0 errors, 0 warnings, 1 checks, 50 lines checked
e7d9b84981c9 drm/i915: Decouple SKL stride units from intel_fb_stride_alignment()
2a232ab75fe1 drm/i915: Add a new "remapped" gtt_view
-:177: CHECK:SPACING: spaces preferred around that '*' (ctx:VxV)
#177: FILE: drivers/gpu/drm/i915/i915_gem_gtt.h:193:
+	BUILD_BUG_ON(sizeof(struct intel_remapped_info) != 9*sizeof(unsigned int));
 	                                                    ^

total: 0 errors, 0 warnings, 1 checks, 231 lines checked
ee777eb6655c drm/i915/selftests: Add mock selftest for remapped vmas
-:114: WARNING:SUSPECT_CODE_INDENT: suspect code indent for conditional statements (8, 8)
#114: FILE: drivers/gpu/drm/i915/selftests/i915_vma.c:493:
+	for (t = types; *t; t++) {
 	for (a = planes; a->width; a++) {

-:132: WARNING:DEEP_INDENTATION: Too many leading tabs - consider code refactoring
#132: FILE: drivers/gpu/drm/i915/selftests/i915_vma.c:554:
+						if (view.type == I915_GGTT_VIEW_ROTATED)

-:133: WARNING:LONG_LINE: line over 100 characters
#133: FILE: drivers/gpu/drm/i915/selftests/i915_vma.c:555:
+							sg = assert_rotated(obj, &view.rotated, n, sg);

-:134: WARNING:DEEP_INDENTATION: Too many leading tabs - consider code refactoring
#134: FILE: drivers/gpu/drm/i915/selftests/i915_vma.c:556:
+						else

-:135: WARNING:LONG_LINE: line over 100 characters
#135: FILE: drivers/gpu/drm/i915/selftests/i915_vma.c:557:
+							sg = assert_remapped(obj, &view.remapped, n, sg);

total: 0 errors, 5 warnings, 0 checks, 129 lines checked
d2f2a9c684e0 drm/i915/selftests: Add live vma selftest
45bb3b57aa21 drm/i915: Overcome display engine stride limits via GTT remapping
0439f5d5b684 drm/i915: Bump gen4+ fb stride limit to 256KiB
-:40: CHECK:SPACING: spaces preferred around that '*' (ctx:VxV)
#40: FILE: drivers/gpu/drm/i915/intel_display.c:2489:
+		return 256*1024;
 		          ^

total: 0 errors, 0 warnings, 1 checks, 19 lines checked
fa36cffdcccc drm/i915: Bump gen7+ fb size limits to 16kx16k

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* ✗ Fi.CI.SPARSE: warning for drm/i915: GTT remapping for display (rev5)
  2018-09-25 19:37 [PATCH v3 0/8] drm/i915: GTT remapping for display Ville Syrjala
                   ` (12 preceding siblings ...)
  2018-10-23 16:21 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: GTT remapping for display (rev5) Patchwork
@ 2018-10-23 16:24 ` Patchwork
  2018-10-23 16:43 ` ✓ Fi.CI.BAT: success " Patchwork
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 62+ messages in thread
From: Patchwork @ 2018-10-23 16:24 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: GTT remapping for display (rev5)
URL   : https://patchwork.freedesktop.org/series/50165/
State : warning

== Summary ==

$ dim sparse origin/drm-tip
Sparse version: v0.5.2
Commit: drm/i915: Make sure fb gtt offsets stay within 32bits
+drivers/gpu/drm/i915/intel_display.c:2367:13: error: undefined identifier '__builtin_add_overflow_p'
+drivers/gpu/drm/i915/intel_display.c:2367:13: warning: call with no type!

Commit: drm/i915: Decouple SKL stride units from intel_fb_stride_alignment()
Okay!

Commit: drm/i915: Add a new "remapped" gtt_view
Okay!

Commit: drm/i915/selftests: Add mock selftest for remapped vmas
Okay!

Commit: drm/i915/selftests: Add live vma selftest
Okay!

Commit: drm/i915: Overcome display engine stride limits via GTT remapping
Okay!

Commit: drm/i915: Bump gen4+ fb stride limit to 256KiB
Okay!

Commit: drm/i915: Bump gen7+ fb size limits to 16kx16k
Okay!

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* ✓ Fi.CI.BAT: success for drm/i915: GTT remapping for display (rev5)
  2018-09-25 19:37 [PATCH v3 0/8] drm/i915: GTT remapping for display Ville Syrjala
                   ` (13 preceding siblings ...)
  2018-10-23 16:24 ` ✗ Fi.CI.SPARSE: " Patchwork
@ 2018-10-23 16:43 ` Patchwork
  2018-10-23 18:13 ` ✓ Fi.CI.IGT: " Patchwork
  2019-01-09  9:45 ` [PATCH v3 0/8] drm/i915: GTT remapping for display Timo Aaltonen
  16 siblings, 0 replies; 62+ messages in thread
From: Patchwork @ 2018-10-23 16:43 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: GTT remapping for display (rev5)
URL   : https://patchwork.freedesktop.org/series/50165/
State : success

== Summary ==

= CI Bug Log - changes from CI_DRM_5022 -> Patchwork_10547 =

== Summary - SUCCESS ==

  No regressions found.

  External URL: https://patchwork.freedesktop.org/api/1.0/series/50165/revisions/5/mbox/

== Known issues ==

  Here are the changes found in Patchwork_10547 that come from known issues:

  === IGT changes ===

    ==== Issues hit ====

    igt@kms_flip@basic-flip-vs-dpms:
      fi-skl-6700hq:      PASS -> DMESG-WARN (fdo#105998)

    igt@kms_frontbuffer_tracking@basic:
      fi-byt-clapper:     PASS -> FAIL (fdo#103167)

    igt@kms_pipe_crc_basic@read-crc-pipe-a-frame-sequence:
      fi-byt-clapper:     PASS -> FAIL (fdo#107362, fdo#103191)

    
  fdo#103167 https://bugs.freedesktop.org/show_bug.cgi?id=103167
  fdo#103191 https://bugs.freedesktop.org/show_bug.cgi?id=103191
  fdo#105998 https://bugs.freedesktop.org/show_bug.cgi?id=105998
  fdo#107362 https://bugs.freedesktop.org/show_bug.cgi?id=107362


== Participating hosts (48 -> 44) ==

  Additional (1): fi-icl-u 
  Missing    (5): fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-ctg-p8600 


== Build changes ==

    * Linux: CI_DRM_5022 -> Patchwork_10547

  CI_DRM_5022: 23e3398e765478f4adb4783543b62a3e6b3ed554 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_4688: fa6dbf8c048961356fd642df047cb58ab49309b2 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_10547: fa36cffdcccc92b88abaccd1b448d741f64e76c9 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

fa36cffdcccc drm/i915: Bump gen7+ fb size limits to 16kx16k
0439f5d5b684 drm/i915: Bump gen4+ fb stride limit to 256KiB
45bb3b57aa21 drm/i915: Overcome display engine stride limits via GTT remapping
d2f2a9c684e0 drm/i915/selftests: Add live vma selftest
ee777eb6655c drm/i915/selftests: Add mock selftest for remapped vmas
2a232ab75fe1 drm/i915: Add a new "remapped" gtt_view
e7d9b84981c9 drm/i915: Decouple SKL stride units from intel_fb_stride_alignment()
7ecc46df21aa drm/i915: Make sure fb gtt offsets stay within 32bits

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_10547/issues.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* ✓ Fi.CI.IGT: success for drm/i915: GTT remapping for display (rev5)
  2018-09-25 19:37 [PATCH v3 0/8] drm/i915: GTT remapping for display Ville Syrjala
                   ` (14 preceding siblings ...)
  2018-10-23 16:43 ` ✓ Fi.CI.BAT: success " Patchwork
@ 2018-10-23 18:13 ` Patchwork
  2019-01-09  9:45 ` [PATCH v3 0/8] drm/i915: GTT remapping for display Timo Aaltonen
  16 siblings, 0 replies; 62+ messages in thread
From: Patchwork @ 2018-10-23 18:13 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: GTT remapping for display (rev5)
URL   : https://patchwork.freedesktop.org/series/50165/
State : success

== Summary ==

= CI Bug Log - changes from CI_DRM_5022_full -> Patchwork_10547_full =

== Summary - SUCCESS ==

  No regressions found.

  

== Known issues ==

  Here are the changes found in Patchwork_10547_full that come from known issues:

  === IGT changes ===

    ==== Issues hit ====

    igt@gem_ctx_bad_destroy@invalid-default-ctx:
      shard-apl:          PASS -> DMESG-WARN (fdo#105602, fdo#103558) +6

    igt@gem_exec_whisper@normal:
      shard-kbl:          PASS -> INCOMPLETE (fdo#103665)

    igt@kms_busy@extended-modeset-hang-newfb-render-a:
      shard-skl:          NOTRUN -> DMESG-WARN (fdo#107956) +2

    igt@kms_color@pipe-b-degamma:
      shard-apl:          PASS -> FAIL (fdo#104782)

    igt@kms_cursor_crc@cursor-128x128-dpms:
      shard-apl:          PASS -> FAIL (fdo#103232) +1

    igt@kms_cursor_crc@cursor-256x256-onscreen:
      shard-glk:          PASS -> FAIL (fdo#103232)

    igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-draw-pwrite:
      shard-apl:          PASS -> FAIL (fdo#103167) +1

    igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-move:
      shard-glk:          PASS -> FAIL (fdo#103167) +2

    igt@kms_frontbuffer_tracking@fbcpsr-stridechange:
      shard-skl:          NOTRUN -> FAIL (fdo#105683)

    igt@kms_frontbuffer_tracking@psr-1p-primscrn-cur-indfb-draw-mmap-cpu:
      shard-skl:          NOTRUN -> FAIL (fdo#103167)

    igt@kms_plane@plane-position-covered-pipe-a-planes:
      shard-apl:          PASS -> FAIL (fdo#103166)

    igt@kms_plane_alpha_blend@pipe-a-coverage-7efc:
      shard-skl:          NOTRUN -> FAIL (fdo#108145, fdo#107815)

    igt@kms_plane_alpha_blend@pipe-b-alpha-transparant-fb:
      shard-skl:          NOTRUN -> FAIL (fdo#108145)

    igt@kms_setmode@basic:
      shard-apl:          PASS -> FAIL (fdo#99912)

    
    ==== Possible fixes ====

    igt@drv_suspend@shrink:
      shard-skl:          INCOMPLETE (fdo#106886) -> PASS

    igt@gem_ctx_isolation@rcs0-dirty-switch:
      shard-glk:          FAIL -> PASS

    igt@gem_exec_await@wide-contexts:
      shard-skl:          FAIL (fdo#106680) -> PASS

    igt@kms_busy@extended-pageflip-modeset-hang-oldfb-render-a:
      shard-hsw:          DMESG-WARN (fdo#107956) -> PASS

    igt@kms_cursor_crc@cursor-256x85-onscreen:
      shard-glk:          FAIL (fdo#103232) -> PASS +1

    igt@kms_cursor_crc@cursor-64x21-offscreen:
      shard-skl:          FAIL (fdo#103232) -> PASS

    igt@kms_draw_crc@draw-method-xrgb2101010-mmap-cpu-untiled:
      shard-skl:          FAIL (fdo#103184) -> PASS +1

    igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-draw-blt:
      shard-apl:          FAIL (fdo#103167) -> PASS

    igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-indfb-draw-blt:
      shard-glk:          FAIL (fdo#103167) -> PASS

    igt@kms_frontbuffer_tracking@psr-rgb101010-draw-mmap-cpu:
      shard-skl:          FAIL (fdo#103167) -> PASS +1

    igt@kms_plane@plane-position-covered-pipe-c-planes:
      shard-apl:          FAIL (fdo#103166) -> PASS +1

    igt@kms_plane_multiple@atomic-pipe-b-tiling-y:
      shard-glk:          FAIL (fdo#103166) -> PASS +2

    
    ==== Warnings ====

    igt@kms_cursor_crc@cursor-64x21-onscreen:
      shard-apl:          FAIL (fdo#103232) -> DMESG-WARN (fdo#105602, fdo#103558)

    
  fdo#103166 https://bugs.freedesktop.org/show_bug.cgi?id=103166
  fdo#103167 https://bugs.freedesktop.org/show_bug.cgi?id=103167
  fdo#103184 https://bugs.freedesktop.org/show_bug.cgi?id=103184
  fdo#103232 https://bugs.freedesktop.org/show_bug.cgi?id=103232
  fdo#103558 https://bugs.freedesktop.org/show_bug.cgi?id=103558
  fdo#103665 https://bugs.freedesktop.org/show_bug.cgi?id=103665
  fdo#104782 https://bugs.freedesktop.org/show_bug.cgi?id=104782
  fdo#105602 https://bugs.freedesktop.org/show_bug.cgi?id=105602
  fdo#105683 https://bugs.freedesktop.org/show_bug.cgi?id=105683
  fdo#106680 https://bugs.freedesktop.org/show_bug.cgi?id=106680
  fdo#106886 https://bugs.freedesktop.org/show_bug.cgi?id=106886
  fdo#107815 https://bugs.freedesktop.org/show_bug.cgi?id=107815
  fdo#107956 https://bugs.freedesktop.org/show_bug.cgi?id=107956
  fdo#108145 https://bugs.freedesktop.org/show_bug.cgi?id=108145
  fdo#99912 https://bugs.freedesktop.org/show_bug.cgi?id=99912


== Participating hosts (6 -> 6) ==

  No changes in participating hosts


== Build changes ==

    * Linux: CI_DRM_5022 -> Patchwork_10547

  CI_DRM_5022: 23e3398e765478f4adb4783543b62a3e6b3ed554 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_4688: fa6dbf8c048961356fd642df047cb58ab49309b2 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_10547: fa36cffdcccc92b88abaccd1b448d741f64e76c9 @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_10547/shards.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v4 1/8] drm/i915: Make sure fb gtt offsets stay within 32bits
  2018-10-23 16:02   ` [PATCH v4 " Ville Syrjala
@ 2018-10-23 18:49     ` Chris Wilson
  2018-10-23 19:16       ` Ville Syrjälä
  0 siblings, 1 reply; 62+ messages in thread
From: Chris Wilson @ 2018-10-23 18:49 UTC (permalink / raw)
  To: Ville Syrjala, intel-gfx

Quoting Ville Syrjala (2018-10-23 17:02:01)
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Let's try to make sure the fb offset computations never hit
> an integer overflow by making sure the entire fb stays
> below 32bits. framebuffer_check() in the core already does
> the same check, but as it doesn't know about tiling some things
> can slip through. Repeat the check in the driver with tiling
> taken into account.
> 
> v2: Use add_overflows() after massaging it to work for me (Chris)
> v3: Call it add_overflow_t() to match min_t() & co. (Chris)
> 
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_utils.h    | 11 +++++++----
>  drivers/gpu/drm/i915/intel_display.c | 18 +++++++++++++++++-
>  2 files changed, 24 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h
> index 5858a43e19da..9726df37c4c4 100644
> --- a/drivers/gpu/drm/i915/i915_utils.h
> +++ b/drivers/gpu/drm/i915/i915_utils.h
> @@ -44,16 +44,19 @@
>                              __stringify(x), (long)(x))
>  
>  #if defined(GCC_VERSION) && GCC_VERSION >= 70000
> -#define add_overflows(A, B) \
> -       __builtin_add_overflow_p((A), (B), (typeof((A) + (B)))0)
> +#define add_overflows_t(T, A, B) \
> +       __builtin_add_overflow_p((A), (B), (T)0)
>  #else
> -#define add_overflows(A, B) ({ \
> +#define add_overflows_t(T, A, B) ({ \
>         typeof(A) a = (A); \
>         typeof(B) b = (B); \
> -       a + b < a; \
> +       (T)(a + b) < a; \
>  })
>  #endif
>  
> +#define add_overflows(A, B) \
> +       add_overflows_t(typeof((A) + (B)), (A), (B))
> +
>  #define range_overflows(start, size, max) ({ \
>         typeof(start) start__ = (start); \
>         typeof(size) size__ = (size); \
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 969d22ca8dcd..e520facc23e1 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2351,10 +2351,26 @@ static int intel_fb_offset_to_xy(int *x, int *y,
>                                  int color_plane)
>  {
>         struct drm_i915_private *dev_priv = to_i915(fb->dev);
> +       unsigned int height;
>  
>         if (fb->modifier != DRM_FORMAT_MOD_LINEAR &&
> -           fb->offsets[color_plane] % intel_tile_size(dev_priv))
> +           fb->offsets[color_plane] % intel_tile_size(dev_priv)) {
> +               DRM_DEBUG_KMS("Misaligned offset 0x%08x for color plane %d\n",
> +                             fb->offsets[color_plane], color_plane);
>                 return -EINVAL;
> +       }
> +
> +       height = drm_framebuffer_plane_height(fb->height, fb, color_plane);
> +       height = ALIGN(height, intel_tile_height(fb, color_plane));

fb height is limited to u16 or thereabouts?

> +
> +       /* Catch potential overflows early */
> +       if (add_overflows_t(u32, mul_u32_u32(height, fb->pitches[color_plane]),
> +                           fb->offsets[color_plane])) {
> +               DRM_DEBUG_KMS("Bad offset 0x%08x or pitch %d for color plane %d\n",
> +                             fb->offsets[color_plane], fb->pitches[color_plane],
> +                             color_plane);
> +               return -ERANGE;
> +       }

Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 2/8] drm/i915: Decouple SKL stride units from intel_fb_stride_alignment()
  2018-09-25 19:37 ` [PATCH v3 2/8] drm/i915: Decouple SKL stride units from intel_fb_stride_alignment() Ville Syrjala
@ 2018-10-23 18:50   ` Chris Wilson
  0 siblings, 0 replies; 62+ messages in thread
From: Chris Wilson @ 2018-10-23 18:50 UTC (permalink / raw)
  To: Ville Syrjala, intel-gfx

Quoting Ville Syrjala (2018-09-25 20:37:08)
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> In the future framebuffer stride alignment requirements won't exactly
> match the units in which skl+ plane stride is specified. So extract
> the code for the skl+ stuff into a separate helper.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

Looks mechanical enough,
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v4 3/8] drm/i915: Add a new "remapped" gtt_view
  2018-10-23 16:02   ` [PATCH v4 " Ville Syrjala
@ 2018-10-23 18:56     ` Chris Wilson
  2018-10-23 19:10       ` Ville Syrjälä
  2018-10-26  9:19     ` Tvrtko Ursulin
  1 sibling, 1 reply; 62+ messages in thread
From: Chris Wilson @ 2018-10-23 18:56 UTC (permalink / raw)
  To: Ville Syrjala, intel-gfx

Quoting Ville Syrjala (2018-10-23 17:02:36)
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> To overcome display engine stride limits we'll want to remap the
> pages in the GTT. To that end we need a new gtt_view type which
> is just like the "rotated" type except not rotated.
> 
> v2: Use intel_remapped_plane_info base type
>     s/unused/unused_mbz/ (Chris)
>     Separate BUILD_BUG_ON()s (Chris)
>     Use I915_GTT_PAGE_SIZE (Chris)
> v3: Use i915_gem_object_get_dma_address() (Chris)
>     Trim the sg (Tvrtko)
> 
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_debugfs.c       | 12 ++++
>  drivers/gpu/drm/i915/i915_gem_gtt.c       | 74 +++++++++++++++++++++++
>  drivers/gpu/drm/i915/i915_gem_gtt.h       | 25 ++++++--
>  drivers/gpu/drm/i915/i915_vma.c           |  6 +-
>  drivers/gpu/drm/i915/i915_vma.h           |  3 +
>  drivers/gpu/drm/i915/intel_display.c      | 11 ++++
>  drivers/gpu/drm/i915/intel_drv.h          |  1 +
>  drivers/gpu/drm/i915/selftests/i915_vma.c |  6 +-
>  8 files changed, 130 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 5b37d5f8e132..ce019126304d 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -196,6 +196,18 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
>                                            vma->ggtt_view.rotated.plane[1].offset);
>                                 break;
>  
> +                       case I915_GGTT_VIEW_REMAPPED:
> +                               seq_printf(m, ", remapped [(%ux%u, stride=%u, offset=%u), (%ux%u, stride=%u, offset=%u)]",
> +                                          vma->ggtt_view.remapped.plane[0].width,
> +                                          vma->ggtt_view.remapped.plane[0].height,
> +                                          vma->ggtt_view.remapped.plane[0].stride,
> +                                          vma->ggtt_view.remapped.plane[0].offset,
> +                                          vma->ggtt_view.remapped.plane[1].width,
> +                                          vma->ggtt_view.remapped.plane[1].height,
> +                                          vma->ggtt_view.remapped.plane[1].stride,
> +                                          vma->ggtt_view.remapped.plane[1].offset);
> +                               break;
> +
>                         default:
>                                 MISSING_CASE(vma->ggtt_view.type);
>                                 break;
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 98d9a1eb1ed2..d0e50b584ebd 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -3705,6 +3705,75 @@ intel_rotate_pages(struct intel_rotation_info *rot_info,
>         return ERR_PTR(ret);
>  }
>  
> +static struct scatterlist *
> +remap_pages(struct drm_i915_gem_object *obj, unsigned int offset,
> +           unsigned int width, unsigned int height,
> +           unsigned int stride,
> +           struct sg_table *st, struct scatterlist *sg)
> +{
> +       unsigned int column, row;
> +
> +       for (row = 0; row < height; row++) {
> +               for (column = 0; column < width; column++) {
> +                       st->nents++;
> +                       /* We don't need the pages, but need to initialize
> +                        * the entries so the sg list can be happily traversed.
> +                        * The only thing we need are DMA addresses.
> +                        */
> +                       sg_set_page(sg, NULL, I915_GTT_PAGE_SIZE, 0);
> +                       sg_dma_address(sg) =
> +                               i915_gem_object_get_dma_address(obj, offset + column);
> +                       sg_dma_len(sg) = I915_GTT_PAGE_SIZE;

There's a bit of work that we could apply here with
i915_gem_object_get_sg() and try and keep large spans. Probably not very
important given that this is for GGTT and so not supporting large PTE,
so we only loose out on keeping the vma->pages sg as small as possible.

> +                       sg = sg_next(sg);
> +               }
> +               offset += stride;
> +       }
> +
> +       return sg;
> +}
> +
> +static noinline struct sg_table *
> +intel_remap_pages(struct intel_remapped_info *rem_info,
> +                 struct drm_i915_gem_object *obj)
> +{
> +       unsigned int size = intel_remapped_info_size(rem_info);
> +       struct sg_table *st;
> +       struct scatterlist *sg;
> +       int ret = -ENOMEM;
> +       int i;
> +
> +       /* Allocate target SG list. */
> +       st = kmalloc(sizeof(*st), GFP_KERNEL);
> +       if (!st)
> +               goto err_st_alloc;
> +
> +       ret = sg_alloc_table(st, size, GFP_KERNEL);
> +       if (ret)
> +               goto err_sg_alloc;
> +
> +       st->nents = 0;
> +       sg = st->sgl;
> +
> +       for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
> +               sg = remap_pages(obj, rem_info->plane[i].offset,
> +                                rem_info->plane[i].width, rem_info->plane[i].height,
> +                                rem_info->plane[i].stride, st, sg);
> +       }
> +
> +       i915_sg_trim(st);
> +
> +       return st;
> +
> +err_sg_alloc:
> +       kfree(st);
> +err_st_alloc:
> +
> +       DRM_DEBUG_DRIVER("Failed to create remapped mapping for object size %zu! (%ux%u tiles, %u pages)\n",
> +                        obj->base.size, rem_info->plane[0].width, rem_info->plane[0].height, size);
> +
> +       return ERR_PTR(ret);
> +}
> +
>  static noinline struct sg_table *
>  intel_partial_pages(const struct i915_ggtt_view *view,
>                     struct drm_i915_gem_object *obj)
> @@ -3783,6 +3852,11 @@ i915_get_ggtt_vma_pages(struct i915_vma *vma)
>                         intel_rotate_pages(&vma->ggtt_view.rotated, vma->obj);
>                 break;
>  
> +       case I915_GGTT_VIEW_REMAPPED:
> +               vma->pages =
> +                       intel_remap_pages(&vma->ggtt_view.remapped, vma->obj);
> +               break;
> +
>         case I915_GGTT_VIEW_PARTIAL:
>                 vma->pages = intel_partial_pages(&vma->ggtt_view, vma->obj);
>                 break;
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
> index 7e2af5f4f39b..69a22f57e6ca 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.h
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
> @@ -160,11 +160,18 @@ typedef u64 gen8_ppgtt_pml4e_t;
>  
>  struct sg_table;
>  
> +struct intel_remapped_plane_info {
> +       /* in gtt pages */
> +       unsigned int width, height, stride, offset;
> +} __packed;
> +
> +struct intel_remapped_info {
> +       struct intel_remapped_plane_info plane[2];
> +       unsigned int unused_mbz;
> +} __packed;
> +
>  struct intel_rotation_info {
> -       struct intel_rotation_plane_info {
> -               /* tiles */
> -               unsigned int width, height, stride, offset;
> -       } plane[2];
> +       struct intel_remapped_plane_info plane[2];
>  } __packed;
>  
>  struct intel_partial_info {
> @@ -176,12 +183,20 @@ enum i915_ggtt_view_type {
>         I915_GGTT_VIEW_NORMAL = 0,
>         I915_GGTT_VIEW_ROTATED = sizeof(struct intel_rotation_info),
>         I915_GGTT_VIEW_PARTIAL = sizeof(struct intel_partial_info),
> +       I915_GGTT_VIEW_REMAPPED = sizeof(struct intel_remapped_info),
>  };
>  
>  static inline void assert_i915_gem_gtt_types(void)
>  {
>         BUILD_BUG_ON(sizeof(struct intel_rotation_info) != 8*sizeof(unsigned int));
>         BUILD_BUG_ON(sizeof(struct intel_partial_info) != sizeof(u64) + sizeof(unsigned int));
> +       BUILD_BUG_ON(sizeof(struct intel_remapped_info) != 9*sizeof(unsigned int));
> +
> +       /* Check that rotation/remapped shares offsets for simplicity */
> +       BUILD_BUG_ON(offsetof(struct intel_remapped_info, plane[0]) !=
> +                    offsetof(struct intel_rotation_info, plane[0]));
> +       BUILD_BUG_ON(offsetofend(struct intel_remapped_info, plane[1]) !=
> +                    offsetofend(struct intel_rotation_info, plane[1]));
>  
>         /* As we encode the size of each branch inside the union into its type,
>          * we have to be careful that each branch has a unique size.
> @@ -190,6 +205,7 @@ static inline void assert_i915_gem_gtt_types(void)
>         case I915_GGTT_VIEW_NORMAL:
>         case I915_GGTT_VIEW_PARTIAL:
>         case I915_GGTT_VIEW_ROTATED:
> +       case I915_GGTT_VIEW_REMAPPED:
>                 /* gcc complains if these are identical cases */
>                 break;
>         }
> @@ -201,6 +217,7 @@ struct i915_ggtt_view {
>                 /* Members need to contain no holes/padding */
>                 struct intel_partial_info partial;
>                 struct intel_rotation_info rotated;
> +               struct intel_remapped_info remapped;
>         };
>  };
>  
> diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
> index 82652c3d1bed..2070e44eaa03 100644
> --- a/drivers/gpu/drm/i915/i915_vma.c
> +++ b/drivers/gpu/drm/i915/i915_vma.c
> @@ -164,6 +164,9 @@ vma_create(struct drm_i915_gem_object *obj,
>                 } else if (view->type == I915_GGTT_VIEW_ROTATED) {
>                         vma->size = intel_rotation_info_size(&view->rotated);
>                         vma->size <<= PAGE_SHIFT;
> +               } else if (view->type == I915_GGTT_VIEW_REMAPPED) {
> +                       vma->size = intel_remapped_info_size(&view->remapped);
> +                       vma->size <<= PAGE_SHIFT;
>                 }
>         }
>  
> @@ -464,7 +467,8 @@ void __i915_vma_set_map_and_fenceable(struct i915_vma *vma)
>          * Explicitly disable for rotated VMA since the display does not
>          * need the fence and the VMA is not accessible to other users.
>          */
> -       if (vma->ggtt_view.type == I915_GGTT_VIEW_ROTATED)
> +       if (vma->ggtt_view.type == I915_GGTT_VIEW_ROTATED ||
> +           vma->ggtt_view.type == I915_GGTT_VIEW_REMAPPED)
>                 return;

Hmm, still sure we don't want fences on the remapped view? Seems
potentially useful.
  
>         fenceable = (vma->node.size >= vma->fence_size &&
> diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
> index 4f7c1c7599f4..64cf029c028a 100644
> --- a/drivers/gpu/drm/i915/i915_vma.h
> +++ b/drivers/gpu/drm/i915/i915_vma.h
> @@ -265,8 +265,11 @@ i915_vma_compare(struct i915_vma *vma,
>          */
>         BUILD_BUG_ON(I915_GGTT_VIEW_NORMAL >= I915_GGTT_VIEW_PARTIAL);
>         BUILD_BUG_ON(I915_GGTT_VIEW_PARTIAL >= I915_GGTT_VIEW_ROTATED);
> +       BUILD_BUG_ON(I915_GGTT_VIEW_ROTATED >= I915_GGTT_VIEW_REMAPPED);
>         BUILD_BUG_ON(offsetof(typeof(*view), rotated) !=
>                      offsetof(typeof(*view), partial));
> +       BUILD_BUG_ON(offsetof(typeof(*view), rotated) !=
> +                    offsetof(typeof(*view), remapped));
>         return memcmp(&vma->ggtt_view.partial, &view->partial, view->type);
>  }
>  
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 8a0b477a69d3..41f7e0795b14 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -1957,6 +1957,17 @@ unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info
>         return size;
>  }
>  
> +unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info)
> +{
> +       unsigned int size = 0;
> +       int i;
> +

I was looking for a good place to stick
	GEM_BUG_ON(rem_info->unused_mbz);
Here?

> +       for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++)
> +               size += rem_info->plane[i].width * rem_info->plane[i].height;
> +
> +       return size;
> +}
> +
>  static void
>  intel_fill_fb_ggtt_view(struct i915_ggtt_view *view,
>                         const struct drm_framebuffer *fb,
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 0e9a926fca04..6993eff5dfaf 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1523,6 +1523,7 @@ unsigned int intel_fb_xy_to_linear(int x, int y,
>  void intel_add_fb_offsets(int *x, int *y,
>                           const struct intel_plane_state *state, int plane);
>  unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info);
> +unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info);
>  bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv);
>  void intel_mark_busy(struct drm_i915_private *dev_priv);
>  void intel_mark_idle(struct drm_i915_private *dev_priv);
> diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c
> index ffa74290e054..4fc49c27f13c 100644
> --- a/drivers/gpu/drm/i915/selftests/i915_vma.c
> +++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
> @@ -395,8 +395,8 @@ assert_rotated(struct drm_i915_gem_object *obj,
>         return sg;
>  }
>  
> -static unsigned int rotated_size(const struct intel_rotation_plane_info *a,
> -                                const struct intel_rotation_plane_info *b)
> +static unsigned int rotated_size(const struct intel_remapped_plane_info *a,
> +                                const struct intel_remapped_plane_info *b)
>  {
>         return a->width * a->height + b->width * b->height;
>  }
> @@ -406,7 +406,7 @@ static int igt_vma_rotate(void *arg)
>         struct drm_i915_private *i915 = arg;
>         struct i915_address_space *vm = &i915->ggtt.vm;
>         struct drm_i915_gem_object *obj;
> -       const struct intel_rotation_plane_info planes[] = {
> +       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 },

The question on whether we do want fences here notwithstanding,
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v4 4/8] drm/i915/selftests: Add mock selftest for remapped vmas
  2018-10-23 16:03   ` [PATCH v4 " Ville Syrjala
@ 2018-10-23 19:02     ` Chris Wilson
  2018-10-23 19:14       ` Ville Syrjälä
  0 siblings, 1 reply; 62+ messages in thread
From: Chris Wilson @ 2018-10-23 19:02 UTC (permalink / raw)
  To: Ville Syrjala, intel-gfx

Quoting Ville Syrjala (2018-10-23 17:03:01)
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Extend the rotated vma mock selftest to cover remapped vmas as
> well.
> 
> TODO: reindent the loops I guess? Left like this for now to
> ease review
> 
> v2: Include the vma type in the error message (Chris)
> 
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
> +static struct scatterlist *
> +assert_remapped(struct drm_i915_gem_object *obj,
> +               const struct intel_remapped_info *r, unsigned int n,
> +               struct scatterlist *sg)
> +{
> +       unsigned int x, y;
> +
> +       for (y = 0; y < r->plane[n].height; y++) {
> +               for (x = 0; x < r->plane[n].width; x++) {
> +                       unsigned long src_idx;
> +                       dma_addr_t src;
> +
> +                       if (!sg) {
> +                               pr_err("Invalid sg table: too short at plane %d, (%d, %d)!\n",
> +                                      n, x, y);
> +                               return ERR_PTR(-EINVAL);
> +                       }
> +
> +                       src_idx = remapped_index(r, n, x, y);
> +                       src = i915_gem_object_get_dma_address(obj, src_idx);
> +
> +                       if (sg_dma_len(sg) != PAGE_SIZE) {
> +                               pr_err("Invalid sg.length, found %d, expected %lu for remapped page (%d, %d) [src index %lu]\n",
> +                                      sg_dma_len(sg), PAGE_SIZE,
> +                                      x, y, src_idx);
> +                               return ERR_PTR(-EINVAL);
> +                       }

Meh, seems overly restrictive for a remapped view. But given we are
iterating by pages and have restricted the construction to be page
aligned (though didn't we use I915_GTT_PAGE_SIZE in the constructor?),
seems reasonable for a first stab.

~o~ it fits the series, but it doesn't validate potential changes.

Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v4 5/8] drm/i915/selftests: Add live vma selftest
  2018-10-23 16:03   ` [PATCH v4 " Ville Syrjala
@ 2018-10-23 19:05     ` Chris Wilson
  0 siblings, 0 replies; 62+ messages in thread
From: Chris Wilson @ 2018-10-23 19:05 UTC (permalink / raw)
  To: Ville Syrjala, intel-gfx

Quoting Ville Syrjala (2018-10-23 17:03:17)
> 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.
> 
> v2: Grab rpm reference (Chris)
>     GEM_BUG_ON(view.type not as expected) (Chris)
>     Allow CAN_FENCE for rotated/remapped vmas (Chris)
>     Update intel_plane_uses_fence() to ask for a fence
>     only for normal vmas on gen4+
> 
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_vma.c               |   8 -
>  drivers/gpu/drm/i915/intel_display.c          |   4 +-
>  .../drm/i915/selftests/i915_live_selftests.h  |   1 +
>  drivers/gpu/drm/i915/selftests/i915_vma.c     | 140 ++++++++++++++++++
>  4 files changed, 144 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
> index 2070e44eaa03..6fe0749dec32 100644
> --- a/drivers/gpu/drm/i915/i915_vma.c
> +++ b/drivers/gpu/drm/i915/i915_vma.c
> @@ -463,14 +463,6 @@ void __i915_vma_set_map_and_fenceable(struct i915_vma *vma)
>         GEM_BUG_ON(!i915_vma_is_ggtt(vma));
>         GEM_BUG_ON(!vma->fence_size);
>  
> -       /*
> -        * Explicitly disable for rotated VMA since the display does not
> -        * need the fence and the VMA is not accessible to other users.
> -        */
> -       if (vma->ggtt_view.type == I915_GGTT_VIEW_ROTATED ||
> -           vma->ggtt_view.type == I915_GGTT_VIEW_REMAPPED)
> -               return;

:)

>         fenceable = (vma->node.size >= vma->fence_size &&
>                      IS_ALIGNED(vma->node.start, vma->fence_alignment));
>  
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 41f7e0795b14..582e8d192abd 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2037,7 +2037,9 @@ static bool intel_plane_uses_fence(const struct intel_plane_state *plane_state)
>         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
>         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
>  
> -       return INTEL_GEN(dev_priv) < 4 || plane->has_fbc;
> +       return INTEL_GEN(dev_priv) < 4 ||
> +               (plane->has_fbc &&
> +                plane_state->view.type == I915_GGTT_VIEW_NORMAL);

Hmm. We only want to use a common fence for FBC so that we have
automatic tracking. Ok. Memory is starting to fade back in.

>  struct i915_vma *
> 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 64c5055c83f9..208629057839 100644
> --- a/drivers/gpu/drm/i915/selftests/i915_vma.c
> +++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
> @@ -799,3 +799,143 @@ 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);
> +
> +       intel_runtime_pm_get(i915);
> +
> +       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;
> +                       }
> +
> +                       GEM_BUG_ON(vma->ggtt_view.type != *t);
> +
> +                       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->ggtt_view.type != I915_GGTT_VIEW_NORMAL);
> +
> +                       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:
> +       intel_runtime_pm_put(i915);
> +       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);
> +}

Neat,
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v4 3/8] drm/i915: Add a new "remapped" gtt_view
  2018-10-23 18:56     ` Chris Wilson
@ 2018-10-23 19:10       ` Ville Syrjälä
  0 siblings, 0 replies; 62+ messages in thread
From: Ville Syrjälä @ 2018-10-23 19:10 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

On Tue, Oct 23, 2018 at 07:56:58PM +0100, Chris Wilson wrote:
> Quoting Ville Syrjala (2018-10-23 17:02:36)
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > To overcome display engine stride limits we'll want to remap the
> > pages in the GTT. To that end we need a new gtt_view type which
> > is just like the "rotated" type except not rotated.
> > 
> > v2: Use intel_remapped_plane_info base type
> >     s/unused/unused_mbz/ (Chris)
> >     Separate BUILD_BUG_ON()s (Chris)
> >     Use I915_GTT_PAGE_SIZE (Chris)
> > v3: Use i915_gem_object_get_dma_address() (Chris)
> >     Trim the sg (Tvrtko)
> > 
> > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> > Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_debugfs.c       | 12 ++++
> >  drivers/gpu/drm/i915/i915_gem_gtt.c       | 74 +++++++++++++++++++++++
> >  drivers/gpu/drm/i915/i915_gem_gtt.h       | 25 ++++++--
> >  drivers/gpu/drm/i915/i915_vma.c           |  6 +-
> >  drivers/gpu/drm/i915/i915_vma.h           |  3 +
> >  drivers/gpu/drm/i915/intel_display.c      | 11 ++++
> >  drivers/gpu/drm/i915/intel_drv.h          |  1 +
> >  drivers/gpu/drm/i915/selftests/i915_vma.c |  6 +-
> >  8 files changed, 130 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> > index 5b37d5f8e132..ce019126304d 100644
> > --- a/drivers/gpu/drm/i915/i915_debugfs.c
> > +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> > @@ -196,6 +196,18 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
> >                                            vma->ggtt_view.rotated.plane[1].offset);
> >                                 break;
> >  
> > +                       case I915_GGTT_VIEW_REMAPPED:
> > +                               seq_printf(m, ", remapped [(%ux%u, stride=%u, offset=%u), (%ux%u, stride=%u, offset=%u)]",
> > +                                          vma->ggtt_view.remapped.plane[0].width,
> > +                                          vma->ggtt_view.remapped.plane[0].height,
> > +                                          vma->ggtt_view.remapped.plane[0].stride,
> > +                                          vma->ggtt_view.remapped.plane[0].offset,
> > +                                          vma->ggtt_view.remapped.plane[1].width,
> > +                                          vma->ggtt_view.remapped.plane[1].height,
> > +                                          vma->ggtt_view.remapped.plane[1].stride,
> > +                                          vma->ggtt_view.remapped.plane[1].offset);
> > +                               break;
> > +
> >                         default:
> >                                 MISSING_CASE(vma->ggtt_view.type);
> >                                 break;
> > diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> > index 98d9a1eb1ed2..d0e50b584ebd 100644
> > --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> > +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> > @@ -3705,6 +3705,75 @@ intel_rotate_pages(struct intel_rotation_info *rot_info,
> >         return ERR_PTR(ret);
> >  }
> >  
> > +static struct scatterlist *
> > +remap_pages(struct drm_i915_gem_object *obj, unsigned int offset,
> > +           unsigned int width, unsigned int height,
> > +           unsigned int stride,
> > +           struct sg_table *st, struct scatterlist *sg)
> > +{
> > +       unsigned int column, row;
> > +
> > +       for (row = 0; row < height; row++) {
> > +               for (column = 0; column < width; column++) {
> > +                       st->nents++;
> > +                       /* We don't need the pages, but need to initialize
> > +                        * the entries so the sg list can be happily traversed.
> > +                        * The only thing we need are DMA addresses.
> > +                        */
> > +                       sg_set_page(sg, NULL, I915_GTT_PAGE_SIZE, 0);
> > +                       sg_dma_address(sg) =
> > +                               i915_gem_object_get_dma_address(obj, offset + column);
> > +                       sg_dma_len(sg) = I915_GTT_PAGE_SIZE;
> 
> There's a bit of work that we could apply here with
> i915_gem_object_get_sg() and try and keep large spans. Probably not very
> important given that this is for GGTT and so not supporting large PTE,
> so we only loose out on keeping the vma->pages sg as small as possible.
> 
> > +                       sg = sg_next(sg);
> > +               }
> > +               offset += stride;
> > +       }
> > +
> > +       return sg;
> > +}
> > +
> > +static noinline struct sg_table *
> > +intel_remap_pages(struct intel_remapped_info *rem_info,
> > +                 struct drm_i915_gem_object *obj)
> > +{
> > +       unsigned int size = intel_remapped_info_size(rem_info);
> > +       struct sg_table *st;
> > +       struct scatterlist *sg;
> > +       int ret = -ENOMEM;
> > +       int i;
> > +
> > +       /* Allocate target SG list. */
> > +       st = kmalloc(sizeof(*st), GFP_KERNEL);
> > +       if (!st)
> > +               goto err_st_alloc;
> > +
> > +       ret = sg_alloc_table(st, size, GFP_KERNEL);
> > +       if (ret)
> > +               goto err_sg_alloc;
> > +
> > +       st->nents = 0;
> > +       sg = st->sgl;
> > +
> > +       for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
> > +               sg = remap_pages(obj, rem_info->plane[i].offset,
> > +                                rem_info->plane[i].width, rem_info->plane[i].height,
> > +                                rem_info->plane[i].stride, st, sg);
> > +       }
> > +
> > +       i915_sg_trim(st);
> > +
> > +       return st;
> > +
> > +err_sg_alloc:
> > +       kfree(st);
> > +err_st_alloc:
> > +
> > +       DRM_DEBUG_DRIVER("Failed to create remapped mapping for object size %zu! (%ux%u tiles, %u pages)\n",
> > +                        obj->base.size, rem_info->plane[0].width, rem_info->plane[0].height, size);
> > +
> > +       return ERR_PTR(ret);
> > +}
> > +
> >  static noinline struct sg_table *
> >  intel_partial_pages(const struct i915_ggtt_view *view,
> >                     struct drm_i915_gem_object *obj)
> > @@ -3783,6 +3852,11 @@ i915_get_ggtt_vma_pages(struct i915_vma *vma)
> >                         intel_rotate_pages(&vma->ggtt_view.rotated, vma->obj);
> >                 break;
> >  
> > +       case I915_GGTT_VIEW_REMAPPED:
> > +               vma->pages =
> > +                       intel_remap_pages(&vma->ggtt_view.remapped, vma->obj);
> > +               break;
> > +
> >         case I915_GGTT_VIEW_PARTIAL:
> >                 vma->pages = intel_partial_pages(&vma->ggtt_view, vma->obj);
> >                 break;
> > diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
> > index 7e2af5f4f39b..69a22f57e6ca 100644
> > --- a/drivers/gpu/drm/i915/i915_gem_gtt.h
> > +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
> > @@ -160,11 +160,18 @@ typedef u64 gen8_ppgtt_pml4e_t;
> >  
> >  struct sg_table;
> >  
> > +struct intel_remapped_plane_info {
> > +       /* in gtt pages */
> > +       unsigned int width, height, stride, offset;
> > +} __packed;
> > +
> > +struct intel_remapped_info {
> > +       struct intel_remapped_plane_info plane[2];
> > +       unsigned int unused_mbz;
> > +} __packed;
> > +
> >  struct intel_rotation_info {
> > -       struct intel_rotation_plane_info {
> > -               /* tiles */
> > -               unsigned int width, height, stride, offset;
> > -       } plane[2];
> > +       struct intel_remapped_plane_info plane[2];
> >  } __packed;
> >  
> >  struct intel_partial_info {
> > @@ -176,12 +183,20 @@ enum i915_ggtt_view_type {
> >         I915_GGTT_VIEW_NORMAL = 0,
> >         I915_GGTT_VIEW_ROTATED = sizeof(struct intel_rotation_info),
> >         I915_GGTT_VIEW_PARTIAL = sizeof(struct intel_partial_info),
> > +       I915_GGTT_VIEW_REMAPPED = sizeof(struct intel_remapped_info),
> >  };
> >  
> >  static inline void assert_i915_gem_gtt_types(void)
> >  {
> >         BUILD_BUG_ON(sizeof(struct intel_rotation_info) != 8*sizeof(unsigned int));
> >         BUILD_BUG_ON(sizeof(struct intel_partial_info) != sizeof(u64) + sizeof(unsigned int));
> > +       BUILD_BUG_ON(sizeof(struct intel_remapped_info) != 9*sizeof(unsigned int));
> > +
> > +       /* Check that rotation/remapped shares offsets for simplicity */
> > +       BUILD_BUG_ON(offsetof(struct intel_remapped_info, plane[0]) !=
> > +                    offsetof(struct intel_rotation_info, plane[0]));
> > +       BUILD_BUG_ON(offsetofend(struct intel_remapped_info, plane[1]) !=
> > +                    offsetofend(struct intel_rotation_info, plane[1]));
> >  
> >         /* As we encode the size of each branch inside the union into its type,
> >          * we have to be careful that each branch has a unique size.
> > @@ -190,6 +205,7 @@ static inline void assert_i915_gem_gtt_types(void)
> >         case I915_GGTT_VIEW_NORMAL:
> >         case I915_GGTT_VIEW_PARTIAL:
> >         case I915_GGTT_VIEW_ROTATED:
> > +       case I915_GGTT_VIEW_REMAPPED:
> >                 /* gcc complains if these are identical cases */
> >                 break;
> >         }
> > @@ -201,6 +217,7 @@ struct i915_ggtt_view {
> >                 /* Members need to contain no holes/padding */
> >                 struct intel_partial_info partial;
> >                 struct intel_rotation_info rotated;
> > +               struct intel_remapped_info remapped;
> >         };
> >  };
> >  
> > diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
> > index 82652c3d1bed..2070e44eaa03 100644
> > --- a/drivers/gpu/drm/i915/i915_vma.c
> > +++ b/drivers/gpu/drm/i915/i915_vma.c
> > @@ -164,6 +164,9 @@ vma_create(struct drm_i915_gem_object *obj,
> >                 } else if (view->type == I915_GGTT_VIEW_ROTATED) {
> >                         vma->size = intel_rotation_info_size(&view->rotated);
> >                         vma->size <<= PAGE_SHIFT;
> > +               } else if (view->type == I915_GGTT_VIEW_REMAPPED) {
> > +                       vma->size = intel_remapped_info_size(&view->remapped);
> > +                       vma->size <<= PAGE_SHIFT;
> >                 }
> >         }
> >  
> > @@ -464,7 +467,8 @@ void __i915_vma_set_map_and_fenceable(struct i915_vma *vma)
> >          * Explicitly disable for rotated VMA since the display does not
> >          * need the fence and the VMA is not accessible to other users.
> >          */
> > -       if (vma->ggtt_view.type == I915_GGTT_VIEW_ROTATED)
> > +       if (vma->ggtt_view.type == I915_GGTT_VIEW_ROTATED ||
> > +           vma->ggtt_view.type == I915_GGTT_VIEW_REMAPPED)
> >                 return;
> 
> Hmm, still sure we don't want fences on the remapped view? Seems
> potentially useful.

I remove that restriction in the selftest patch since that's the first
thing that really needs it. I was pondering about moving it to an
entirely separate patch but for whatever reason decided against it.
I can still split it out if people prefer that?

>   
> >         fenceable = (vma->node.size >= vma->fence_size &&
> > diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
> > index 4f7c1c7599f4..64cf029c028a 100644
> > --- a/drivers/gpu/drm/i915/i915_vma.h
> > +++ b/drivers/gpu/drm/i915/i915_vma.h
> > @@ -265,8 +265,11 @@ i915_vma_compare(struct i915_vma *vma,
> >          */
> >         BUILD_BUG_ON(I915_GGTT_VIEW_NORMAL >= I915_GGTT_VIEW_PARTIAL);
> >         BUILD_BUG_ON(I915_GGTT_VIEW_PARTIAL >= I915_GGTT_VIEW_ROTATED);
> > +       BUILD_BUG_ON(I915_GGTT_VIEW_ROTATED >= I915_GGTT_VIEW_REMAPPED);
> >         BUILD_BUG_ON(offsetof(typeof(*view), rotated) !=
> >                      offsetof(typeof(*view), partial));
> > +       BUILD_BUG_ON(offsetof(typeof(*view), rotated) !=
> > +                    offsetof(typeof(*view), remapped));
> >         return memcmp(&vma->ggtt_view.partial, &view->partial, view->type);
> >  }
> >  
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 8a0b477a69d3..41f7e0795b14 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -1957,6 +1957,17 @@ unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info
> >         return size;
> >  }
> >  
> > +unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info)
> > +{
> > +       unsigned int size = 0;
> > +       int i;
> > +
> 
> I was looking for a good place to stick
> 	GEM_BUG_ON(rem_info->unused_mbz);
> Here?

I guess this as good a place as any. I shall add it.

> 
> > +       for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++)
> > +               size += rem_info->plane[i].width * rem_info->plane[i].height;
> > +
> > +       return size;
> > +}
> > +
> >  static void
> >  intel_fill_fb_ggtt_view(struct i915_ggtt_view *view,
> >                         const struct drm_framebuffer *fb,
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index 0e9a926fca04..6993eff5dfaf 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -1523,6 +1523,7 @@ unsigned int intel_fb_xy_to_linear(int x, int y,
> >  void intel_add_fb_offsets(int *x, int *y,
> >                           const struct intel_plane_state *state, int plane);
> >  unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info);
> > +unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info);
> >  bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv);
> >  void intel_mark_busy(struct drm_i915_private *dev_priv);
> >  void intel_mark_idle(struct drm_i915_private *dev_priv);
> > diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c
> > index ffa74290e054..4fc49c27f13c 100644
> > --- a/drivers/gpu/drm/i915/selftests/i915_vma.c
> > +++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
> > @@ -395,8 +395,8 @@ assert_rotated(struct drm_i915_gem_object *obj,
> >         return sg;
> >  }
> >  
> > -static unsigned int rotated_size(const struct intel_rotation_plane_info *a,
> > -                                const struct intel_rotation_plane_info *b)
> > +static unsigned int rotated_size(const struct intel_remapped_plane_info *a,
> > +                                const struct intel_remapped_plane_info *b)
> >  {
> >         return a->width * a->height + b->width * b->height;
> >  }
> > @@ -406,7 +406,7 @@ static int igt_vma_rotate(void *arg)
> >         struct drm_i915_private *i915 = arg;
> >         struct i915_address_space *vm = &i915->ggtt.vm;
> >         struct drm_i915_gem_object *obj;
> > -       const struct intel_rotation_plane_info planes[] = {
> > +       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 },
> 
> The question on whether we do want fences here notwithstanding,
> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
> -Chris

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v4 4/8] drm/i915/selftests: Add mock selftest for remapped vmas
  2018-10-23 19:02     ` Chris Wilson
@ 2018-10-23 19:14       ` Ville Syrjälä
  0 siblings, 0 replies; 62+ messages in thread
From: Ville Syrjälä @ 2018-10-23 19:14 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

On Tue, Oct 23, 2018 at 08:02:16PM +0100, Chris Wilson wrote:
> Quoting Ville Syrjala (2018-10-23 17:03:01)
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Extend the rotated vma mock selftest to cover remapped vmas as
> > well.
> > 
> > TODO: reindent the loops I guess? Left like this for now to
> > ease review
> > 
> > v2: Include the vma type in the error message (Chris)
> > 
> > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> > +static struct scatterlist *
> > +assert_remapped(struct drm_i915_gem_object *obj,
> > +               const struct intel_remapped_info *r, unsigned int n,
> > +               struct scatterlist *sg)
> > +{
> > +       unsigned int x, y;
> > +
> > +       for (y = 0; y < r->plane[n].height; y++) {
> > +               for (x = 0; x < r->plane[n].width; x++) {
> > +                       unsigned long src_idx;
> > +                       dma_addr_t src;
> > +
> > +                       if (!sg) {
> > +                               pr_err("Invalid sg table: too short at plane %d, (%d, %d)!\n",
> > +                                      n, x, y);
> > +                               return ERR_PTR(-EINVAL);
> > +                       }
> > +
> > +                       src_idx = remapped_index(r, n, x, y);
> > +                       src = i915_gem_object_get_dma_address(obj, src_idx);
> > +
> > +                       if (sg_dma_len(sg) != PAGE_SIZE) {
> > +                               pr_err("Invalid sg.length, found %d, expected %lu for remapped page (%d, %d) [src index %lu]\n",
> > +                                      sg_dma_len(sg), PAGE_SIZE,
> > +                                      x, y, src_idx);
> > +                               return ERR_PTR(-EINVAL);
> > +                       }
> 
> Meh, seems overly restrictive for a remapped view. But given we are
> iterating by pages and have restricted the construction to be page
> aligned (though didn't we use I915_GTT_PAGE_SIZE in the constructor?),
> seems reasonable for a first stab.

Hrm. I am calling sg_trim() now, so I guess this is actually bonkers.
Did I not actually run the selftests after that change?

> 
> ~o~ it fits the series, but it doesn't validate potential changes.
> 
> Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
> -Chris

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v4 1/8] drm/i915: Make sure fb gtt offsets stay within 32bits
  2018-10-23 18:49     ` Chris Wilson
@ 2018-10-23 19:16       ` Ville Syrjälä
  0 siblings, 0 replies; 62+ messages in thread
From: Ville Syrjälä @ 2018-10-23 19:16 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

On Tue, Oct 23, 2018 at 07:49:42PM +0100, Chris Wilson wrote:
> Quoting Ville Syrjala (2018-10-23 17:02:01)
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Let's try to make sure the fb offset computations never hit
> > an integer overflow by making sure the entire fb stays
> > below 32bits. framebuffer_check() in the core already does
> > the same check, but as it doesn't know about tiling some things
> > can slip through. Repeat the check in the driver with tiling
> > taken into account.
> > 
> > v2: Use add_overflows() after massaging it to work for me (Chris)
> > v3: Call it add_overflow_t() to match min_t() & co. (Chris)
> > 
> > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_utils.h    | 11 +++++++----
> >  drivers/gpu/drm/i915/intel_display.c | 18 +++++++++++++++++-
> >  2 files changed, 24 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h
> > index 5858a43e19da..9726df37c4c4 100644
> > --- a/drivers/gpu/drm/i915/i915_utils.h
> > +++ b/drivers/gpu/drm/i915/i915_utils.h
> > @@ -44,16 +44,19 @@
> >                              __stringify(x), (long)(x))
> >  
> >  #if defined(GCC_VERSION) && GCC_VERSION >= 70000
> > -#define add_overflows(A, B) \
> > -       __builtin_add_overflow_p((A), (B), (typeof((A) + (B)))0)
> > +#define add_overflows_t(T, A, B) \
> > +       __builtin_add_overflow_p((A), (B), (T)0)
> >  #else
> > -#define add_overflows(A, B) ({ \
> > +#define add_overflows_t(T, A, B) ({ \
> >         typeof(A) a = (A); \
> >         typeof(B) b = (B); \
> > -       a + b < a; \
> > +       (T)(a + b) < a; \
> >  })
> >  #endif
> >  
> > +#define add_overflows(A, B) \
> > +       add_overflows_t(typeof((A) + (B)), (A), (B))
> > +
> >  #define range_overflows(start, size, max) ({ \
> >         typeof(start) start__ = (start); \
> >         typeof(size) size__ = (size); \
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 969d22ca8dcd..e520facc23e1 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -2351,10 +2351,26 @@ static int intel_fb_offset_to_xy(int *x, int *y,
> >                                  int color_plane)
> >  {
> >         struct drm_i915_private *dev_priv = to_i915(fb->dev);
> > +       unsigned int height;
> >  
> >         if (fb->modifier != DRM_FORMAT_MOD_LINEAR &&
> > -           fb->offsets[color_plane] % intel_tile_size(dev_priv))
> > +           fb->offsets[color_plane] % intel_tile_size(dev_priv)) {
> > +               DRM_DEBUG_KMS("Misaligned offset 0x%08x for color plane %d\n",
> > +                             fb->offsets[color_plane], color_plane);
> >                 return -EINVAL;
> > +       }
> > +
> > +       height = drm_framebuffer_plane_height(fb->height, fb, color_plane);
> > +       height = ALIGN(height, intel_tile_height(fb, color_plane));
> 
> fb height is limited to u16 or thereabouts?

Thereabouts. Would be <=16k after the last patch in the series.

> 
> > +
> > +       /* Catch potential overflows early */
> > +       if (add_overflows_t(u32, mul_u32_u32(height, fb->pitches[color_plane]),
> > +                           fb->offsets[color_plane])) {
> > +               DRM_DEBUG_KMS("Bad offset 0x%08x or pitch %d for color plane %d\n",
> > +                             fb->offsets[color_plane], fb->pitches[color_plane],
> > +                             color_plane);
> > +               return -ERANGE;
> > +       }
> 
> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
> -Chris

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 6/8] drm/i915: Overcome display engine stride limits via GTT remapping
  2018-09-25 19:37 ` [PATCH v3 6/8] drm/i915: Overcome display engine stride limits via GTT remapping Ville Syrjala
@ 2018-10-23 19:16   ` Chris Wilson
  2018-10-25 13:45     ` Ville Syrjälä
  0 siblings, 1 reply; 62+ messages in thread
From: Chris Wilson @ 2018-10-23 19:16 UTC (permalink / raw)
  To: Ville Syrjala, intel-gfx

Quoting Ville Syrjala (2018-09-25 20:37:12)
> +static bool intel_plane_needs_remap(const struct intel_plane_state *plane_state)
> +{
> +       struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
> +       struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> +       const struct drm_framebuffer *fb = plane_state->base.fb;
> +       unsigned int rotation = plane_state->base.rotation;
> +       u32 stride, max_stride;
> +
> +       /* We don't want to deal with remapping with cursors */
> +       if (plane->id == PLANE_CURSOR)
> +               return false;
> +
> +       /* No fence for the remapped vma */

Should work now (with a minor tweak to plane_can_fence), right?

> +       if (INTEL_GEN(dev_priv) < 4)
> +               return false;
> +
> +       /* New CCS hash mode makes remapping impossible */
> +       if (is_ccs_modifier(fb->modifier))
> +               return false;
> +
> +       /* FIXME other color planes? */
> +       stride = intel_fb_pitch(fb, 0, rotation);
> +       max_stride = plane->max_stride(plane, fb->format->format,
> +                                      fb->modifier, rotation);
> +
> +       return stride > max_stride;
> +}
> +
>  static int
>  intel_fill_fb_info(struct drm_i915_private *dev_priv,
>                    struct drm_framebuffer *fb)
> @@ -2676,6 +2741,182 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv,
>         return 0;
>  }
>  
> +static void
> +intel_plane_remap_gtt(struct intel_plane_state *plane_state)
> +{
> +       struct drm_i915_private *dev_priv =
> +               to_i915(plane_state->base.plane->dev);
> +       struct drm_framebuffer *fb = plane_state->base.fb;
> +       struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
> +       struct intel_rotation_info *info = &plane_state->view.rotated;
> +       unsigned int rotation = plane_state->base.rotation;
> +       int i, num_planes = fb->format->num_planes;
> +       unsigned int tile_size = intel_tile_size(dev_priv);
> +       unsigned int tile_width, tile_height;
> +       unsigned int aligned_x, aligned_y;
> +       unsigned int aligned_w, aligned_h;
> +       unsigned int src_x, src_y;
> +       unsigned int src_w, src_h;
> +       unsigned int x, y;
> +       u32 gtt_offset = 0;
> +
> +       memset(&plane_state->view, 0, sizeof(plane_state->view));
> +       plane_state->view.type = drm_rotation_90_or_270(rotation) ?
> +               I915_GGTT_VIEW_ROTATED : I915_GGTT_VIEW_REMAPPED;
> +
> +       src_x = plane_state->base.src.x1 >> 16;
> +       src_y = plane_state->base.src.y1 >> 16;
> +       src_w = drm_rect_width(&plane_state->base.src) >> 16;
> +       src_h = drm_rect_height(&plane_state->base.src) >> 16;
> +
> +       WARN_ON(is_ccs_modifier(fb->modifier));
> +
> +       /* Align our viewport start to tile boundary */
> +       intel_tile_dims(fb, 0, &tile_width, &tile_height);
> +
> +       x = src_x & (tile_width - 1);
> +       y = src_y & (tile_height - 1);
> +
> +       aligned_x = src_x - x;
> +       aligned_y = src_y - y;
> +
> +       aligned_w = x + src_w;
> +       aligned_h = y + src_h;
> +
> +       /* Make src coordinates relative to the aligned viewport */
> +       drm_rect_translate(&plane_state->base.src,
> +                          -(aligned_x << 16), -(aligned_y << 16));
> +
> +       /* Rotate src coordinates to match rotated GTT view */
> +       if (drm_rotation_90_or_270(rotation))
> +               drm_rect_rotate(&plane_state->base.src,
> +                               aligned_w << 16, aligned_h << 16,
> +                               DRM_MODE_ROTATE_270);
> +
> +       for (i = 0; i < num_planes; i++) {
> +               unsigned int hsub = i ? fb->format->hsub : 1;
> +               unsigned int vsub = i ? fb->format->vsub : 1;
> +               unsigned int cpp = fb->format->cpp[i];
> +               unsigned int width, height;
> +               unsigned int pitch_tiles;
> +               unsigned int x, y;
> +               u32 offset;
> +
> +               intel_tile_dims(fb, i, &tile_width, &tile_height);
> +
> +               x = aligned_x / hsub;
> +               y = aligned_y / vsub;
> +               width = aligned_w / hsub;

aligned_w here seems to be just x2.

Did I miss aligned_w = ALIGN(aligned_w, tile_width) - aligned_x?

> +               height = aligned_h / vsub;
> +
> +               /*
> +                * First pixel of the aligned src viewport
> +                * from the start of the normal gtt mapping.
> +                */
> +               x += intel_fb->normal[i].x;
> +               y += intel_fb->normal[i].y;
> +
> +               offset = intel_compute_aligned_offset(dev_priv, &x, &y,
> +                                                     fb, i, fb->pitches[i],
> +                                                     DRM_MODE_ROTATE_0, tile_size);
> +               offset /= tile_size;
> +
> +               info->plane[i].offset = offset;
> +               info->plane[i].stride = DIV_ROUND_UP(fb->pitches[i],
> +                                                    tile_width * cpp);
> +               info->plane[i].width = DIV_ROUND_UP(x + width, tile_width);
> +               info->plane[i].height = DIV_ROUND_UP(y + height, tile_height);

I thought .width here would be in pages? Ok tile_width != fence_stride
and does produce pages just fine.

And shouldn't width here be adjusted for x? Similarly for height?
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 6/8] drm/i915: Overcome display engine stride limits via GTT remapping
  2018-10-23 19:16   ` Chris Wilson
@ 2018-10-25 13:45     ` Ville Syrjälä
  0 siblings, 0 replies; 62+ messages in thread
From: Ville Syrjälä @ 2018-10-25 13:45 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

On Tue, Oct 23, 2018 at 08:16:56PM +0100, Chris Wilson wrote:
> Quoting Ville Syrjala (2018-09-25 20:37:12)
> > +static bool intel_plane_needs_remap(const struct intel_plane_state *plane_state)
> > +{
> > +       struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
> > +       struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> > +       const struct drm_framebuffer *fb = plane_state->base.fb;
> > +       unsigned int rotation = plane_state->base.rotation;
> > +       u32 stride, max_stride;
> > +
> > +       /* We don't want to deal with remapping with cursors */
> > +       if (plane->id == PLANE_CURSOR)
> > +               return false;
> > +
> > +       /* No fence for the remapped vma */
> 
> Should work now (with a minor tweak to plane_can_fence), right?

Gen2 would probably need a bit of extra considerationa due to
the tile size vs. page size thing. I guess gen3 might work as is.

But as long as we're limited by the current max fb size I
suppose there isn't much point in remapping.

> 
> > +       if (INTEL_GEN(dev_priv) < 4)
> > +               return false;
> > +
> > +       /* New CCS hash mode makes remapping impossible */
> > +       if (is_ccs_modifier(fb->modifier))
> > +               return false;
> > +
> > +       /* FIXME other color planes? */
> > +       stride = intel_fb_pitch(fb, 0, rotation);
> > +       max_stride = plane->max_stride(plane, fb->format->format,
> > +                                      fb->modifier, rotation);
> > +
> > +       return stride > max_stride;
> > +}
> > +
> >  static int
> >  intel_fill_fb_info(struct drm_i915_private *dev_priv,
> >                    struct drm_framebuffer *fb)
> > @@ -2676,6 +2741,182 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv,
> >         return 0;
> >  }
> >  
> > +static void
> > +intel_plane_remap_gtt(struct intel_plane_state *plane_state)
> > +{
> > +       struct drm_i915_private *dev_priv =
> > +               to_i915(plane_state->base.plane->dev);
> > +       struct drm_framebuffer *fb = plane_state->base.fb;
> > +       struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
> > +       struct intel_rotation_info *info = &plane_state->view.rotated;
> > +       unsigned int rotation = plane_state->base.rotation;
> > +       int i, num_planes = fb->format->num_planes;
> > +       unsigned int tile_size = intel_tile_size(dev_priv);
> > +       unsigned int tile_width, tile_height;
> > +       unsigned int aligned_x, aligned_y;
> > +       unsigned int aligned_w, aligned_h;
> > +       unsigned int src_x, src_y;
> > +       unsigned int src_w, src_h;
> > +       unsigned int x, y;
> > +       u32 gtt_offset = 0;
> > +
> > +       memset(&plane_state->view, 0, sizeof(plane_state->view));
> > +       plane_state->view.type = drm_rotation_90_or_270(rotation) ?
> > +               I915_GGTT_VIEW_ROTATED : I915_GGTT_VIEW_REMAPPED;
> > +
> > +       src_x = plane_state->base.src.x1 >> 16;
> > +       src_y = plane_state->base.src.y1 >> 16;
> > +       src_w = drm_rect_width(&plane_state->base.src) >> 16;
> > +       src_h = drm_rect_height(&plane_state->base.src) >> 16;
> > +
> > +       WARN_ON(is_ccs_modifier(fb->modifier));
> > +
> > +       /* Align our viewport start to tile boundary */
> > +       intel_tile_dims(fb, 0, &tile_width, &tile_height);
> > +
> > +       x = src_x & (tile_width - 1);
> > +       y = src_y & (tile_height - 1);
> > +
> > +       aligned_x = src_x - x;
> > +       aligned_y = src_y - y;
> > +
> > +       aligned_w = x + src_w;
> > +       aligned_h = y + src_h;
> > +
> > +       /* Make src coordinates relative to the aligned viewport */
> > +       drm_rect_translate(&plane_state->base.src,
> > +                          -(aligned_x << 16), -(aligned_y << 16));
> > +
> > +       /* Rotate src coordinates to match rotated GTT view */
> > +       if (drm_rotation_90_or_270(rotation))
> > +               drm_rect_rotate(&plane_state->base.src,
> > +                               aligned_w << 16, aligned_h << 16,
> > +                               DRM_MODE_ROTATE_270);
> > +
> > +       for (i = 0; i < num_planes; i++) {
> > +               unsigned int hsub = i ? fb->format->hsub : 1;
> > +               unsigned int vsub = i ? fb->format->vsub : 1;
> > +               unsigned int cpp = fb->format->cpp[i];
> > +               unsigned int width, height;
> > +               unsigned int pitch_tiles;
> > +               unsigned int x, y;
> > +               u32 offset;
> > +
> > +               intel_tile_dims(fb, i, &tile_width, &tile_height);
> > +
> > +               x = aligned_x / hsub;
> > +               y = aligned_y / vsub;
> > +               width = aligned_w / hsub;
> 
> aligned_w here seems to be just x2.
> 
> Did I miss aligned_w = ALIGN(aligned_w, tile_width) - aligned_x?

No. I guess it should be called width_from_aligned_x or something along
those lines.

> 
> > +               height = aligned_h / vsub;
> > +
> > +               /*
> > +                * First pixel of the aligned src viewport
> > +                * from the start of the normal gtt mapping.
> > +                */
> > +               x += intel_fb->normal[i].x;
> > +               y += intel_fb->normal[i].y;
> > +
> > +               offset = intel_compute_aligned_offset(dev_priv, &x, &y,
> > +                                                     fb, i, fb->pitches[i],
> > +                                                     DRM_MODE_ROTATE_0, tile_size);
> > +               offset /= tile_size;
> > +
> > +               info->plane[i].offset = offset;
> > +               info->plane[i].stride = DIV_ROUND_UP(fb->pitches[i],
> > +                                                    tile_width * cpp);
> > +               info->plane[i].width = DIV_ROUND_UP(x + width, tile_width);
> > +               info->plane[i].height = DIV_ROUND_UP(y + height, tile_height);
> 
> I thought .width here would be in pages? Ok tile_width != fence_stride
> and does produce pages just fine.
> 
> And shouldn't width here be adjusted for x? Similarly for height?

Hmm. The surf register will point to offset (well, the equivalent place
in the new vma), and the plane starts to scan out x pixels from that,
so the vma must be at least x+width pixels wide. Still seems to make
sense to me at least :)

Actually thinking about this some more, I should be able to just throw
out the aligned_x/y stuff. intel_compute_aligned_offset() will give us
what we need anyway. I originally added that extra alignement step for
CCS (to align to a whole CCS tile), but since remapping with CCS
doesn't work anyway there's no point in doing this extra work.

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v4 3/8] drm/i915: Add a new "remapped" gtt_view
  2018-10-23 16:02   ` [PATCH v4 " Ville Syrjala
  2018-10-23 18:56     ` Chris Wilson
@ 2018-10-26  9:19     ` Tvrtko Ursulin
  2018-10-26 12:43       ` Ville Syrjälä
  1 sibling, 1 reply; 62+ messages in thread
From: Tvrtko Ursulin @ 2018-10-26  9:19 UTC (permalink / raw)
  To: Ville Syrjala, intel-gfx


On 23/10/2018 17:02, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> To overcome display engine stride limits we'll want to remap the
> pages in the GTT. To that end we need a new gtt_view type which
> is just like the "rotated" type except not rotated.
> 
> v2: Use intel_remapped_plane_info base type
>      s/unused/unused_mbz/ (Chris)
>      Separate BUILD_BUG_ON()s (Chris)
>      Use I915_GTT_PAGE_SIZE (Chris)
> v3: Use i915_gem_object_get_dma_address() (Chris)
>      Trim the sg (Tvrtko)
> 
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>   drivers/gpu/drm/i915/i915_debugfs.c       | 12 ++++
>   drivers/gpu/drm/i915/i915_gem_gtt.c       | 74 +++++++++++++++++++++++
>   drivers/gpu/drm/i915/i915_gem_gtt.h       | 25 ++++++--
>   drivers/gpu/drm/i915/i915_vma.c           |  6 +-
>   drivers/gpu/drm/i915/i915_vma.h           |  3 +
>   drivers/gpu/drm/i915/intel_display.c      | 11 ++++
>   drivers/gpu/drm/i915/intel_drv.h          |  1 +
>   drivers/gpu/drm/i915/selftests/i915_vma.c |  6 +-
>   8 files changed, 130 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 5b37d5f8e132..ce019126304d 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -196,6 +196,18 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
>   					   vma->ggtt_view.rotated.plane[1].offset);
>   				break;
>   
> +			case I915_GGTT_VIEW_REMAPPED:
> +				seq_printf(m, ", remapped [(%ux%u, stride=%u, offset=%u), (%ux%u, stride=%u, offset=%u)]",
> +					   vma->ggtt_view.remapped.plane[0].width,
> +					   vma->ggtt_view.remapped.plane[0].height,
> +					   vma->ggtt_view.remapped.plane[0].stride,
> +					   vma->ggtt_view.remapped.plane[0].offset,
> +					   vma->ggtt_view.remapped.plane[1].width,
> +					   vma->ggtt_view.remapped.plane[1].height,
> +					   vma->ggtt_view.remapped.plane[1].stride,
> +					   vma->ggtt_view.remapped.plane[1].offset);
> +				break;
> +
>   			default:
>   				MISSING_CASE(vma->ggtt_view.type);
>   				break;
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 98d9a1eb1ed2..d0e50b584ebd 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -3705,6 +3705,75 @@ intel_rotate_pages(struct intel_rotation_info *rot_info,
>   	return ERR_PTR(ret);
>   }
>   
> +static struct scatterlist *
> +remap_pages(struct drm_i915_gem_object *obj, unsigned int offset,
> +	    unsigned int width, unsigned int height,
> +	    unsigned int stride,
> +	    struct sg_table *st, struct scatterlist *sg)
> +{
> +	unsigned int column, row;
> +
> +	for (row = 0; row < height; row++) {
> +		for (column = 0; column < width; column++) {
> +			st->nents++;
> +			/* We don't need the pages, but need to initialize
> +			 * the entries so the sg list can be happily traversed.
> +			 * The only thing we need are DMA addresses.
> +			 */
> +			sg_set_page(sg, NULL, I915_GTT_PAGE_SIZE, 0);
> +			sg_dma_address(sg) =
> +				i915_gem_object_get_dma_address(obj, offset + column);
> +			sg_dma_len(sg) = I915_GTT_PAGE_SIZE;

Sg trim will do nothing since the nents is equal to num pages. To 
benefit from it, you would need to look for consecutive DMA addresses 
and "append" to the existing sg entry in those cases. Contrary to the 
rotated remap, this one should actually benefit a lot from it. (For this 
reason rotated remap does not bother to try it - it would be some luck 
to find consecutive pages after rotation.)

Regards,

Tvrtko

> +			sg = sg_next(sg);
> +		}
> +		offset += stride;
> +	}
> +
> +	return sg;
> +}
> +
> +static noinline struct sg_table *
> +intel_remap_pages(struct intel_remapped_info *rem_info,
> +		  struct drm_i915_gem_object *obj)
> +{
> +	unsigned int size = intel_remapped_info_size(rem_info);
> +	struct sg_table *st;
> +	struct scatterlist *sg;
> +	int ret = -ENOMEM;
> +	int i;
> +
> +	/* Allocate target SG list. */
> +	st = kmalloc(sizeof(*st), GFP_KERNEL);
> +	if (!st)
> +		goto err_st_alloc;
> +
> +	ret = sg_alloc_table(st, size, GFP_KERNEL);
> +	if (ret)
> +		goto err_sg_alloc;
> +
> +	st->nents = 0;
> +	sg = st->sgl;
> +
> +	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
> +		sg = remap_pages(obj, rem_info->plane[i].offset,
> +				 rem_info->plane[i].width, rem_info->plane[i].height,
> +				 rem_info->plane[i].stride, st, sg);
> +	}
> +
> +	i915_sg_trim(st);
> +
> +	return st;
> +
> +err_sg_alloc:
> +	kfree(st);
> +err_st_alloc:
> +
> +	DRM_DEBUG_DRIVER("Failed to create remapped mapping for object size %zu! (%ux%u tiles, %u pages)\n",
> +			 obj->base.size, rem_info->plane[0].width, rem_info->plane[0].height, size);
> +
> +	return ERR_PTR(ret);
> +}
> +
>   static noinline struct sg_table *
>   intel_partial_pages(const struct i915_ggtt_view *view,
>   		    struct drm_i915_gem_object *obj)
> @@ -3783,6 +3852,11 @@ i915_get_ggtt_vma_pages(struct i915_vma *vma)
>   			intel_rotate_pages(&vma->ggtt_view.rotated, vma->obj);
>   		break;
>   
> +	case I915_GGTT_VIEW_REMAPPED:
> +		vma->pages =
> +			intel_remap_pages(&vma->ggtt_view.remapped, vma->obj);
> +		break;
> +
>   	case I915_GGTT_VIEW_PARTIAL:
>   		vma->pages = intel_partial_pages(&vma->ggtt_view, vma->obj);
>   		break;
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
> index 7e2af5f4f39b..69a22f57e6ca 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.h
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
> @@ -160,11 +160,18 @@ typedef u64 gen8_ppgtt_pml4e_t;
>   
>   struct sg_table;
>   
> +struct intel_remapped_plane_info {
> +	/* in gtt pages */
> +	unsigned int width, height, stride, offset;
> +} __packed;
> +
> +struct intel_remapped_info {
> +	struct intel_remapped_plane_info plane[2];
> +	unsigned int unused_mbz;
> +} __packed;
> +
>   struct intel_rotation_info {
> -	struct intel_rotation_plane_info {
> -		/* tiles */
> -		unsigned int width, height, stride, offset;
> -	} plane[2];
> +	struct intel_remapped_plane_info plane[2];
>   } __packed;
>   
>   struct intel_partial_info {
> @@ -176,12 +183,20 @@ enum i915_ggtt_view_type {
>   	I915_GGTT_VIEW_NORMAL = 0,
>   	I915_GGTT_VIEW_ROTATED = sizeof(struct intel_rotation_info),
>   	I915_GGTT_VIEW_PARTIAL = sizeof(struct intel_partial_info),
> +	I915_GGTT_VIEW_REMAPPED = sizeof(struct intel_remapped_info),
>   };
>   
>   static inline void assert_i915_gem_gtt_types(void)
>   {
>   	BUILD_BUG_ON(sizeof(struct intel_rotation_info) != 8*sizeof(unsigned int));
>   	BUILD_BUG_ON(sizeof(struct intel_partial_info) != sizeof(u64) + sizeof(unsigned int));
> +	BUILD_BUG_ON(sizeof(struct intel_remapped_info) != 9*sizeof(unsigned int));
> +
> +	/* Check that rotation/remapped shares offsets for simplicity */
> +	BUILD_BUG_ON(offsetof(struct intel_remapped_info, plane[0]) !=
> +		     offsetof(struct intel_rotation_info, plane[0]));
> +	BUILD_BUG_ON(offsetofend(struct intel_remapped_info, plane[1]) !=
> +		     offsetofend(struct intel_rotation_info, plane[1]));
>   
>   	/* As we encode the size of each branch inside the union into its type,
>   	 * we have to be careful that each branch has a unique size.
> @@ -190,6 +205,7 @@ static inline void assert_i915_gem_gtt_types(void)
>   	case I915_GGTT_VIEW_NORMAL:
>   	case I915_GGTT_VIEW_PARTIAL:
>   	case I915_GGTT_VIEW_ROTATED:
> +	case I915_GGTT_VIEW_REMAPPED:
>   		/* gcc complains if these are identical cases */
>   		break;
>   	}
> @@ -201,6 +217,7 @@ struct i915_ggtt_view {
>   		/* Members need to contain no holes/padding */
>   		struct intel_partial_info partial;
>   		struct intel_rotation_info rotated;
> +		struct intel_remapped_info remapped;
>   	};
>   };
>   
> diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
> index 82652c3d1bed..2070e44eaa03 100644
> --- a/drivers/gpu/drm/i915/i915_vma.c
> +++ b/drivers/gpu/drm/i915/i915_vma.c
> @@ -164,6 +164,9 @@ vma_create(struct drm_i915_gem_object *obj,
>   		} else if (view->type == I915_GGTT_VIEW_ROTATED) {
>   			vma->size = intel_rotation_info_size(&view->rotated);
>   			vma->size <<= PAGE_SHIFT;
> +		} else if (view->type == I915_GGTT_VIEW_REMAPPED) {
> +			vma->size = intel_remapped_info_size(&view->remapped);
> +			vma->size <<= PAGE_SHIFT;
>   		}
>   	}
>   
> @@ -464,7 +467,8 @@ void __i915_vma_set_map_and_fenceable(struct i915_vma *vma)
>   	 * Explicitly disable for rotated VMA since the display does not
>   	 * need the fence and the VMA is not accessible to other users.
>   	 */
> -	if (vma->ggtt_view.type == I915_GGTT_VIEW_ROTATED)
> +	if (vma->ggtt_view.type == I915_GGTT_VIEW_ROTATED ||
> +	    vma->ggtt_view.type == I915_GGTT_VIEW_REMAPPED)
>   		return;
>   
>   	fenceable = (vma->node.size >= vma->fence_size &&
> diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
> index 4f7c1c7599f4..64cf029c028a 100644
> --- a/drivers/gpu/drm/i915/i915_vma.h
> +++ b/drivers/gpu/drm/i915/i915_vma.h
> @@ -265,8 +265,11 @@ i915_vma_compare(struct i915_vma *vma,
>   	 */
>   	BUILD_BUG_ON(I915_GGTT_VIEW_NORMAL >= I915_GGTT_VIEW_PARTIAL);
>   	BUILD_BUG_ON(I915_GGTT_VIEW_PARTIAL >= I915_GGTT_VIEW_ROTATED);
> +	BUILD_BUG_ON(I915_GGTT_VIEW_ROTATED >= I915_GGTT_VIEW_REMAPPED);
>   	BUILD_BUG_ON(offsetof(typeof(*view), rotated) !=
>   		     offsetof(typeof(*view), partial));
> +	BUILD_BUG_ON(offsetof(typeof(*view), rotated) !=
> +		     offsetof(typeof(*view), remapped));
>   	return memcmp(&vma->ggtt_view.partial, &view->partial, view->type);
>   }
>   
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 8a0b477a69d3..41f7e0795b14 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -1957,6 +1957,17 @@ unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info
>   	return size;
>   }
>   
> +unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info)
> +{
> +	unsigned int size = 0;
> +	int i;
> +
> +	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++)
> +		size += rem_info->plane[i].width * rem_info->plane[i].height;
> +
> +	return size;
> +}
> +
>   static void
>   intel_fill_fb_ggtt_view(struct i915_ggtt_view *view,
>   			const struct drm_framebuffer *fb,
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 0e9a926fca04..6993eff5dfaf 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1523,6 +1523,7 @@ unsigned int intel_fb_xy_to_linear(int x, int y,
>   void intel_add_fb_offsets(int *x, int *y,
>   			  const struct intel_plane_state *state, int plane);
>   unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info);
> +unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info);
>   bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv);
>   void intel_mark_busy(struct drm_i915_private *dev_priv);
>   void intel_mark_idle(struct drm_i915_private *dev_priv);
> diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c
> index ffa74290e054..4fc49c27f13c 100644
> --- a/drivers/gpu/drm/i915/selftests/i915_vma.c
> +++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
> @@ -395,8 +395,8 @@ assert_rotated(struct drm_i915_gem_object *obj,
>   	return sg;
>   }
>   
> -static unsigned int rotated_size(const struct intel_rotation_plane_info *a,
> -				 const struct intel_rotation_plane_info *b)
> +static unsigned int rotated_size(const struct intel_remapped_plane_info *a,
> +				 const struct intel_remapped_plane_info *b)
>   {
>   	return a->width * a->height + b->width * b->height;
>   }
> @@ -406,7 +406,7 @@ static int igt_vma_rotate(void *arg)
>   	struct drm_i915_private *i915 = arg;
>   	struct i915_address_space *vm = &i915->ggtt.vm;
>   	struct drm_i915_gem_object *obj;
> -	const struct intel_rotation_plane_info planes[] = {
> +	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 },
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v4 3/8] drm/i915: Add a new "remapped" gtt_view
  2018-10-26  9:19     ` Tvrtko Ursulin
@ 2018-10-26 12:43       ` Ville Syrjälä
  2018-10-26 12:48         ` Tvrtko Ursulin
  0 siblings, 1 reply; 62+ messages in thread
From: Ville Syrjälä @ 2018-10-26 12:43 UTC (permalink / raw)
  To: Tvrtko Ursulin; +Cc: intel-gfx

On Fri, Oct 26, 2018 at 10:19:25AM +0100, Tvrtko Ursulin wrote:
> 
> On 23/10/2018 17:02, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > To overcome display engine stride limits we'll want to remap the
> > pages in the GTT. To that end we need a new gtt_view type which
> > is just like the "rotated" type except not rotated.
> > 
> > v2: Use intel_remapped_plane_info base type
> >      s/unused/unused_mbz/ (Chris)
> >      Separate BUILD_BUG_ON()s (Chris)
> >      Use I915_GTT_PAGE_SIZE (Chris)
> > v3: Use i915_gem_object_get_dma_address() (Chris)
> >      Trim the sg (Tvrtko)
> > 
> > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> > Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >   drivers/gpu/drm/i915/i915_debugfs.c       | 12 ++++
> >   drivers/gpu/drm/i915/i915_gem_gtt.c       | 74 +++++++++++++++++++++++
> >   drivers/gpu/drm/i915/i915_gem_gtt.h       | 25 ++++++--
> >   drivers/gpu/drm/i915/i915_vma.c           |  6 +-
> >   drivers/gpu/drm/i915/i915_vma.h           |  3 +
> >   drivers/gpu/drm/i915/intel_display.c      | 11 ++++
> >   drivers/gpu/drm/i915/intel_drv.h          |  1 +
> >   drivers/gpu/drm/i915/selftests/i915_vma.c |  6 +-
> >   8 files changed, 130 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> > index 5b37d5f8e132..ce019126304d 100644
> > --- a/drivers/gpu/drm/i915/i915_debugfs.c
> > +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> > @@ -196,6 +196,18 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
> >   					   vma->ggtt_view.rotated.plane[1].offset);
> >   				break;
> >   
> > +			case I915_GGTT_VIEW_REMAPPED:
> > +				seq_printf(m, ", remapped [(%ux%u, stride=%u, offset=%u), (%ux%u, stride=%u, offset=%u)]",
> > +					   vma->ggtt_view.remapped.plane[0].width,
> > +					   vma->ggtt_view.remapped.plane[0].height,
> > +					   vma->ggtt_view.remapped.plane[0].stride,
> > +					   vma->ggtt_view.remapped.plane[0].offset,
> > +					   vma->ggtt_view.remapped.plane[1].width,
> > +					   vma->ggtt_view.remapped.plane[1].height,
> > +					   vma->ggtt_view.remapped.plane[1].stride,
> > +					   vma->ggtt_view.remapped.plane[1].offset);
> > +				break;
> > +
> >   			default:
> >   				MISSING_CASE(vma->ggtt_view.type);
> >   				break;
> > diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> > index 98d9a1eb1ed2..d0e50b584ebd 100644
> > --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> > +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> > @@ -3705,6 +3705,75 @@ intel_rotate_pages(struct intel_rotation_info *rot_info,
> >   	return ERR_PTR(ret);
> >   }
> >   
> > +static struct scatterlist *
> > +remap_pages(struct drm_i915_gem_object *obj, unsigned int offset,
> > +	    unsigned int width, unsigned int height,
> > +	    unsigned int stride,
> > +	    struct sg_table *st, struct scatterlist *sg)
> > +{
> > +	unsigned int column, row;
> > +
> > +	for (row = 0; row < height; row++) {
> > +		for (column = 0; column < width; column++) {
> > +			st->nents++;
> > +			/* We don't need the pages, but need to initialize
> > +			 * the entries so the sg list can be happily traversed.
> > +			 * The only thing we need are DMA addresses.
> > +			 */
> > +			sg_set_page(sg, NULL, I915_GTT_PAGE_SIZE, 0);
> > +			sg_dma_address(sg) =
> > +				i915_gem_object_get_dma_address(obj, offset + column);
> > +			sg_dma_len(sg) = I915_GTT_PAGE_SIZE;
> 
> Sg trim will do nothing since the nents is equal to num pages. To 
> benefit from it, you would need to look for consecutive DMA addresses 
> and "append" to the existing sg entry in those cases.

Hmm. I thought that is what sg_trim() does. I guess not.

> Contrary to the 
> rotated remap, this one should actually benefit a lot from it. (For this 
> reason rotated remap does not bother to try it - it would be some luck 
> to find consecutive pages after rotation.)
> 
> Regards,
> 
> Tvrtko
> 
> > +			sg = sg_next(sg);
> > +		}
> > +		offset += stride;
> > +	}
> > +
> > +	return sg;
> > +}
> > +
> > +static noinline struct sg_table *
> > +intel_remap_pages(struct intel_remapped_info *rem_info,
> > +		  struct drm_i915_gem_object *obj)
> > +{
> > +	unsigned int size = intel_remapped_info_size(rem_info);
> > +	struct sg_table *st;
> > +	struct scatterlist *sg;
> > +	int ret = -ENOMEM;
> > +	int i;
> > +
> > +	/* Allocate target SG list. */
> > +	st = kmalloc(sizeof(*st), GFP_KERNEL);
> > +	if (!st)
> > +		goto err_st_alloc;
> > +
> > +	ret = sg_alloc_table(st, size, GFP_KERNEL);
> > +	if (ret)
> > +		goto err_sg_alloc;
> > +
> > +	st->nents = 0;
> > +	sg = st->sgl;
> > +
> > +	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
> > +		sg = remap_pages(obj, rem_info->plane[i].offset,
> > +				 rem_info->plane[i].width, rem_info->plane[i].height,
> > +				 rem_info->plane[i].stride, st, sg);
> > +	}
> > +
> > +	i915_sg_trim(st);
> > +
> > +	return st;
> > +
> > +err_sg_alloc:
> > +	kfree(st);
> > +err_st_alloc:
> > +
> > +	DRM_DEBUG_DRIVER("Failed to create remapped mapping for object size %zu! (%ux%u tiles, %u pages)\n",
> > +			 obj->base.size, rem_info->plane[0].width, rem_info->plane[0].height, size);
> > +
> > +	return ERR_PTR(ret);
> > +}
> > +
> >   static noinline struct sg_table *
> >   intel_partial_pages(const struct i915_ggtt_view *view,
> >   		    struct drm_i915_gem_object *obj)
> > @@ -3783,6 +3852,11 @@ i915_get_ggtt_vma_pages(struct i915_vma *vma)
> >   			intel_rotate_pages(&vma->ggtt_view.rotated, vma->obj);
> >   		break;
> >   
> > +	case I915_GGTT_VIEW_REMAPPED:
> > +		vma->pages =
> > +			intel_remap_pages(&vma->ggtt_view.remapped, vma->obj);
> > +		break;
> > +
> >   	case I915_GGTT_VIEW_PARTIAL:
> >   		vma->pages = intel_partial_pages(&vma->ggtt_view, vma->obj);
> >   		break;
> > diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
> > index 7e2af5f4f39b..69a22f57e6ca 100644
> > --- a/drivers/gpu/drm/i915/i915_gem_gtt.h
> > +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
> > @@ -160,11 +160,18 @@ typedef u64 gen8_ppgtt_pml4e_t;
> >   
> >   struct sg_table;
> >   
> > +struct intel_remapped_plane_info {
> > +	/* in gtt pages */
> > +	unsigned int width, height, stride, offset;
> > +} __packed;
> > +
> > +struct intel_remapped_info {
> > +	struct intel_remapped_plane_info plane[2];
> > +	unsigned int unused_mbz;
> > +} __packed;
> > +
> >   struct intel_rotation_info {
> > -	struct intel_rotation_plane_info {
> > -		/* tiles */
> > -		unsigned int width, height, stride, offset;
> > -	} plane[2];
> > +	struct intel_remapped_plane_info plane[2];
> >   } __packed;
> >   
> >   struct intel_partial_info {
> > @@ -176,12 +183,20 @@ enum i915_ggtt_view_type {
> >   	I915_GGTT_VIEW_NORMAL = 0,
> >   	I915_GGTT_VIEW_ROTATED = sizeof(struct intel_rotation_info),
> >   	I915_GGTT_VIEW_PARTIAL = sizeof(struct intel_partial_info),
> > +	I915_GGTT_VIEW_REMAPPED = sizeof(struct intel_remapped_info),
> >   };
> >   
> >   static inline void assert_i915_gem_gtt_types(void)
> >   {
> >   	BUILD_BUG_ON(sizeof(struct intel_rotation_info) != 8*sizeof(unsigned int));
> >   	BUILD_BUG_ON(sizeof(struct intel_partial_info) != sizeof(u64) + sizeof(unsigned int));
> > +	BUILD_BUG_ON(sizeof(struct intel_remapped_info) != 9*sizeof(unsigned int));
> > +
> > +	/* Check that rotation/remapped shares offsets for simplicity */
> > +	BUILD_BUG_ON(offsetof(struct intel_remapped_info, plane[0]) !=
> > +		     offsetof(struct intel_rotation_info, plane[0]));
> > +	BUILD_BUG_ON(offsetofend(struct intel_remapped_info, plane[1]) !=
> > +		     offsetofend(struct intel_rotation_info, plane[1]));
> >   
> >   	/* As we encode the size of each branch inside the union into its type,
> >   	 * we have to be careful that each branch has a unique size.
> > @@ -190,6 +205,7 @@ static inline void assert_i915_gem_gtt_types(void)
> >   	case I915_GGTT_VIEW_NORMAL:
> >   	case I915_GGTT_VIEW_PARTIAL:
> >   	case I915_GGTT_VIEW_ROTATED:
> > +	case I915_GGTT_VIEW_REMAPPED:
> >   		/* gcc complains if these are identical cases */
> >   		break;
> >   	}
> > @@ -201,6 +217,7 @@ struct i915_ggtt_view {
> >   		/* Members need to contain no holes/padding */
> >   		struct intel_partial_info partial;
> >   		struct intel_rotation_info rotated;
> > +		struct intel_remapped_info remapped;
> >   	};
> >   };
> >   
> > diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
> > index 82652c3d1bed..2070e44eaa03 100644
> > --- a/drivers/gpu/drm/i915/i915_vma.c
> > +++ b/drivers/gpu/drm/i915/i915_vma.c
> > @@ -164,6 +164,9 @@ vma_create(struct drm_i915_gem_object *obj,
> >   		} else if (view->type == I915_GGTT_VIEW_ROTATED) {
> >   			vma->size = intel_rotation_info_size(&view->rotated);
> >   			vma->size <<= PAGE_SHIFT;
> > +		} else if (view->type == I915_GGTT_VIEW_REMAPPED) {
> > +			vma->size = intel_remapped_info_size(&view->remapped);
> > +			vma->size <<= PAGE_SHIFT;
> >   		}
> >   	}
> >   
> > @@ -464,7 +467,8 @@ void __i915_vma_set_map_and_fenceable(struct i915_vma *vma)
> >   	 * Explicitly disable for rotated VMA since the display does not
> >   	 * need the fence and the VMA is not accessible to other users.
> >   	 */
> > -	if (vma->ggtt_view.type == I915_GGTT_VIEW_ROTATED)
> > +	if (vma->ggtt_view.type == I915_GGTT_VIEW_ROTATED ||
> > +	    vma->ggtt_view.type == I915_GGTT_VIEW_REMAPPED)
> >   		return;
> >   
> >   	fenceable = (vma->node.size >= vma->fence_size &&
> > diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
> > index 4f7c1c7599f4..64cf029c028a 100644
> > --- a/drivers/gpu/drm/i915/i915_vma.h
> > +++ b/drivers/gpu/drm/i915/i915_vma.h
> > @@ -265,8 +265,11 @@ i915_vma_compare(struct i915_vma *vma,
> >   	 */
> >   	BUILD_BUG_ON(I915_GGTT_VIEW_NORMAL >= I915_GGTT_VIEW_PARTIAL);
> >   	BUILD_BUG_ON(I915_GGTT_VIEW_PARTIAL >= I915_GGTT_VIEW_ROTATED);
> > +	BUILD_BUG_ON(I915_GGTT_VIEW_ROTATED >= I915_GGTT_VIEW_REMAPPED);
> >   	BUILD_BUG_ON(offsetof(typeof(*view), rotated) !=
> >   		     offsetof(typeof(*view), partial));
> > +	BUILD_BUG_ON(offsetof(typeof(*view), rotated) !=
> > +		     offsetof(typeof(*view), remapped));
> >   	return memcmp(&vma->ggtt_view.partial, &view->partial, view->type);
> >   }
> >   
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 8a0b477a69d3..41f7e0795b14 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -1957,6 +1957,17 @@ unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info
> >   	return size;
> >   }
> >   
> > +unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info)
> > +{
> > +	unsigned int size = 0;
> > +	int i;
> > +
> > +	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++)
> > +		size += rem_info->plane[i].width * rem_info->plane[i].height;
> > +
> > +	return size;
> > +}
> > +
> >   static void
> >   intel_fill_fb_ggtt_view(struct i915_ggtt_view *view,
> >   			const struct drm_framebuffer *fb,
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index 0e9a926fca04..6993eff5dfaf 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -1523,6 +1523,7 @@ unsigned int intel_fb_xy_to_linear(int x, int y,
> >   void intel_add_fb_offsets(int *x, int *y,
> >   			  const struct intel_plane_state *state, int plane);
> >   unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info);
> > +unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info);
> >   bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv);
> >   void intel_mark_busy(struct drm_i915_private *dev_priv);
> >   void intel_mark_idle(struct drm_i915_private *dev_priv);
> > diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c
> > index ffa74290e054..4fc49c27f13c 100644
> > --- a/drivers/gpu/drm/i915/selftests/i915_vma.c
> > +++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
> > @@ -395,8 +395,8 @@ assert_rotated(struct drm_i915_gem_object *obj,
> >   	return sg;
> >   }
> >   
> > -static unsigned int rotated_size(const struct intel_rotation_plane_info *a,
> > -				 const struct intel_rotation_plane_info *b)
> > +static unsigned int rotated_size(const struct intel_remapped_plane_info *a,
> > +				 const struct intel_remapped_plane_info *b)
> >   {
> >   	return a->width * a->height + b->width * b->height;
> >   }
> > @@ -406,7 +406,7 @@ static int igt_vma_rotate(void *arg)
> >   	struct drm_i915_private *i915 = arg;
> >   	struct i915_address_space *vm = &i915->ggtt.vm;
> >   	struct drm_i915_gem_object *obj;
> > -	const struct intel_rotation_plane_info planes[] = {
> > +	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 },
> > 

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v4 3/8] drm/i915: Add a new "remapped" gtt_view
  2018-10-26 12:43       ` Ville Syrjälä
@ 2018-10-26 12:48         ` Tvrtko Ursulin
  0 siblings, 0 replies; 62+ messages in thread
From: Tvrtko Ursulin @ 2018-10-26 12:48 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx


On 26/10/2018 13:43, Ville Syrjälä wrote:
> On Fri, Oct 26, 2018 at 10:19:25AM +0100, Tvrtko Ursulin wrote:
>>
>> On 23/10/2018 17:02, Ville Syrjala wrote:
>>> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
>>>
>>> To overcome display engine stride limits we'll want to remap the
>>> pages in the GTT. To that end we need a new gtt_view type which
>>> is just like the "rotated" type except not rotated.
>>>
>>> v2: Use intel_remapped_plane_info base type
>>>       s/unused/unused_mbz/ (Chris)
>>>       Separate BUILD_BUG_ON()s (Chris)
>>>       Use I915_GTT_PAGE_SIZE (Chris)
>>> v3: Use i915_gem_object_get_dma_address() (Chris)
>>>       Trim the sg (Tvrtko)
>>>
>>> Cc: Chris Wilson <chris@chris-wilson.co.uk>
>>> Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
>>> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
>>> ---
>>>    drivers/gpu/drm/i915/i915_debugfs.c       | 12 ++++
>>>    drivers/gpu/drm/i915/i915_gem_gtt.c       | 74 +++++++++++++++++++++++
>>>    drivers/gpu/drm/i915/i915_gem_gtt.h       | 25 ++++++--
>>>    drivers/gpu/drm/i915/i915_vma.c           |  6 +-
>>>    drivers/gpu/drm/i915/i915_vma.h           |  3 +
>>>    drivers/gpu/drm/i915/intel_display.c      | 11 ++++
>>>    drivers/gpu/drm/i915/intel_drv.h          |  1 +
>>>    drivers/gpu/drm/i915/selftests/i915_vma.c |  6 +-
>>>    8 files changed, 130 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
>>> index 5b37d5f8e132..ce019126304d 100644
>>> --- a/drivers/gpu/drm/i915/i915_debugfs.c
>>> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
>>> @@ -196,6 +196,18 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
>>>    					   vma->ggtt_view.rotated.plane[1].offset);
>>>    				break;
>>>    
>>> +			case I915_GGTT_VIEW_REMAPPED:
>>> +				seq_printf(m, ", remapped [(%ux%u, stride=%u, offset=%u), (%ux%u, stride=%u, offset=%u)]",
>>> +					   vma->ggtt_view.remapped.plane[0].width,
>>> +					   vma->ggtt_view.remapped.plane[0].height,
>>> +					   vma->ggtt_view.remapped.plane[0].stride,
>>> +					   vma->ggtt_view.remapped.plane[0].offset,
>>> +					   vma->ggtt_view.remapped.plane[1].width,
>>> +					   vma->ggtt_view.remapped.plane[1].height,
>>> +					   vma->ggtt_view.remapped.plane[1].stride,
>>> +					   vma->ggtt_view.remapped.plane[1].offset);
>>> +				break;
>>> +
>>>    			default:
>>>    				MISSING_CASE(vma->ggtt_view.type);
>>>    				break;
>>> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
>>> index 98d9a1eb1ed2..d0e50b584ebd 100644
>>> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
>>> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
>>> @@ -3705,6 +3705,75 @@ intel_rotate_pages(struct intel_rotation_info *rot_info,
>>>    	return ERR_PTR(ret);
>>>    }
>>>    
>>> +static struct scatterlist *
>>> +remap_pages(struct drm_i915_gem_object *obj, unsigned int offset,
>>> +	    unsigned int width, unsigned int height,
>>> +	    unsigned int stride,
>>> +	    struct sg_table *st, struct scatterlist *sg)
>>> +{
>>> +	unsigned int column, row;
>>> +
>>> +	for (row = 0; row < height; row++) {
>>> +		for (column = 0; column < width; column++) {
>>> +			st->nents++;
>>> +			/* We don't need the pages, but need to initialize
>>> +			 * the entries so the sg list can be happily traversed.
>>> +			 * The only thing we need are DMA addresses.
>>> +			 */
>>> +			sg_set_page(sg, NULL, I915_GTT_PAGE_SIZE, 0);
>>> +			sg_dma_address(sg) =
>>> +				i915_gem_object_get_dma_address(obj, offset + column);
>>> +			sg_dma_len(sg) = I915_GTT_PAGE_SIZE;
>>
>> Sg trim will do nothing since the nents is equal to num pages. To
>> benefit from it, you would need to look for consecutive DMA addresses
>> and "append" to the existing sg entry in those cases.
> 
> Hmm. I thought that is what sg_trim() does. I guess not.

Ah.. no, it just discards the unused sg entries, the difference from 
sg->nents to sg->orig_nents.

What you thought it does could be called i915_sg_coalesce, optimize, or 
something. Maybe it would make sense to add this kind of helper if there 
are sufficient users. It should be doable in place without too much 
trouble I think.

Regards,

Tvrtko

>> Contrary to the
>> rotated remap, this one should actually benefit a lot from it. (For this
>> reason rotated remap does not bother to try it - it would be some luck
>> to find consecutive pages after rotation.)
>>
>> Regards,
>>
>> Tvrtko
>>
>>> +			sg = sg_next(sg);
>>> +		}
>>> +		offset += stride;
>>> +	}
>>> +
>>> +	return sg;
>>> +}
>>> +
>>> +static noinline struct sg_table *
>>> +intel_remap_pages(struct intel_remapped_info *rem_info,
>>> +		  struct drm_i915_gem_object *obj)
>>> +{
>>> +	unsigned int size = intel_remapped_info_size(rem_info);
>>> +	struct sg_table *st;
>>> +	struct scatterlist *sg;
>>> +	int ret = -ENOMEM;
>>> +	int i;
>>> +
>>> +	/* Allocate target SG list. */
>>> +	st = kmalloc(sizeof(*st), GFP_KERNEL);
>>> +	if (!st)
>>> +		goto err_st_alloc;
>>> +
>>> +	ret = sg_alloc_table(st, size, GFP_KERNEL);
>>> +	if (ret)
>>> +		goto err_sg_alloc;
>>> +
>>> +	st->nents = 0;
>>> +	sg = st->sgl;
>>> +
>>> +	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
>>> +		sg = remap_pages(obj, rem_info->plane[i].offset,
>>> +				 rem_info->plane[i].width, rem_info->plane[i].height,
>>> +				 rem_info->plane[i].stride, st, sg);
>>> +	}
>>> +
>>> +	i915_sg_trim(st);
>>> +
>>> +	return st;
>>> +
>>> +err_sg_alloc:
>>> +	kfree(st);
>>> +err_st_alloc:
>>> +
>>> +	DRM_DEBUG_DRIVER("Failed to create remapped mapping for object size %zu! (%ux%u tiles, %u pages)\n",
>>> +			 obj->base.size, rem_info->plane[0].width, rem_info->plane[0].height, size);
>>> +
>>> +	return ERR_PTR(ret);
>>> +}
>>> +
>>>    static noinline struct sg_table *
>>>    intel_partial_pages(const struct i915_ggtt_view *view,
>>>    		    struct drm_i915_gem_object *obj)
>>> @@ -3783,6 +3852,11 @@ i915_get_ggtt_vma_pages(struct i915_vma *vma)
>>>    			intel_rotate_pages(&vma->ggtt_view.rotated, vma->obj);
>>>    		break;
>>>    
>>> +	case I915_GGTT_VIEW_REMAPPED:
>>> +		vma->pages =
>>> +			intel_remap_pages(&vma->ggtt_view.remapped, vma->obj);
>>> +		break;
>>> +
>>>    	case I915_GGTT_VIEW_PARTIAL:
>>>    		vma->pages = intel_partial_pages(&vma->ggtt_view, vma->obj);
>>>    		break;
>>> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
>>> index 7e2af5f4f39b..69a22f57e6ca 100644
>>> --- a/drivers/gpu/drm/i915/i915_gem_gtt.h
>>> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
>>> @@ -160,11 +160,18 @@ typedef u64 gen8_ppgtt_pml4e_t;
>>>    
>>>    struct sg_table;
>>>    
>>> +struct intel_remapped_plane_info {
>>> +	/* in gtt pages */
>>> +	unsigned int width, height, stride, offset;
>>> +} __packed;
>>> +
>>> +struct intel_remapped_info {
>>> +	struct intel_remapped_plane_info plane[2];
>>> +	unsigned int unused_mbz;
>>> +} __packed;
>>> +
>>>    struct intel_rotation_info {
>>> -	struct intel_rotation_plane_info {
>>> -		/* tiles */
>>> -		unsigned int width, height, stride, offset;
>>> -	} plane[2];
>>> +	struct intel_remapped_plane_info plane[2];
>>>    } __packed;
>>>    
>>>    struct intel_partial_info {
>>> @@ -176,12 +183,20 @@ enum i915_ggtt_view_type {
>>>    	I915_GGTT_VIEW_NORMAL = 0,
>>>    	I915_GGTT_VIEW_ROTATED = sizeof(struct intel_rotation_info),
>>>    	I915_GGTT_VIEW_PARTIAL = sizeof(struct intel_partial_info),
>>> +	I915_GGTT_VIEW_REMAPPED = sizeof(struct intel_remapped_info),
>>>    };
>>>    
>>>    static inline void assert_i915_gem_gtt_types(void)
>>>    {
>>>    	BUILD_BUG_ON(sizeof(struct intel_rotation_info) != 8*sizeof(unsigned int));
>>>    	BUILD_BUG_ON(sizeof(struct intel_partial_info) != sizeof(u64) + sizeof(unsigned int));
>>> +	BUILD_BUG_ON(sizeof(struct intel_remapped_info) != 9*sizeof(unsigned int));
>>> +
>>> +	/* Check that rotation/remapped shares offsets for simplicity */
>>> +	BUILD_BUG_ON(offsetof(struct intel_remapped_info, plane[0]) !=
>>> +		     offsetof(struct intel_rotation_info, plane[0]));
>>> +	BUILD_BUG_ON(offsetofend(struct intel_remapped_info, plane[1]) !=
>>> +		     offsetofend(struct intel_rotation_info, plane[1]));
>>>    
>>>    	/* As we encode the size of each branch inside the union into its type,
>>>    	 * we have to be careful that each branch has a unique size.
>>> @@ -190,6 +205,7 @@ static inline void assert_i915_gem_gtt_types(void)
>>>    	case I915_GGTT_VIEW_NORMAL:
>>>    	case I915_GGTT_VIEW_PARTIAL:
>>>    	case I915_GGTT_VIEW_ROTATED:
>>> +	case I915_GGTT_VIEW_REMAPPED:
>>>    		/* gcc complains if these are identical cases */
>>>    		break;
>>>    	}
>>> @@ -201,6 +217,7 @@ struct i915_ggtt_view {
>>>    		/* Members need to contain no holes/padding */
>>>    		struct intel_partial_info partial;
>>>    		struct intel_rotation_info rotated;
>>> +		struct intel_remapped_info remapped;
>>>    	};
>>>    };
>>>    
>>> diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
>>> index 82652c3d1bed..2070e44eaa03 100644
>>> --- a/drivers/gpu/drm/i915/i915_vma.c
>>> +++ b/drivers/gpu/drm/i915/i915_vma.c
>>> @@ -164,6 +164,9 @@ vma_create(struct drm_i915_gem_object *obj,
>>>    		} else if (view->type == I915_GGTT_VIEW_ROTATED) {
>>>    			vma->size = intel_rotation_info_size(&view->rotated);
>>>    			vma->size <<= PAGE_SHIFT;
>>> +		} else if (view->type == I915_GGTT_VIEW_REMAPPED) {
>>> +			vma->size = intel_remapped_info_size(&view->remapped);
>>> +			vma->size <<= PAGE_SHIFT;
>>>    		}
>>>    	}
>>>    
>>> @@ -464,7 +467,8 @@ void __i915_vma_set_map_and_fenceable(struct i915_vma *vma)
>>>    	 * Explicitly disable for rotated VMA since the display does not
>>>    	 * need the fence and the VMA is not accessible to other users.
>>>    	 */
>>> -	if (vma->ggtt_view.type == I915_GGTT_VIEW_ROTATED)
>>> +	if (vma->ggtt_view.type == I915_GGTT_VIEW_ROTATED ||
>>> +	    vma->ggtt_view.type == I915_GGTT_VIEW_REMAPPED)
>>>    		return;
>>>    
>>>    	fenceable = (vma->node.size >= vma->fence_size &&
>>> diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
>>> index 4f7c1c7599f4..64cf029c028a 100644
>>> --- a/drivers/gpu/drm/i915/i915_vma.h
>>> +++ b/drivers/gpu/drm/i915/i915_vma.h
>>> @@ -265,8 +265,11 @@ i915_vma_compare(struct i915_vma *vma,
>>>    	 */
>>>    	BUILD_BUG_ON(I915_GGTT_VIEW_NORMAL >= I915_GGTT_VIEW_PARTIAL);
>>>    	BUILD_BUG_ON(I915_GGTT_VIEW_PARTIAL >= I915_GGTT_VIEW_ROTATED);
>>> +	BUILD_BUG_ON(I915_GGTT_VIEW_ROTATED >= I915_GGTT_VIEW_REMAPPED);
>>>    	BUILD_BUG_ON(offsetof(typeof(*view), rotated) !=
>>>    		     offsetof(typeof(*view), partial));
>>> +	BUILD_BUG_ON(offsetof(typeof(*view), rotated) !=
>>> +		     offsetof(typeof(*view), remapped));
>>>    	return memcmp(&vma->ggtt_view.partial, &view->partial, view->type);
>>>    }
>>>    
>>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>>> index 8a0b477a69d3..41f7e0795b14 100644
>>> --- a/drivers/gpu/drm/i915/intel_display.c
>>> +++ b/drivers/gpu/drm/i915/intel_display.c
>>> @@ -1957,6 +1957,17 @@ unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info
>>>    	return size;
>>>    }
>>>    
>>> +unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info)
>>> +{
>>> +	unsigned int size = 0;
>>> +	int i;
>>> +
>>> +	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++)
>>> +		size += rem_info->plane[i].width * rem_info->plane[i].height;
>>> +
>>> +	return size;
>>> +}
>>> +
>>>    static void
>>>    intel_fill_fb_ggtt_view(struct i915_ggtt_view *view,
>>>    			const struct drm_framebuffer *fb,
>>> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
>>> index 0e9a926fca04..6993eff5dfaf 100644
>>> --- a/drivers/gpu/drm/i915/intel_drv.h
>>> +++ b/drivers/gpu/drm/i915/intel_drv.h
>>> @@ -1523,6 +1523,7 @@ unsigned int intel_fb_xy_to_linear(int x, int y,
>>>    void intel_add_fb_offsets(int *x, int *y,
>>>    			  const struct intel_plane_state *state, int plane);
>>>    unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info);
>>> +unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info);
>>>    bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv);
>>>    void intel_mark_busy(struct drm_i915_private *dev_priv);
>>>    void intel_mark_idle(struct drm_i915_private *dev_priv);
>>> diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c
>>> index ffa74290e054..4fc49c27f13c 100644
>>> --- a/drivers/gpu/drm/i915/selftests/i915_vma.c
>>> +++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
>>> @@ -395,8 +395,8 @@ assert_rotated(struct drm_i915_gem_object *obj,
>>>    	return sg;
>>>    }
>>>    
>>> -static unsigned int rotated_size(const struct intel_rotation_plane_info *a,
>>> -				 const struct intel_rotation_plane_info *b)
>>> +static unsigned int rotated_size(const struct intel_remapped_plane_info *a,
>>> +				 const struct intel_remapped_plane_info *b)
>>>    {
>>>    	return a->width * a->height + b->width * b->height;
>>>    }
>>> @@ -406,7 +406,7 @@ static int igt_vma_rotate(void *arg)
>>>    	struct drm_i915_private *i915 = arg;
>>>    	struct i915_address_space *vm = &i915->ggtt.vm;
>>>    	struct drm_i915_gem_object *obj;
>>> -	const struct intel_rotation_plane_info planes[] = {
>>> +	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 },
>>>
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v3 0/8] drm/i915: GTT remapping for display
  2018-09-25 19:37 [PATCH v3 0/8] drm/i915: GTT remapping for display Ville Syrjala
                   ` (15 preceding siblings ...)
  2018-10-23 18:13 ` ✓ Fi.CI.IGT: " Patchwork
@ 2019-01-09  9:45 ` Timo Aaltonen
  16 siblings, 0 replies; 62+ messages in thread
From: Timo Aaltonen @ 2019-01-09  9:45 UTC (permalink / raw)
  To: Ville Syrjala, intel-gfx

On 25.9.2018 22.37, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Another gtt remapping posting.
> 
> Changes since the last time:
> - split out the plane stride check function (already in)
> - use add_overflows() (after massaging it a bit)
> - include some selftests for the remapped/rotated vmas
> - reduce the max fb size to 16kx16k on gen7+ due to mesa+glamor
>   and keep it unchanged at 8kx8k on gen4+ for the same reason
> 
> Ville Syrjälä (8):
>   drm/i915: Make sure fb gtt offsets stay within 32bits
>   drm/i915: Decouple SKL stride units from intel_fb_stride_alignment()
>   drm/i915: Add a new "remapped" gtt_view
>   drm/i915/selftests: Add mock selftest for remapped vmas
>   drm/i915/selftests: Add live vma selftest
>   drm/i915: Overcome display engine stride limits via GTT remapping
>   drm/i915: Bump gen4+ fb stride limit to 256KiB
>   drm/i915: Bump gen7+ fb size limits to 16kx16k
> 
>  drivers/gpu/drm/i915/i915_debugfs.c                |  12 +
>  drivers/gpu/drm/i915/i915_gem_gtt.c                |  91 +++++
>  drivers/gpu/drm/i915/i915_gem_gtt.h                |  25 +-
>  drivers/gpu/drm/i915/i915_utils.h                  |   8 +-
>  drivers/gpu/drm/i915/i915_vma.c                    |   6 +-
>  drivers/gpu/drm/i915/i915_vma.h                    |   3 +
>  drivers/gpu/drm/i915/intel_display.c               | 435 ++++++++++++++++-----
>  drivers/gpu/drm/i915/intel_drv.h                   |   1 +
>  .../gpu/drm/i915/selftests/i915_live_selftests.h   |   1 +
>  drivers/gpu/drm/i915/selftests/i915_vma.c          | 212 +++++++++-
>  10 files changed, 682 insertions(+), 112 deletions(-)

Hi, this series is still unmerged, any plan to get it mainline sometime
soon?


-- 
t
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v3 0/8] drm/i915: GTT remapping for display
@ 2019-01-18 15:27 Ville Syrjala
  0 siblings, 0 replies; 62+ messages in thread
From: Ville Syrjala @ 2019-01-18 15:27 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Another posting of the gtt remapping series. This time with Chris's idea
of forcing gtt remapping for ci. A slight gap in that testing comes from
the fact that igt will not align linear stride to 4k for non-dumb
buffers. I'd need to pair this with an igt patch to make that happen.

Apart from the hacks the only change from v2 is dealing with
fallout from intel_wakeref_t.

Force pushed on top of the last attempt:
git://github.com/vsyrjala/linux.git fb_vma_remap_13                                                                    

Ville Syrjälä (8):
  drm/i915: Add a new "remapped" gtt_view
  drm/i915/selftests: Add mock selftest for remapped vmas
  drm/i915/selftests: Add live vma selftest
  drm/i915: Overcome display engine stride limits via GTT remapping
  drm/i915: Bump gen4+ fb stride limit to 256KiB
  drm/i915: Bump gen7+ fb size limits to 16kx16k
  hack: drm/i915: Always remap gtt
  hack: align dumb buffer stride to 4k to allow for gtt remapping

 drivers/gpu/drm/i915/i915_debugfs.c           |  12 +
 drivers/gpu/drm/i915/i915_drv.h               |   4 +
 drivers/gpu/drm/i915/i915_gem.c               |  19 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c           |  88 ++++
 drivers/gpu/drm/i915/i915_gem_gtt.h           |  25 +-
 drivers/gpu/drm/i915/i915_vma.c               |  10 +-
 drivers/gpu/drm/i915/i915_vma.h               |   3 +
 drivers/gpu/drm/i915/intel_display.c          | 401 ++++++++++++++----
 drivers/gpu/drm/i915/intel_drv.h              |   1 +
 .../drm/i915/selftests/i915_live_selftests.h  |   1 +
 drivers/gpu/drm/i915/selftests/i915_vma.c     | 252 ++++++++++-
 11 files changed, 707 insertions(+), 109 deletions(-)

-- 
2.19.2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 62+ messages in thread

end of thread, other threads:[~2019-01-18 15:27 UTC | newest]

Thread overview: 62+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-25 19:37 [PATCH v3 0/8] drm/i915: GTT remapping for display Ville Syrjala
2018-09-25 19:37 ` [PATCH v3 1/8] drm/i915: Make sure fb gtt offsets stay within 32bits Ville Syrjala
2018-09-25 20:29   ` Chris Wilson
2018-09-26  9:27     ` Ville Syrjälä
2018-09-26 20:09       ` Chris Wilson
2018-09-27 12:24         ` Ville Syrjälä
2018-10-23 16:02   ` [PATCH v4 " Ville Syrjala
2018-10-23 18:49     ` Chris Wilson
2018-10-23 19:16       ` Ville Syrjälä
2018-09-25 19:37 ` [PATCH v3 2/8] drm/i915: Decouple SKL stride units from intel_fb_stride_alignment() Ville Syrjala
2018-10-23 18:50   ` Chris Wilson
2018-09-25 19:37 ` [PATCH v3 3/8] drm/i915: Add a new "remapped" gtt_view Ville Syrjala
2018-09-26  7:50   ` Tvrtko Ursulin
2018-10-01 15:03     ` Ville Syrjälä
2018-10-01 15:12       ` Chris Wilson
2018-10-01 15:27         ` Ville Syrjälä
2018-10-01 15:37           ` Chris Wilson
2018-10-01 15:48             ` Tvrtko Ursulin
2018-10-05 18:42               ` Ville Syrjälä
2018-10-09  8:24                 ` Tvrtko Ursulin
2018-10-09  8:41                   ` Chris Wilson
2018-10-09 11:54                   ` Ville Syrjälä
2018-10-10  7:04                     ` Tvrtko Ursulin
2018-10-01 15:38           ` Tvrtko Ursulin
2018-10-01 15:35         ` Tvrtko Ursulin
2018-10-23 16:02   ` [PATCH v4 " Ville Syrjala
2018-10-23 18:56     ` Chris Wilson
2018-10-23 19:10       ` Ville Syrjälä
2018-10-26  9:19     ` Tvrtko Ursulin
2018-10-26 12:43       ` Ville Syrjälä
2018-10-26 12:48         ` Tvrtko Ursulin
2018-09-25 19:37 ` [PATCH v3 4/8] drm/i915/selftests: Add mock selftest for remapped vmas Ville Syrjala
2018-09-25 20:22   ` Chris Wilson
2018-09-26  9:28     ` Ville Syrjälä
2018-10-23 16:03   ` [PATCH v4 " Ville Syrjala
2018-10-23 19:02     ` Chris Wilson
2018-10-23 19:14       ` Ville Syrjälä
2018-09-25 19:37 ` [PATCH v3 5/8] drm/i915/selftests: Add live vma selftest Ville Syrjala
2018-09-25 20:19   ` Chris Wilson
2018-09-25 20:40   ` Chris Wilson
2018-09-26  9:33     ` Ville Syrjälä
2018-10-23 16:03   ` [PATCH v4 " Ville Syrjala
2018-10-23 19:05     ` Chris Wilson
2018-09-25 19:37 ` [PATCH v3 6/8] drm/i915: Overcome display engine stride limits via GTT remapping Ville Syrjala
2018-10-23 19:16   ` Chris Wilson
2018-10-25 13:45     ` Ville Syrjälä
2018-09-25 19:37 ` [PATCH v3 7/8] drm/i915: Bump gen4+ fb stride limit to 256KiB Ville Syrjala
2018-09-25 20:13   ` Chris Wilson
2018-09-28 19:19     ` Ville Syrjälä
2018-09-25 19:37 ` [PATCH v3 8/8] drm/i915: Bump gen7+ fb size limits to 16kx16k Ville Syrjala
2018-09-25 19:59   ` Chris Wilson
2018-09-26  9:25     ` Ville Syrjälä
2018-09-25 20:05 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: GTT remapping for display Patchwork
2018-09-25 20:08 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-09-25 20:30 ` ✓ Fi.CI.BAT: success " Patchwork
2018-09-25 21:21 ` ✓ Fi.CI.IGT: " Patchwork
2018-10-23 16:21 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: GTT remapping for display (rev5) Patchwork
2018-10-23 16:24 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-10-23 16:43 ` ✓ Fi.CI.BAT: success " Patchwork
2018-10-23 18:13 ` ✓ Fi.CI.IGT: " Patchwork
2019-01-09  9:45 ` [PATCH v3 0/8] drm/i915: GTT remapping for display Timo Aaltonen
2019-01-18 15:27 Ville Syrjala

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.