diff mbox

[1/2] drm/i915/gtt: Fix pte clear range

Message ID 1477927486-6549-1-git-send-email-mika.kuoppala@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Mika Kuoppala Oct. 31, 2016, 3:24 p.m. UTC
Comparing pte index to a number of entries is wrong
when clearing a range of pte entries. Use end marker
of 'one past' to correctly point adequate number of
ptes to the scratch page.

Fixes: d209b9c3cd28 ("drm/i915/gtt: Split gen8_ppgtt_clear_pte_range")
References: https://bugs.freedesktop.org/show_bug.cgi?id=98282
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Michel Thierry <michel.thierry@intel.com>
Cc: Michał Winiarski <michal.winiarski@intel.com>
Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

Comments

Chris Wilson Oct. 31, 2016, 3:42 p.m. UTC | #1
On Mon, Oct 31, 2016 at 05:24:45PM +0200, Mika Kuoppala wrote:
> Comparing pte index to a number of entries is wrong
> when clearing a range of pte entries. Use end marker
> of 'one past' to correctly point adequate number of
> ptes to the scratch page.
> 
> Fixes: d209b9c3cd28 ("drm/i915/gtt: Split gen8_ppgtt_clear_pte_range")
> References: https://bugs.freedesktop.org/show_bug.cgi?id=98282
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> Cc: Michel Thierry <michel.thierry@intel.com>
> Cc: Michał Winiarski <michal.winiarski@intel.com>
> Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_gem_gtt.c | 19 +++++++++++--------
>  1 file changed, 11 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index e7afad5..cda263c 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -712,13 +712,13 @@ static int gen8_48b_mm_switch(struct i915_hw_ppgtt *ppgtt,
>   */
>  static bool gen8_ppgtt_clear_pt(struct i915_address_space *vm,
>  				struct i915_page_table *pt,
> -				uint64_t start,
> -				uint64_t length)
> +				const uint64_t start,
> +				const uint64_t length)
>  {
>  	struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
> -	unsigned int pte_start = gen8_pte_index(start);
> -	unsigned int num_entries = gen8_pte_count(start, length);
> -	uint64_t pte;
> +	const unsigned int num_entries = gen8_pte_count(start, length);
> +	unsigned int pte = gen8_pte_index(start);
> +	unsigned int pte_end = pte + num_entries;
>  	gen8_pte_t *pt_vaddr;
>  	gen8_pte_t scratch_pte = gen8_pte_encode(vm->scratch_page.daddr,
>  						 I915_CACHE_LLC);
> @@ -726,17 +726,20 @@ static bool gen8_ppgtt_clear_pt(struct i915_address_space *vm,
>  	if (WARN_ON(!px_page(pt)))
>  		return false;
>  
> -	bitmap_clear(pt->used_ptes, pte_start, num_entries);
> +	bitmap_clear(pt->used_ptes, pte, num_entries);
>  
>  	if (bitmap_empty(pt->used_ptes, GEN8_PTES)) {
>  		free_pt(vm->dev, pt);
>  		return true;
>  	}
>  
> +	if (WARN_ON_ONCE(pte_end > GEN8_PTES))
> +		pte_end = GEN8_PTES;

Internal programming error, if you hit all the upper layers are dead,
i.e. bug on. GEM_BUG_ON.

And the assert should be earlier since you have already used the invalid
values (i.e. pte+num_entries).

> +
>  	pt_vaddr = kmap_px(pt);
>  
> -	for (pte = pte_start; pte < num_entries; pte++)

Nice catch.
R-b on this part, less enamoured with the reset.
-Chris
Mika Kuoppala Nov. 1, 2016, 4:28 p.m. UTC | #2
Patchwork <patchwork@emeril.freedesktop.org> writes:

> == Series Details ==
>
> Series: series starting with [1/2] drm/i915/gtt: Fix pte clear range (rev3)
> URL   : https://patchwork.freedesktop.org/series/14620/
> State : warning
>
> == Summary ==
>
> Series 14620v3 Series without cover letter
> https://patchwork.freedesktop.org/api/1.0/series/14620/revisions/3/mbox/
>
> Test drv_module_reload_basic:
>                 dmesg-warn -> PASS       (fi-skl-6770hq)
>                 dmesg-warn -> PASS       (fi-ilk-650)
> Test kms_pipe_crc_basic:
>         Subgroup nonblocking-crc-pipe-a-frame-sequence:
>                 pass       -> DMESG-WARN (fi-ilk-650)
>         Subgroup nonblocking-crc-pipe-b:
>                 pass       -> DMESG-WARN (fi-ilk-650)
>         Subgroup nonblocking-crc-pipe-b-frame-sequence:
>                 pass       -> DMESG-WARN (fi-ilk-650)

https://bugs.freedesktop.org/show_bug.cgi?id=98531

>
> fi-bdw-5557u     total:241  pass:226  dwarn:0   dfail:0   fail:0   skip:15 
> fi-bsw-n3050     total:241  pass:201  dwarn:0   dfail:0   fail:0   skip:40 
> fi-bxt-t5700     total:241  pass:213  dwarn:0   dfail:0   fail:0   skip:28 
> fi-byt-j1900     total:241  pass:213  dwarn:0   dfail:0   fail:0   skip:28 
> fi-byt-n2820     total:241  pass:209  dwarn:0   dfail:0   fail:0   skip:32 
> fi-hsw-4770      total:241  pass:221  dwarn:0   dfail:0   fail:0   skip:20 
> fi-hsw-4770r     total:241  pass:220  dwarn:0   dfail:0   fail:0   skip:21 
> fi-ilk-650       total:241  pass:184  dwarn:3   dfail:0   fail:0   skip:54 
> fi-ivb-3520m     total:241  pass:218  dwarn:0   dfail:0   fail:0   skip:23 
> fi-ivb-3770      total:241  pass:218  dwarn:0   dfail:0   fail:0   skip:23 
> fi-kbl-7200u     total:241  pass:219  dwarn:0   dfail:0   fail:0   skip:22 
> fi-skl-6260u     total:241  pass:227  dwarn:0   dfail:0   fail:0   skip:14 
> fi-skl-6700hq    total:241  pass:220  dwarn:0   dfail:0   fail:0   skip:21 
> fi-skl-6700k     total:241  pass:219  dwarn:1   dfail:0   fail:0   skip:21 
> fi-skl-6770hq    total:241  pass:227  dwarn:0   dfail:0   fail:0   skip:14 
> fi-snb-2520m     total:241  pass:208  dwarn:0   dfail:0   fail:0   skip:33 
> fi-snb-2600      total:241  pass:207  dwarn:0   dfail:0   fail:0   skip:34 
>
> 659f3942757fa5e85f37a2cab9da8c94b8f16f7a drm-intel-nightly: 2016y-11m-01d-14h-42m-02s UTC integration manifest
> b44a28b drm/i915/gtt: Mark tlbs dirty on clear
> de61fdd drm/i915/gtt: Fix pte clear range
>
> == Logs ==
>
> For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_2876/
^^

This is awesome!

-Mika
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index e7afad5..cda263c 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -712,13 +712,13 @@  static int gen8_48b_mm_switch(struct i915_hw_ppgtt *ppgtt,
  */
 static bool gen8_ppgtt_clear_pt(struct i915_address_space *vm,
 				struct i915_page_table *pt,
-				uint64_t start,
-				uint64_t length)
+				const uint64_t start,
+				const uint64_t length)
 {
 	struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
-	unsigned int pte_start = gen8_pte_index(start);
-	unsigned int num_entries = gen8_pte_count(start, length);
-	uint64_t pte;
+	const unsigned int num_entries = gen8_pte_count(start, length);
+	unsigned int pte = gen8_pte_index(start);
+	unsigned int pte_end = pte + num_entries;
 	gen8_pte_t *pt_vaddr;
 	gen8_pte_t scratch_pte = gen8_pte_encode(vm->scratch_page.daddr,
 						 I915_CACHE_LLC);
@@ -726,17 +726,20 @@  static bool gen8_ppgtt_clear_pt(struct i915_address_space *vm,
 	if (WARN_ON(!px_page(pt)))
 		return false;
 
-	bitmap_clear(pt->used_ptes, pte_start, num_entries);
+	bitmap_clear(pt->used_ptes, pte, num_entries);
 
 	if (bitmap_empty(pt->used_ptes, GEN8_PTES)) {
 		free_pt(vm->dev, pt);
 		return true;
 	}
 
+	if (WARN_ON_ONCE(pte_end > GEN8_PTES))
+		pte_end = GEN8_PTES;
+
 	pt_vaddr = kmap_px(pt);
 
-	for (pte = pte_start; pte < num_entries; pte++)
-		pt_vaddr[pte] = scratch_pte;
+	while (pte < pte_end)
+		pt_vaddr[pte++] = scratch_pte;
 
 	kunmap_px(ppgtt, pt_vaddr);