Re: [Intel-gfx] [PATCH 05/38] drm/i915: Compress GPU objects in error state

2016-09-21 Thread Joonas Lahtinen
On ti, 2016-09-20 at 09:29 +0100, Chris Wilson wrote:
> @@ -175,6 +176,110 @@ static void i915_error_puts(struct 
> drm_i915_error_state_buf *e,
>  #define err_printf(e, ...) i915_error_printf(e, __VA_ARGS__)
>  #define err_puts(e, s) i915_error_puts(e, s)
>  
> +#ifdef CONFIG_DRM_I915_COMPRESS_ERROR
> +
> +static bool compress_init(struct z_stream_s *zstream)
> +{
> + memset(zstream, 0, sizeof(*zstream));
> +
> + zstream->workspace =
> + kmalloc(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL),
> + GFP_ATOMIC | __GFP_NOWARN);
> + if (!zstream->workspace)
> + return NULL;

return false;

> +static int compress_page(struct z_stream_s *zstream,
> +  void *src,
> +  struct drm_i915_error_object *dst)
> +{
> + zstream->next_in = src;
> + zstream->avail_in = PAGE_SIZE;
> +
> + do {
> + if (zstream->avail_out == 0) {
> + unsigned long page;
> +
> + page = __get_free_page(GFP_ATOMIC | __GFP_NOWARN);
> + if (!page)
> + return -ENOMEM;
> +
> + dst->pages[dst->page_count++] = (void *)page;
> +
> + zstream->next_out = (void *)page;
> + zstream->avail_out = PAGE_SIZE;
> + }
> +
> + if (zlib_deflate(zstream, Z_SYNC_FLUSH) != Z_OK)
> + return -EIO;
> +
> + /* Fallback to uncompressed if we increase size? */
> + if (0 && zstream->total_out > zstream->total_in)
> + return -E2BIG;

We could still end up decreasing in the future, so this check should
really be outside of this function at the end of compression.

> @@ -327,13 +450,23 @@ static void print_error_obj(struct 
> drm_i915_error_state_buf *m,
>      lower_32_bits(obj->gtt_offset));
>   }
>  
> - for (page = offset = 0; page < obj->page_count; page++) {
> - for (elt = 0; elt < PAGE_SIZE/4; elt++) {
> - err_printf(m, "%08x :  %08x\n", offset,
> -    obj->pages[page][elt]);
> - offset += 4;
> + err_compression_marker(m);
> + for (page = 0; page < obj->page_count; page++) {
> + int i, len;
> +
> + len = PAGE_SIZE;
> + if (page == obj->page_count - 1)
> + len -= obj->unused;
> + len = (len + 3) / 4;

Magic-ish. ascii85_length() or so.

> + num_pages = DIV_ROUND_UP(10 * num_pages, 8); /* worstcase zlib growth */

Could be a function added to kernel zlib.

Above addressed;

Reviewed-by: Joonas Lahtinen 

Regards, Joonas
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 05/38] drm/i915: Compress GPU objects in error state

2016-09-20 Thread Chris Wilson
Our error states are quickly growing, pinning kernel memory with them.
The majority of the space is taken up by the error objects. These
compress well using zlib and without decode are mostly meaningless, so
encoding them does not hinder quickly parsing the error state for
familiarity.

v2: Make the zlib dependency optional

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/Kconfig  |  12 +++
 drivers/gpu/drm/i915/i915_drv.h   |   3 +-
 drivers/gpu/drm/i915/i915_gpu_error.c | 170 +-
 3 files changed, 163 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index 0f46a9c04c0e..92ecced1bc8f 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -57,6 +57,18 @@ config DRM_I915_CAPTURE_ERROR
 
  If in doubt, say "Y".
 
+config DRM_I915_COMPRESS_ERROR
+   bool "Compress GPU error state"
+   depends on DRM_I915_CAPTURE_ERROR
+   select ZLIB_DEFLATE
+   default y
+   help
+ This option selects ZLIB_DEFLATE if it isn't already
+ selected and causes any error state captured upon a GPU hang
+ to be compressed using zlib.
+
+ If in doubt, say "Y".
+
 config DRM_I915_USERPTR
bool "Always enable userptr support"
depends on DRM_I915
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 3fda31816fdd..dc0cca48ff3d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -806,9 +806,10 @@ struct drm_i915_error_state {
u32 semaphore_mboxes[I915_NUM_ENGINES - 1];
 
struct drm_i915_error_object {
-   int page_count;
u64 gtt_offset;
u64 gtt_size;
+   int page_count;
+   int unused;
u32 *pages[0];
} *ringbuffer, *batchbuffer, *wa_batchbuffer, *ctx, *hws_page;
 
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c 
b/drivers/gpu/drm/i915/i915_gpu_error.c
index f4cc6746dc72..dcb279035b29 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -29,6 +29,7 @@
 
 #include 
 #include 
+#include 
 #include "i915_drv.h"
 
 #ifdef CONFIG_DRM_I915_CAPTURE_ERROR
@@ -175,6 +176,110 @@ static void i915_error_puts(struct 
drm_i915_error_state_buf *e,
 #define err_printf(e, ...) i915_error_printf(e, __VA_ARGS__)
 #define err_puts(e, s) i915_error_puts(e, s)
 
+#ifdef CONFIG_DRM_I915_COMPRESS_ERROR
+
+static bool compress_init(struct z_stream_s *zstream)
+{
+   memset(zstream, 0, sizeof(*zstream));
+
+   zstream->workspace =
+   kmalloc(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL),
+   GFP_ATOMIC | __GFP_NOWARN);
+   if (!zstream->workspace)
+   return NULL;
+
+   if (zlib_deflateInit(zstream, Z_DEFAULT_COMPRESSION) != Z_OK) {
+   kfree(zstream->workspace);
+   return false;
+   }
+
+   return true;
+}
+
+static int compress_page(struct z_stream_s *zstream,
+void *src,
+struct drm_i915_error_object *dst)
+{
+   zstream->next_in = src;
+   zstream->avail_in = PAGE_SIZE;
+
+   do {
+   if (zstream->avail_out == 0) {
+   unsigned long page;
+
+   page = __get_free_page(GFP_ATOMIC | __GFP_NOWARN);
+   if (!page)
+   return -ENOMEM;
+
+   dst->pages[dst->page_count++] = (void *)page;
+
+   zstream->next_out = (void *)page;
+   zstream->avail_out = PAGE_SIZE;
+   }
+
+   if (zlib_deflate(zstream, Z_SYNC_FLUSH) != Z_OK)
+   return -EIO;
+
+   /* Fallback to uncompressed if we increase size? */
+   if (0 && zstream->total_out > zstream->total_in)
+   return -E2BIG;
+   } while (zstream->avail_in);
+
+   return 0;
+}
+
+static void compress_fini(struct z_stream_s *zstream,
+ struct drm_i915_error_object *dst)
+{
+   if (dst) {
+   zlib_deflate(zstream, Z_FINISH);
+   dst->unused = zstream->avail_out;
+   }
+
+   zlib_deflateEnd(zstream);
+   kfree(zstream->workspace);
+}
+
+static void err_compression_marker(struct drm_i915_error_state_buf *m)
+{
+   err_puts(m, ":");
+}
+
+#else
+
+static bool compress_init(struct z_stream_s *zstream)
+{
+   return true;
+}
+
+static int compress_page(struct z_stream_s *zstream,
+void *src,
+struct drm_i915_error_object *dst)
+{
+   unsigned long page;
+
+   page = __get_free_page(GFP_ATOMIC | __GFP_NOWARN);
+   if (!page)
+   return -ENOMEM;
+
+