All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
To: Chris Wilson <chris@chris-wilson.co.uk>,
	intel-gfx <intel-gfx@lists.freedesktop.org>
Subject: Re: [PATCH 2/4] drm/i915: Handle incomplete Z_FINISH for compressed error states
Date: Tue, 2 Oct 2018 13:20:05 +0100	[thread overview]
Message-ID: <673d9c33-df35-d403-3e61-fbbc98047ba6@linux.intel.com> (raw)
In-Reply-To: <20181001194447.29910-2-chris@chris-wilson.co.uk>


On 01/10/2018 20:44, Chris Wilson wrote:
> The final call to zlib_deflate(Z_FINISH) may require more output
> space to be allocated and so needs to re-invoked. Failure to do so in
> the current code leads to incomplete zlib streams (albeit intact due to
> the use of Z_SYNC_FLUSH) resulting in the occasional short object
> capture.
> 
> Testcase: igt/i915-error-capture.js
> Fixes: 0a97015d45ee ("drm/i915: Compress GPU objects in error state")
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> Cc: <stable@vger.kernel.org> # v4.10+
> ---
>   drivers/gpu/drm/i915/i915_gpu_error.c | 60 +++++++++++++++++++++------
>   1 file changed, 47 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
> index 3d5554f14dfd..ed8c16cbfaa4 100644
> --- a/drivers/gpu/drm/i915/i915_gpu_error.c
> +++ b/drivers/gpu/drm/i915/i915_gpu_error.c
> @@ -237,6 +237,7 @@ static int compress_page(struct compress *c,
>   			 struct drm_i915_error_object *dst)
>   {
>   	struct z_stream_s *zstream = &c->zstream;
> +	int flush = Z_NO_FLUSH;
>   
>   	zstream->next_in = src;
>   	if (c->tmp && i915_memcpy_from_wc(c->tmp, src, PAGE_SIZE))
> @@ -257,8 +258,11 @@ static int compress_page(struct compress *c,
>   			zstream->avail_out = PAGE_SIZE;
>   		}

Looks like the block above, not shown in this diff, could use a check 
and abort if the dst->page_count overgrows the pessimistic allocation of 
the array.

>   
> -		if (zlib_deflate(zstream, Z_SYNC_FLUSH) != Z_OK)
> +		if (zlib_deflate(zstream, flush) != Z_OK)

So this (not always asking for a flush) actually not only fixes the 
flush at the end but improves the API usage and potentially compression 
ratio, correct?

>   			return -EIO;
> +
> +		if (zstream->avail_out)
> +			flush = Z_SYNC_FLUSH;

Hm.. but why this? It will flush only occasionally, when one input page 
did not fit in the available output - but that will depend on 
compressibility so I don't think it has a fixed period. It is not for 
instance for every 4k of compressed output, if that was maybe the goal.

>   	} while (zstream->avail_in);
>   
>   	/* Fallback to uncompressed if we increase size? */
> @@ -268,19 +272,43 @@ static int compress_page(struct compress *c,
>   	return 0;
>   }
>   
> -static void compress_fini(struct compress *c,
> +static int compress_flush(struct compress *c,
>   			  struct drm_i915_error_object *dst)
>   {
>   	struct z_stream_s *zstream = &c->zstream;
> +	unsigned long page;
>   
> -	if (dst) {
> -		zlib_deflate(zstream, Z_FINISH);
> -		dst->unused = zstream->avail_out;
> -	}
> +	do {
> +		switch (zlib_deflate(zstream, Z_FINISH)) {
> +		case Z_OK: /* more space requested */
> +			page = __get_free_page(GFP_ATOMIC | __GFP_NOWARN);
> +			if (!page)
> +				return -ENOMEM;
> +
> +			dst->pages[dst->page_count++] = (void *)page;

I'd put in a check for pages array exhaustion here as well. Or even 
better, compress_page and compress_flush could share this whole block.

> +			zstream->next_out = (void *)page;
> +			zstream->avail_out = PAGE_SIZE;
> +			break;
> +		case Z_STREAM_END:
> +			goto end;
> +		default: /* any error */
> +			return -EIO;
> +		}
> +	} while (1);
> +
> +end:
> +	memset(zstream->next_out, 0, zstream->avail_out);
> +	dst->unused = zstream->avail_out;
> +	return 0;
> +}
> +
> +static void compress_fini(struct compress *c,
> +			  struct drm_i915_error_object *dst)
> +{
> +	struct z_stream_s *zstream = &c->zstream;
>   
>   	zlib_deflateEnd(zstream);
>   	kfree(zstream->workspace);
> -
>   	if (c->tmp)
>   		free_page((unsigned long)c->tmp);
>   }
> @@ -319,6 +347,12 @@ static int compress_page(struct compress *c,
>   	return 0;
>   }
>   
> +static int compress_flush(struct compress *c,
> +			  struct drm_i915_error_object *dst)
> +{
> +	return 0;
> +}
> +
>   static void compress_fini(struct compress *c,
>   			  struct drm_i915_error_object *dst)
>   {
> @@ -951,15 +985,15 @@ i915_error_object_create(struct drm_i915_private *i915,
>   		if (ret)
>   			goto unwind;
>   	}
> -	goto out;
>   
> +	if (compress_flush(&compress, dst)) {
>   unwind:

A bit nasty, jump in conditional block. Could set a boolean and break 
from the above loop. Like "if (failed || compress_flush(...))".

> -	while (dst->page_count--)
> -		free_page((unsigned long)dst->pages[dst->page_count]);
> -	kfree(dst);
> -	dst = NULL;
> +		while (dst->page_count--)
> +			free_page((unsigned long)dst->pages[dst->page_count]);
> +		kfree(dst);
> +		dst = NULL;
> +	}
>   
> -out:
>   	compress_fini(&compress, dst);
>   	ggtt->vm.clear_range(&ggtt->vm, slot, PAGE_SIZE);
>   	return dst;
> 

Regards,

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

  reply	other threads:[~2018-10-02 12:20 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-01 19:44 [PATCH 1/4] drm/i915: Replace some open-coded i915_map_coherent_type() Chris Wilson
2018-10-01 19:44 ` [PATCH 2/4] drm/i915: Handle incomplete Z_FINISH for compressed error states Chris Wilson
2018-10-02 12:20   ` Tvrtko Ursulin [this message]
2018-10-02 12:24     ` Chris Wilson
2018-10-02 13:13       ` Tvrtko Ursulin
2018-10-02 13:22         ` Chris Wilson
2018-10-02 13:46           ` Tvrtko Ursulin
2018-10-02 13:52             ` Chris Wilson
2018-10-02 14:34               ` Tvrtko Ursulin
2018-10-02 12:36   ` [PATCH v2] " Chris Wilson
2018-10-03  8:24   ` [PATCH v3] " Chris Wilson
2018-10-03  9:04     ` Tvrtko Ursulin
2018-10-03  9:04       ` [Intel-gfx] " Tvrtko Ursulin
2018-10-03 10:47       ` Chris Wilson
2018-10-01 19:44 ` [PATCH 3/4] drm/i915: Clear the error PTE just once on finish Chris Wilson
2018-10-02 12:27   ` Tvrtko Ursulin
2018-10-01 19:44 ` [PATCH 4/4] drm/i915: Cache the error string Chris Wilson
2018-10-01 21:39 ` ✗ Fi.CI.SPARSE: warning for series starting with [1/4] drm/i915: Replace some open-coded i915_map_coherent_type() Patchwork
2018-10-01 22:02 ` ✗ Fi.CI.BAT: failure " Patchwork
2018-10-02 11:48 ` [PATCH 1/4] " Tvrtko Ursulin
2018-10-02 13:31 ` ✗ Fi.CI.SPARSE: warning for series starting with [1/4] drm/i915: Replace some open-coded i915_map_coherent_type() (rev2) Patchwork
2018-10-02 13:49 ` ✓ Fi.CI.BAT: success " Patchwork
2018-10-03  2:47 ` ✗ Fi.CI.IGT: failure " Patchwork
2018-10-03  9:56   ` Martin Peres
2018-10-03  9:05 ` ✗ Fi.CI.BAT: failure for series starting with [1/4] drm/i915: Replace some open-coded i915_map_coherent_type() (rev3) Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=673d9c33-df35-d403-3e61-fbbc98047ba6@linux.intel.com \
    --to=tvrtko.ursulin@linux.intel.com \
    --cc=chris@chris-wilson.co.uk \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.