[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