[Mesa-dev] [PATCH v2 5/6] gallium/radeon: implement set_device_reset_callback

Marek Olšák maraeo at gmail.com
Tue Oct 4 13:23:46 UTC 2016


For the series:

Reviewed-by: Marek Olšák <marek.olsak at amd.com>

Marek

On Tue, Oct 4, 2016 at 10:11 AM, Nicolai Hähnle <nhaehnle at gmail.com> wrote:
> From: Nicolai Hähnle <nicolai.haehnle at amd.com>
>
> Check for device reset on flush. It would be nicer if the kernel just
> reported this as an error on the submit ioctl (and similarly for fences),
> but this will do for now.
> ---
>  src/gallium/drivers/r600/r600_hw_context.c    |  3 +++
>  src/gallium/drivers/radeon/r600_pipe_common.c | 32 +++++++++++++++++++++++++++
>  src/gallium/drivers/radeon/r600_pipe_common.h |  2 ++
>  src/gallium/drivers/radeonsi/si_hw_context.c  |  3 +++
>  4 files changed, 40 insertions(+)
>
> diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c
> index dc5ad75..bc6217a 100644
> --- a/src/gallium/drivers/r600/r600_hw_context.c
> +++ b/src/gallium/drivers/r600/r600_hw_context.c
> @@ -251,20 +251,23 @@ void r600_flush_emit(struct r600_context *rctx)
>  void r600_context_gfx_flush(void *context, unsigned flags,
>                             struct pipe_fence_handle **fence)
>  {
>         struct r600_context *ctx = context;
>         struct radeon_winsys_cs *cs = ctx->b.gfx.cs;
>         struct radeon_winsys *ws = ctx->b.ws;
>
>         if (!radeon_emitted(cs, ctx->b.initial_gfx_cs_size))
>                 return;
>
> +       if (r600_check_device_reset(&ctx->b))
> +               return;
> +
>         r600_preflush_suspend_features(&ctx->b);
>
>         /* flush the framebuffer cache */
>         ctx->b.flags |= R600_CONTEXT_FLUSH_AND_INV |
>                       R600_CONTEXT_FLUSH_AND_INV_CB |
>                       R600_CONTEXT_FLUSH_AND_INV_DB |
>                       R600_CONTEXT_FLUSH_AND_INV_CB_META |
>                       R600_CONTEXT_FLUSH_AND_INV_DB_META |
>                       R600_CONTEXT_WAIT_3D_IDLE |
>                       R600_CONTEXT_WAIT_CP_DMA_IDLE;
> diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c
> index 95950c3..4e94e07 100644
> --- a/src/gallium/drivers/radeon/r600_pipe_common.c
> +++ b/src/gallium/drivers/radeon/r600_pipe_common.c
> @@ -477,20 +477,50 @@ static void r600_set_debug_callback(struct pipe_context *ctx,
>                                     const struct pipe_debug_callback *cb)
>  {
>         struct r600_common_context *rctx = (struct r600_common_context *)ctx;
>
>         if (cb)
>                 rctx->debug = *cb;
>         else
>                 memset(&rctx->debug, 0, sizeof(rctx->debug));
>  }
>
> +static void r600_set_device_reset_callback(struct pipe_context *ctx,
> +                                          const struct pipe_device_reset_callback *cb)
> +{
> +       struct r600_common_context *rctx = (struct r600_common_context *)ctx;
> +
> +       if (cb)
> +               rctx->device_reset_callback = *cb;
> +       else
> +               memset(&rctx->device_reset_callback, 0,
> +                      sizeof(rctx->device_reset_callback));
> +}
> +
> +bool r600_check_device_reset(struct r600_common_context *rctx)
> +{
> +       enum pipe_reset_status status;
> +
> +       if (!rctx->device_reset_callback.reset)
> +               return false;
> +
> +       if (!rctx->b.get_device_reset_status)
> +               return false;
> +
> +       status = rctx->b.get_device_reset_status(&rctx->b);
> +       if (status == PIPE_NO_RESET)
> +               return false;
> +
> +       rctx->device_reset_callback.reset(rctx->device_reset_callback.data, status);
> +       return true;
> +}
> +
>  bool r600_common_context_init(struct r600_common_context *rctx,
>                               struct r600_common_screen *rscreen,
>                               unsigned context_flags)
>  {
>         slab_create(&rctx->pool_transfers,
>                          sizeof(struct r600_transfer), 64);
>
>         rctx->screen = rscreen;
>         rctx->ws = rscreen->ws;
>         rctx->family = rscreen->family;
> @@ -521,20 +551,22 @@ bool r600_common_context_init(struct r600_common_context *rctx,
>         else
>                 rctx->b.buffer_subdata = r600_buffer_subdata;
>
>         if (rscreen->info.drm_major == 2 && rscreen->info.drm_minor >= 43) {
>                 rctx->b.get_device_reset_status = r600_get_reset_status;
>                 rctx->gpu_reset_counter =
>                         rctx->ws->query_value(rctx->ws,
>                                               RADEON_GPU_RESET_COUNTER);
>         }
>
> +       rctx->b.set_device_reset_callback = r600_set_device_reset_callback;
> +
>         LIST_INITHEAD(&rctx->texture_buffers);
>
>         r600_init_context_texture_functions(rctx);
>         r600_init_viewport_functions(rctx);
>         r600_streamout_init(rctx);
>         r600_query_init(rctx);
>         cayman_init_msaa(&rctx->b);
>
>         rctx->allocator_zeroed_memory =
>                 u_suballocator_create(&rctx->b, rscreen->info.gart_page_size,
> diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
> index c6669cc..d6b6664 100644
> --- a/src/gallium/drivers/radeon/r600_pipe_common.h
> +++ b/src/gallium/drivers/radeon/r600_pipe_common.h
> @@ -613,20 +613,21 @@ struct r600_common_context {
>                 int64_t                         last_use_timestamp;
>                 bool                            query_active;
>         } dcc_stats[5];
>
>         /* The list of all texture buffer objects in this context.
>          * This list is walked when a buffer is invalidated/reallocated and
>          * the GPU addresses are updated. */
>         struct list_head                texture_buffers;
>
>         struct pipe_debug_callback      debug;
> +       struct pipe_device_reset_callback device_reset_callback;
>
>         void                            *query_result_shader;
>
>         /* Copy one resource to another using async DMA. */
>         void (*dma_copy)(struct pipe_context *ctx,
>                          struct pipe_resource *dst,
>                          unsigned dst_level,
>                          unsigned dst_x, unsigned dst_y, unsigned dst_z,
>                          struct pipe_resource *src,
>                          unsigned src_level,
> @@ -726,20 +727,21 @@ void r600_screen_clear_buffer(struct r600_common_screen *rscreen, struct pipe_re
>                               enum r600_coherency coher);
>  struct pipe_resource *r600_resource_create_common(struct pipe_screen *screen,
>                                                   const struct pipe_resource *templ);
>  const char *r600_get_llvm_processor_name(enum radeon_family family);
>  void r600_need_dma_space(struct r600_common_context *ctx, unsigned num_dw,
>                          struct r600_resource *dst, struct r600_resource *src);
>  void r600_dma_emit_wait_idle(struct r600_common_context *rctx);
>  void radeon_save_cs(struct radeon_winsys *ws, struct radeon_winsys_cs *cs,
>                     struct radeon_saved_cs *saved);
>  void radeon_clear_saved_cs(struct radeon_saved_cs *saved);
> +bool r600_check_device_reset(struct r600_common_context *rctx);
>
>  /* r600_gpu_load.c */
>  void r600_gpu_load_kill_thread(struct r600_common_screen *rscreen);
>  uint64_t r600_gpu_load_begin(struct r600_common_screen *rscreen);
>  unsigned r600_gpu_load_end(struct r600_common_screen *rscreen, uint64_t begin);
>
>  /* r600_perfcounters.c */
>  void r600_perfcounters_destroy(struct r600_common_screen *rscreen);
>
>  /* r600_query.c */
> diff --git a/src/gallium/drivers/radeonsi/si_hw_context.c b/src/gallium/drivers/radeonsi/si_hw_context.c
> index 67e8352..7d851b8 100644
> --- a/src/gallium/drivers/radeonsi/si_hw_context.c
> +++ b/src/gallium/drivers/radeonsi/si_hw_context.c
> @@ -96,20 +96,23 @@ void si_context_gfx_flush(void *context, unsigned flags,
>         struct si_context *ctx = context;
>         struct radeon_winsys_cs *cs = ctx->b.gfx.cs;
>         struct radeon_winsys *ws = ctx->b.ws;
>
>         if (ctx->gfx_flush_in_progress)
>                 return;
>
>         if (!radeon_emitted(cs, ctx->b.initial_gfx_cs_size))
>                 return;
>
> +       if (r600_check_device_reset(&ctx->b))
> +               return;
> +
>         ctx->gfx_flush_in_progress = true;
>
>         r600_preflush_suspend_features(&ctx->b);
>
>         ctx->b.flags |= SI_CONTEXT_CS_PARTIAL_FLUSH |
>                         SI_CONTEXT_PS_PARTIAL_FLUSH;
>
>         /* DRM 3.1.0 doesn't flush TC for VI correctly. */
>         if (ctx->b.chip_class == VI && ctx->b.screen->info.drm_minor <= 1)
>                 ctx->b.flags |= SI_CONTEXT_INV_GLOBAL_L2 |
> --
> 2.7.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list