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
next prev parent 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.