radeonsi: stop reporting reset to app once gpu recovery is done

This way apps know they can recreate their contexts when
the status go back to NO_ERROR.

This depends on new UAPI in the kernel; for older kernel, radeonsi
will stop reporting a reset after 3 seconds. Apps will be able to
create new contexts but they'll have to handle not being able to
submit tasks.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/7460
Reviewed-by: André Almeida <andrealmeid@igalia.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22290>
This commit is contained in:
Pierre-Eric Pelloux-Prayer
2023-04-07 09:48:02 +02:00
committed by Marge Bot
parent 5022531120
commit e528823400
7 changed files with 38 additions and 12 deletions
+1 -1
View File
@@ -489,7 +489,7 @@ static enum pipe_reset_status r600_get_reset_status(struct pipe_context *ctx)
{
struct r600_common_context *rctx = (struct r600_common_context *)ctx;
return rctx->ws->ctx_query_reset_status(rctx->ctx, false, NULL);
return rctx->ws->ctx_query_reset_status(rctx->ctx, false, NULL, NULL);
}
static void r600_set_debug_callback(struct pipe_context *ctx,
+1 -1
View File
@@ -80,7 +80,7 @@ void si_flush_gfx_cs(struct si_context *ctx, unsigned flags, struct pipe_fence_h
* while si_get_reset_status can't. */
if (!(ctx->context_flags & SI_CONTEXT_FLAG_AUX) &&
ctx->device_reset_callback.reset) {
enum pipe_reset_status status = ctx->ws->ctx_query_reset_status(ctx->ctx, true, NULL);
enum pipe_reset_status status = ctx->ws->ctx_query_reset_status(ctx->ctx, true, NULL, NULL);
if (status != PIPE_NO_RESET)
ctx->device_reset_callback.reset(ctx->device_reset_callback.data, status);
}
+14 -7
View File
@@ -385,13 +385,20 @@ static enum pipe_reset_status si_get_reset_status(struct pipe_context *ctx)
if (sctx->context_flags & SI_CONTEXT_FLAG_AUX)
return PIPE_NO_RESET;
bool needs_reset;
enum pipe_reset_status status = sctx->ws->ctx_query_reset_status(sctx->ctx, false, &needs_reset);
bool needs_reset, reset_completed;
enum pipe_reset_status status = sctx->ws->ctx_query_reset_status(sctx->ctx, false,
&needs_reset, &reset_completed);
if (status != PIPE_NO_RESET && needs_reset && !(sctx->context_flags & SI_CONTEXT_FLAG_AUX)) {
/* Call the gallium frontend to set a no-op API dispatch. */
if (sctx->device_reset_callback.reset) {
sctx->device_reset_callback.reset(sctx->device_reset_callback.data, status);
if (status != PIPE_NO_RESET) {
if (sctx->has_reset_been_notified && reset_completed)
return PIPE_NO_RESET;
sctx->has_reset_been_notified = true;
if (!(sctx->context_flags & SI_CONTEXT_FLAG_AUX)) {
/* Call the gallium frontend to set a no-op API dispatch. */
if (needs_reset && sctx->device_reset_callback.reset)
sctx->device_reset_callback.reset(sctx->device_reset_callback.data, status);
}
}
return status;
@@ -818,7 +825,7 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen, unsign
struct si_context *saux = si_get_aux_context(sscreen);
enum pipe_reset_status status = sctx->ws->ctx_query_reset_status(
saux->ctx, true, NULL);
saux->ctx, true, NULL, NULL);
if (status != PIPE_NO_RESET) {
/* We lost the aux_context, create a new one */
struct u_log_context *aux_log = (saux)->log;
+1
View File
@@ -1218,6 +1218,7 @@ struct si_context {
bool dpbb_force_off_profile_ps;
bool vs_writes_viewport_index;
bool vs_disables_clipping_viewport;
bool has_reset_been_notified;
/* Precomputed IA_MULTI_VGT_PARAM */
union si_vgt_param_key ia_multi_vgt_param_key;
+1 -1
View File
@@ -527,7 +527,7 @@ struct radeon_winsys {
*/
enum pipe_reset_status (*ctx_query_reset_status)(struct radeon_winsys_ctx *ctx,
bool full_reset_only,
bool *needs_reset);
bool *needs_reset, bool *reset_completed);
/**
* Create a command stream.
+15 -1
View File
@@ -349,13 +349,15 @@ static void amdgpu_ctx_destroy(struct radeon_winsys_ctx *rwctx)
static enum pipe_reset_status
amdgpu_ctx_query_reset_status(struct radeon_winsys_ctx *rwctx, bool full_reset_only,
bool *needs_reset)
bool *needs_reset, bool *reset_completed)
{
struct amdgpu_ctx *ctx = (struct amdgpu_ctx*)rwctx;
int r;
if (needs_reset)
*needs_reset = false;
if (reset_completed)
*reset_completed = false;
/* Return a failure due to a GPU hang. */
if (ctx->ws->info.drm_minor >= 24) {
@@ -376,6 +378,18 @@ amdgpu_ctx_query_reset_status(struct radeon_winsys_ctx *rwctx, bool full_reset_o
}
if (flags & AMDGPU_CTX_QUERY2_FLAGS_RESET) {
if (reset_completed) {
/* The ARB_robustness spec says:
*
* If a reset status other than NO_ERROR is returned and subsequent
* calls return NO_ERROR, the context reset was encountered and
* completed. If a reset status is repeatedly returned, the context may
* be in the process of resetting.
*
*/
if (!(flags & AMDGPU_CTX_QUERY2_FLAGS_RESET_IN_PROGRESS))
*reset_completed = true;
}
if (needs_reset)
*needs_reset = flags & AMDGPU_CTX_QUERY2_FLAGS_VRAMLOST;
if (flags & AMDGPU_CTX_QUERY2_FLAGS_GUILTY)
@@ -89,7 +89,7 @@ static void radeon_drm_ctx_destroy(struct radeon_winsys_ctx *ctx)
static enum pipe_reset_status
radeon_drm_ctx_query_reset_status(struct radeon_winsys_ctx *rctx, bool full_reset_only,
bool *needs_reset)
bool *needs_reset, bool *reset_completed)
{
struct radeon_ctx *ctx = (struct radeon_ctx*)rctx;
@@ -98,11 +98,15 @@ radeon_drm_ctx_query_reset_status(struct radeon_winsys_ctx *rctx, bool full_rese
if (ctx->gpu_reset_counter == latest) {
if (needs_reset)
*needs_reset = false;
if (reset_completed)
*reset_completed = false;
return PIPE_NO_RESET;
}
if (needs_reset)
*needs_reset = true;
if (reset_completed)
*reset_completed = true;
ctx->gpu_reset_counter = latest;
return PIPE_UNKNOWN_CONTEXT_RESET;