diff mbox

[v2] drm/i915/skl: Make sure to allocate mininum sizes in the DDB

Message ID 1423488910-19303-1-git-send-email-damien.lespiau@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Lespiau, Damien Feb. 9, 2015, 1:35 p.m. UTC
I overlooked the fact that we need to allocate a minimum 8 blocks and
that just allocating the planes depending on how much they need to fetch
from the DDB in proportion of how much memory bw is necessary for the
whole display can lead to cases where we don't respect those minima (and
thus overrun).

So, instead, start by allocating 8 blocks to each active display plane
and then allocate the remaining blocks like before.

v2: Rebase on top of -nightly

Cc: Mahesh Kumar <mahesh1.kumar@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

Comments

Ville Syrjälä Feb. 9, 2015, 1:56 p.m. UTC | #1
On Mon, Feb 09, 2015 at 01:35:10PM +0000, Damien Lespiau wrote:
> I overlooked the fact that we need to allocate a minimum 8 blocks and
> that just allocating the planes depending on how much they need to fetch
> from the DDB in proportion of how much memory bw is necessary for the
> whole display can lead to cases where we don't respect those minima (and
> thus overrun).
> 
> So, instead, start by allocating 8 blocks to each active display plane
> and then allocate the remaining blocks like before.
> 
> v2: Rebase on top of -nightly
> 
> Cc: Mahesh Kumar <mahesh1.kumar@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 22 ++++++++++++++++++----
>  1 file changed, 18 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index bebefe7..f6c7e53 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2502,6 +2502,7 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
>  	enum pipe pipe = intel_crtc->pipe;
>  	struct skl_ddb_entry *alloc = &ddb->pipe[pipe];
>  	uint16_t alloc_size, start, cursor_blocks;
> +	uint16_t minimum[I915_MAX_PLANES];
>  	unsigned int total_data_rate;
>  	int plane;
>  
> @@ -2520,9 +2521,21 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
>  	alloc_size -= cursor_blocks;
>  	alloc->end -= cursor_blocks;
>  
> +	/* 1. Allocate the mininum required blocks for each active plane */
> +	for_each_plane(pipe, plane) {
> +		const struct intel_plane_wm_parameters *p;
> +
> +		p = &params->plane[plane];
> +		if (!p->enabled)
> +			continue;
> +
> +		minimum[plane] = 8;
> +		alloc_size -= minimum[plane];
> +	}
> +
>  	/*
> -	 * Each active plane get a portion of the remaining space, in
> -	 * proportion to the amount of data they need to fetch from memory.
> +	 * 2. Distribute the remaining space in proportion to the amount of
> +	 * data each plane needs to fetch from memory.
>  	 *
>  	 * FIXME: we may not allocate every single block here.
>  	 */
> @@ -2544,8 +2557,9 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
>  		 * promote the expression to 64 bits to avoid overflowing, the
>  		 * result is < available as data_rate / total_data_rate < 1
>  		 */
> -		plane_blocks = div_u64((uint64_t)alloc_size * data_rate,
> -				       total_data_rate);
> +		plane_blocks = minimum[plane];
> +		plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
> +					total_data_rate);

The minimum[] array seems pointless. The value here is always going to
be 8.

>  
>  		ddb->plane[pipe][plane].start = start;
>  		ddb->plane[pipe][plane].end = start + plane_blocks;
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Lespiau, Damien Feb. 9, 2015, 1:59 p.m. UTC | #2
On Mon, Feb 09, 2015 at 03:56:20PM +0200, Ville Syrjälä wrote:
> > @@ -2544,8 +2557,9 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
> >  		 * promote the expression to 64 bits to avoid overflowing, the
> >  		 * result is < available as data_rate / total_data_rate < 1
> >  		 */
> > -		plane_blocks = div_u64((uint64_t)alloc_size * data_rate,
> > -				       total_data_rate);
> > +		plane_blocks = minimum[plane];
> > +		plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
> > +					total_data_rate);
> 
> The minimum[] array seems pointless. The value here is always going to
> be 8.

Not in the future with new features appearing.
Shuang He Feb. 10, 2015, 4:09 a.m. UTC | #3
Tested-By: PRC QA PRTS (Patch Regression Test System Contact: shuang.he@intel.com)
Task id: 5732
-------------------------------------Summary-------------------------------------
Platform          Delta          drm-intel-nightly          Series Applied
PNV                                  282/283              282/283
ILK                                  308/319              308/319
SNB              +1-3              340/346              338/346
IVB              +1-2              378/384              377/384
BYT                                  296/296              296/296
HSW              +1                 421/428              422/428
BDW                                  318/333              318/333
-------------------------------------Detailed-------------------------------------
Platform  Test                                drm-intel-nightly          Series Applied
*SNB  igt_kms_flip_dpms-vs-vblank-race      PASS(3, M22)      DMESG_WARN(1, M22)
 SNB  igt_kms_flip_dpms-vs-vblank-race-interruptible      DMESG_WARN(3, M22)PASS(1, M22)      DMESG_WARN(1, M22)
 SNB  igt_kms_flip_modeset-vs-vblank-race-interruptible      DMESG_WARN(1, M22)PASS(2, M22)      DMESG_WARN(1, M22)
 SNB  igt_kms_pipe_crc_basic_read-crc-pipe-A      DMESG_WARN(1, M22)PASS(4, M22)      PASS(1, M22)
*IVB  igt_gem_pwrite_pread_snooped-copy-performance      PASS(2, M34)      DMESG_WARN(1, M34)
 IVB  igt_gem_storedw_batches_loop_normal      DMESG_WARN(1, M34)PASS(1, M34)      PASS(1, M34)
 IVB  igt_gem_storedw_batches_loop_secure-dispatch      DMESG_WARN(1, M34)PASS(1, M34)      DMESG_WARN(1, M34)
 HSW  igt_gem_storedw_loop_blt      DMESG_WARN(2, M20)PASS(1, M20)      PASS(1, M20)
Note: You need to pay more attention to line start with '*'
Ville Syrjälä Feb. 24, 2015, 5:56 p.m. UTC | #4
On Mon, Feb 09, 2015 at 01:35:10PM +0000, Damien Lespiau wrote:
> I overlooked the fact that we need to allocate a minimum 8 blocks and
> that just allocating the planes depending on how much they need to fetch
> from the DDB in proportion of how much memory bw is necessary for the
> whole display can lead to cases where we don't respect those minima (and
> thus overrun).
> 
> So, instead, start by allocating 8 blocks to each active display plane
> and then allocate the remaining blocks like before.
> 
> v2: Rebase on top of -nightly
> 
> Cc: Mahesh Kumar <mahesh1.kumar@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

OK after reading through the spec the minimum[] thing makes sense, so
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/i915/intel_pm.c | 22 ++++++++++++++++++----
>  1 file changed, 18 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index bebefe7..f6c7e53 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2502,6 +2502,7 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
>  	enum pipe pipe = intel_crtc->pipe;
>  	struct skl_ddb_entry *alloc = &ddb->pipe[pipe];
>  	uint16_t alloc_size, start, cursor_blocks;
> +	uint16_t minimum[I915_MAX_PLANES];
>  	unsigned int total_data_rate;
>  	int plane;
>  
> @@ -2520,9 +2521,21 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
>  	alloc_size -= cursor_blocks;
>  	alloc->end -= cursor_blocks;
>  
> +	/* 1. Allocate the mininum required blocks for each active plane */
> +	for_each_plane(pipe, plane) {
> +		const struct intel_plane_wm_parameters *p;
> +
> +		p = &params->plane[plane];
> +		if (!p->enabled)
> +			continue;
> +
> +		minimum[plane] = 8;
> +		alloc_size -= minimum[plane];
> +	}
> +
>  	/*
> -	 * Each active plane get a portion of the remaining space, in
> -	 * proportion to the amount of data they need to fetch from memory.
> +	 * 2. Distribute the remaining space in proportion to the amount of
> +	 * data each plane needs to fetch from memory.
>  	 *
>  	 * FIXME: we may not allocate every single block here.
>  	 */
> @@ -2544,8 +2557,9 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
>  		 * promote the expression to 64 bits to avoid overflowing, the
>  		 * result is < available as data_rate / total_data_rate < 1
>  		 */
> -		plane_blocks = div_u64((uint64_t)alloc_size * data_rate,
> -				       total_data_rate);
> +		plane_blocks = minimum[plane];
> +		plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
> +					total_data_rate);
>  
>  		ddb->plane[pipe][plane].start = start;
>  		ddb->plane[pipe][plane].end = start + plane_blocks;
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Daniel Vetter Feb. 24, 2015, 8:42 p.m. UTC | #5
On Tue, Feb 24, 2015 at 07:56:58PM +0200, Ville Syrjälä wrote:
> On Mon, Feb 09, 2015 at 01:35:10PM +0000, Damien Lespiau wrote:
> > I overlooked the fact that we need to allocate a minimum 8 blocks and
> > that just allocating the planes depending on how much they need to fetch
> > from the DDB in proportion of how much memory bw is necessary for the
> > whole display can lead to cases where we don't respect those minima (and
> > thus overrun).
> > 
> > So, instead, start by allocating 8 blocks to each active display plane
> > and then allocate the remaining blocks like before.
> > 
> > v2: Rebase on top of -nightly
> > 
> > Cc: Mahesh Kumar <mahesh1.kumar@intel.com>
> > Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> 
> OK after reading through the spec the minimum[] thing makes sense, so
> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

Queued for -next, thanks for the patch.
-Daniel
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index bebefe7..f6c7e53 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2502,6 +2502,7 @@  skl_allocate_pipe_ddb(struct drm_crtc *crtc,
 	enum pipe pipe = intel_crtc->pipe;
 	struct skl_ddb_entry *alloc = &ddb->pipe[pipe];
 	uint16_t alloc_size, start, cursor_blocks;
+	uint16_t minimum[I915_MAX_PLANES];
 	unsigned int total_data_rate;
 	int plane;
 
@@ -2520,9 +2521,21 @@  skl_allocate_pipe_ddb(struct drm_crtc *crtc,
 	alloc_size -= cursor_blocks;
 	alloc->end -= cursor_blocks;
 
+	/* 1. Allocate the mininum required blocks for each active plane */
+	for_each_plane(pipe, plane) {
+		const struct intel_plane_wm_parameters *p;
+
+		p = &params->plane[plane];
+		if (!p->enabled)
+			continue;
+
+		minimum[plane] = 8;
+		alloc_size -= minimum[plane];
+	}
+
 	/*
-	 * Each active plane get a portion of the remaining space, in
-	 * proportion to the amount of data they need to fetch from memory.
+	 * 2. Distribute the remaining space in proportion to the amount of
+	 * data each plane needs to fetch from memory.
 	 *
 	 * FIXME: we may not allocate every single block here.
 	 */
@@ -2544,8 +2557,9 @@  skl_allocate_pipe_ddb(struct drm_crtc *crtc,
 		 * promote the expression to 64 bits to avoid overflowing, the
 		 * result is < available as data_rate / total_data_rate < 1
 		 */
-		plane_blocks = div_u64((uint64_t)alloc_size * data_rate,
-				       total_data_rate);
+		plane_blocks = minimum[plane];
+		plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
+					total_data_rate);
 
 		ddb->plane[pipe][plane].start = start;
 		ddb->plane[pipe][plane].end = start + plane_blocks;