The kernel can do different types of recovery (soft recovery, GPU reset).
Since they both increase gpu_reset_counter, this will cause all contexts
to report AMDGPU_CTX_QUERY2_FLAGS_RESET, which is a bit misleading: if
a single context was soft-recovered, the others are fine and we don't need
special processing.
This commit uses the AMDGPU_CTX_QUERY2_FLAGS_VRAMLOST to distinguish
between the 2 kind of reset and later commits will use this information.
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10179>
{
struct r600_common_context *rctx = (struct r600_common_context *)ctx;
- return rctx->ws->ctx_query_reset_status(rctx->ctx);
+ return rctx->ws->ctx_query_reset_status(rctx->ctx, NULL);
}
static void r600_set_debug_callback(struct pipe_context *ctx,
/**
* Query a GPU reset status.
*/
- enum pipe_reset_status (*ctx_query_reset_status)(struct radeon_winsys_ctx *ctx);
+ enum pipe_reset_status (*ctx_query_reset_status)(struct radeon_winsys_ctx *ctx,
+ bool *needs_reset);
/**
* Create a command stream.
{
struct si_context *sctx = (struct si_context *)ctx;
struct si_screen *sscreen = sctx->screen;
- enum pipe_reset_status status = sctx->ws->ctx_query_reset_status(sctx->ctx);
+ bool needs_reset;
+ enum pipe_reset_status status = sctx->ws->ctx_query_reset_status(sctx->ctx, &needs_reset);
if (status != PIPE_NO_RESET) {
/* Call the gallium frontend to set a no-op API dispatch. */
}
static enum pipe_reset_status
-amdgpu_ctx_query_reset_status(struct radeon_winsys_ctx *rwctx)
+amdgpu_ctx_query_reset_status(struct radeon_winsys_ctx *rwctx, bool *needs_reset)
{
struct amdgpu_ctx *ctx = (struct amdgpu_ctx*)rwctx;
int r;
+ if (needs_reset)
+ *needs_reset = false;
+
/* Return a failure due to a GPU hang. */
if (ctx->ws->info.drm_minor >= 24) {
uint64_t flags;
}
if (flags & AMDGPU_CTX_QUERY2_FLAGS_RESET) {
+ if (needs_reset)
+ *needs_reset = flags & AMDGPU_CTX_QUERY2_FLAGS_VRAMLOST;
if (flags & AMDGPU_CTX_QUERY2_FLAGS_GUILTY)
return PIPE_GUILTY_CONTEXT_RESET;
else
return PIPE_NO_RESET;
}
+ if (needs_reset)
+ *needs_reset = true;
switch (result) {
case AMDGPU_CTX_GUILTY_RESET:
return PIPE_GUILTY_CONTEXT_RESET;
/* Return a failure due to a rejected command submission. */
if (ctx->ws->num_total_rejected_cs > ctx->initial_num_total_rejected_cs) {
+ if (needs_reset)
+ *needs_reset = true;
return ctx->num_rejected_cs ? PIPE_GUILTY_CONTEXT_RESET :
PIPE_INNOCENT_CONTEXT_RESET;
}
+ if (needs_reset)
+ *needs_reset = false;
return PIPE_NO_RESET;
}
}
static enum pipe_reset_status
-radeon_drm_ctx_query_reset_status(struct radeon_winsys_ctx *rctx)
+radeon_drm_ctx_query_reset_status(struct radeon_winsys_ctx *rctx, bool *needs_reset)
{
struct radeon_ctx *ctx = (struct radeon_ctx*)rctx;
unsigned latest = radeon_drm_get_gpu_reset_counter(ctx->ws);
- if (ctx->gpu_reset_counter == latest)
+ if (ctx->gpu_reset_counter == latest) {
+ if (needs_reset)
+ *needs_reset = false;
return PIPE_NO_RESET;
+ }
+
+ if (needs_reset)
+ *needs_reset = true;
ctx->gpu_reset_counter = latest;
return PIPE_UNKNOWN_CONTEXT_RESET;