panfrost: Add get_device_reset_status() to the CSF backend

Panthor can report the group state, so let's provide a
get_device_reset_status() querying this state and turning it into a
pipe_reset_status status.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31868>
This commit is contained in:
Boris Brezillon
2024-10-28 11:15:55 +01:00
committed by Marge Bot
parent ff9907927f
commit 4eb3e865ce
3 changed files with 58 additions and 1 deletions
+54 -1
View File
@@ -512,6 +512,34 @@ csf_attach_sync_points(struct panfrost_batch *batch, uint32_t vm_sync_handle,
vm_sync_handle, vm_sync_signal_point, 0);
}
static void
update_reset_status(struct panfrost_context *ctx,
enum pipe_reset_status new_status)
{
switch (new_status) {
case PIPE_GUILTY_CONTEXT_RESET:
/* Guilty reset overrides everything. */
ctx->csf.reset_status = new_status;
break;
case PIPE_UNKNOWN_CONTEXT_RESET:
/* Preserve guilty reset, override otherwise. */
if (ctx->csf.reset_status != PIPE_GUILTY_CONTEXT_RESET)
ctx->csf.reset_status = new_status;
break;
case PIPE_INNOCENT_CONTEXT_RESET:
/* Preserve guilty/unknown resets, override otherwise. */
if (ctx->csf.reset_status != PIPE_GUILTY_CONTEXT_RESET &&
ctx->csf.reset_status != PIPE_UNKNOWN_CONTEXT_RESET)
ctx->csf.reset_status = new_status;
break;
case PIPE_NO_RESET:
break;
default:
assert(!"Invalid reset status");
break;
}
}
static void
csf_check_ctx_state_and_reinit(struct panfrost_context *ctx)
{
@@ -524,13 +552,17 @@ csf_check_ctx_state_and_reinit(struct panfrost_context *ctx)
ret = pan_kmod_ioctl(panfrost_device_fd(dev),
DRM_IOCTL_PANTHOR_GROUP_GET_STATE, &state);
if (ret) {
update_reset_status(ctx, PIPE_UNKNOWN_CONTEXT_RESET);
mesa_loge("DRM_IOCTL_PANTHOR_GROUP_GET_STATE failed (err=%d)", errno);
return;
}
/* Context is still usable. This was a transient error. */
if (state.state == 0)
if (!(state.state & (DRM_PANTHOR_GROUP_STATE_FATAL_FAULT |
DRM_PANTHOR_GROUP_STATE_TIMEDOUT))) {
update_reset_status(ctx, PIPE_NO_RESET);
return;
}
/* If the VM is unusable, we can't do much, as this is shared between all
* contexts, and restoring the VM state is non-trivial.
@@ -540,6 +572,14 @@ csf_check_ctx_state_and_reinit(struct panfrost_context *ctx)
assert(!"VM became unusable, we can't reset the context");
}
/* DRM_PANTHOR_GROUP_STATE_INNOCENT only exists since panthor 1.3, which
* means we consider all resets as guilty until that point, but that
* should be fine.
*/
update_reset_status(ctx, state.state & DRM_PANTHOR_GROUP_STATE_INNOCENT
? PIPE_INNOCENT_CONTEXT_RESET
: PIPE_GUILTY_CONTEXT_RESET);
panfrost_context_reinit(ctx);
}
@@ -1431,6 +1471,17 @@ get_panthor_group_priority(struct panfrost_context *ctx)
return PANTHOR_GROUP_PRIORITY_MEDIUM;
}
static enum pipe_reset_status
get_device_reset_status(struct pipe_context *pctx)
{
struct panfrost_context *ctx = pan_context(pctx);
enum pipe_reset_status reset_status = ctx->csf.reset_status;
/* Reset the status before returning. */
ctx->csf.reset_status = PIPE_NO_RESET;
return reset_status;
}
int
GENX(csf_init_context)(struct panfrost_context *ctx)
{
@@ -1576,6 +1627,8 @@ GENX(csf_init_context)(struct panfrost_context *ctx)
panfrost_bo_unreference(cs_bo);
ctx->csf.reset_status = PIPE_NO_RESET;
ctx->base.get_device_reset_status = get_device_reset_status;
ctx->csf.is_init = true;
return 0;
err_g_submit:
+2
View File
@@ -87,6 +87,8 @@ struct panfrost_csf_context {
struct panfrost_bo *desc_bo;
} heap;
enum pipe_reset_status reset_status;
/* Temporary geometry buffer. Used as a FIFO by the tiler. */
struct panfrost_bo *tmp_geom_bo;
@@ -676,6 +676,8 @@ panfrost_init_screen_caps(struct panfrost_screen *screen)
caps->texture_multisample = true;
caps->surface_sample_count = true;
caps->device_reset_status_query = dev->arch >= 10;
caps->sampler_view_target = true;
caps->clip_halfz = true;
caps->polygon_offset_clamp = true;