e721d1cc81
Marking the context as guilty currently only makes the application which hits a single timeout problem to stop its rendering context entirely. All jobs submitted later are dropped from the guilty context. Lima runs on fairly underpowered hardware for modern standards and it is not entirely unreasonable that a rendering job may time out occasionally due to high system load or too demanding application stack. In this case it would be generally preferred to report the error but try to keep the application going. Other similar embedded GPU drivers don't make use of the guilty context flag. Now that there are reliability improvements to the lima timeout recovery handling, drop the guilty contexts to let the application keep running in this case. Signed-off-by: Erico Nunes <nunes.erico@gmail.com> Acked-by: Christian König <christian.koenig@amd.com> Reviewed-by: Vasily Khoruzhick <anarsoul@gmail.com> Signed-off-by: Qiang Yu <yuq825@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240124025947.2110659-7-nunes.erico@gmail.com
103 lines
2.0 KiB
C
103 lines
2.0 KiB
C
// SPDX-License-Identifier: GPL-2.0 OR MIT
|
|
/* Copyright 2018-2019 Qiang Yu <yuq825@gmail.com> */
|
|
|
|
#include <linux/pid.h>
|
|
#include <linux/slab.h>
|
|
|
|
#include "lima_device.h"
|
|
#include "lima_ctx.h"
|
|
|
|
int lima_ctx_create(struct lima_device *dev, struct lima_ctx_mgr *mgr, u32 *id)
|
|
{
|
|
struct lima_ctx *ctx;
|
|
int i, err;
|
|
|
|
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
|
|
if (!ctx)
|
|
return -ENOMEM;
|
|
ctx->dev = dev;
|
|
kref_init(&ctx->refcnt);
|
|
|
|
for (i = 0; i < lima_pipe_num; i++) {
|
|
err = lima_sched_context_init(dev->pipe + i, ctx->context + i);
|
|
if (err)
|
|
goto err_out0;
|
|
}
|
|
|
|
err = xa_alloc(&mgr->handles, id, ctx, xa_limit_32b, GFP_KERNEL);
|
|
if (err < 0)
|
|
goto err_out0;
|
|
|
|
ctx->pid = task_pid_nr(current);
|
|
get_task_comm(ctx->pname, current);
|
|
|
|
return 0;
|
|
|
|
err_out0:
|
|
for (i--; i >= 0; i--)
|
|
lima_sched_context_fini(dev->pipe + i, ctx->context + i);
|
|
kfree(ctx);
|
|
return err;
|
|
}
|
|
|
|
static void lima_ctx_do_release(struct kref *ref)
|
|
{
|
|
struct lima_ctx *ctx = container_of(ref, struct lima_ctx, refcnt);
|
|
int i;
|
|
|
|
for (i = 0; i < lima_pipe_num; i++)
|
|
lima_sched_context_fini(ctx->dev->pipe + i, ctx->context + i);
|
|
kfree(ctx);
|
|
}
|
|
|
|
int lima_ctx_free(struct lima_ctx_mgr *mgr, u32 id)
|
|
{
|
|
struct lima_ctx *ctx;
|
|
int ret = 0;
|
|
|
|
mutex_lock(&mgr->lock);
|
|
ctx = xa_erase(&mgr->handles, id);
|
|
if (ctx)
|
|
kref_put(&ctx->refcnt, lima_ctx_do_release);
|
|
else
|
|
ret = -EINVAL;
|
|
mutex_unlock(&mgr->lock);
|
|
return ret;
|
|
}
|
|
|
|
struct lima_ctx *lima_ctx_get(struct lima_ctx_mgr *mgr, u32 id)
|
|
{
|
|
struct lima_ctx *ctx;
|
|
|
|
mutex_lock(&mgr->lock);
|
|
ctx = xa_load(&mgr->handles, id);
|
|
if (ctx)
|
|
kref_get(&ctx->refcnt);
|
|
mutex_unlock(&mgr->lock);
|
|
return ctx;
|
|
}
|
|
|
|
void lima_ctx_put(struct lima_ctx *ctx)
|
|
{
|
|
kref_put(&ctx->refcnt, lima_ctx_do_release);
|
|
}
|
|
|
|
void lima_ctx_mgr_init(struct lima_ctx_mgr *mgr)
|
|
{
|
|
mutex_init(&mgr->lock);
|
|
xa_init_flags(&mgr->handles, XA_FLAGS_ALLOC);
|
|
}
|
|
|
|
void lima_ctx_mgr_fini(struct lima_ctx_mgr *mgr)
|
|
{
|
|
struct lima_ctx *ctx;
|
|
unsigned long id;
|
|
|
|
xa_for_each(&mgr->handles, id, ctx) {
|
|
kref_put(&ctx->refcnt, lima_ctx_do_release);
|
|
}
|
|
|
|
xa_destroy(&mgr->handles);
|
|
mutex_destroy(&mgr->lock);
|
|
}
|