Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0 OR MIT
0002 /* Copyright 2018-2019 Qiang Yu <yuq825@gmail.com> */
0003 
0004 #include <linux/slab.h>
0005 
0006 #include "lima_device.h"
0007 #include "lima_ctx.h"
0008 
0009 int lima_ctx_create(struct lima_device *dev, struct lima_ctx_mgr *mgr, u32 *id)
0010 {
0011     struct lima_ctx *ctx;
0012     int i, err;
0013 
0014     ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
0015     if (!ctx)
0016         return -ENOMEM;
0017     ctx->dev = dev;
0018     kref_init(&ctx->refcnt);
0019 
0020     for (i = 0; i < lima_pipe_num; i++) {
0021         err = lima_sched_context_init(dev->pipe + i, ctx->context + i, &ctx->guilty);
0022         if (err)
0023             goto err_out0;
0024     }
0025 
0026     err = xa_alloc(&mgr->handles, id, ctx, xa_limit_32b, GFP_KERNEL);
0027     if (err < 0)
0028         goto err_out0;
0029 
0030     ctx->pid = task_pid_nr(current);
0031     get_task_comm(ctx->pname, current);
0032 
0033     return 0;
0034 
0035 err_out0:
0036     for (i--; i >= 0; i--)
0037         lima_sched_context_fini(dev->pipe + i, ctx->context + i);
0038     kfree(ctx);
0039     return err;
0040 }
0041 
0042 static void lima_ctx_do_release(struct kref *ref)
0043 {
0044     struct lima_ctx *ctx = container_of(ref, struct lima_ctx, refcnt);
0045     int i;
0046 
0047     for (i = 0; i < lima_pipe_num; i++)
0048         lima_sched_context_fini(ctx->dev->pipe + i, ctx->context + i);
0049     kfree(ctx);
0050 }
0051 
0052 int lima_ctx_free(struct lima_ctx_mgr *mgr, u32 id)
0053 {
0054     struct lima_ctx *ctx;
0055     int ret = 0;
0056 
0057     mutex_lock(&mgr->lock);
0058     ctx = xa_erase(&mgr->handles, id);
0059     if (ctx)
0060         kref_put(&ctx->refcnt, lima_ctx_do_release);
0061     else
0062         ret = -EINVAL;
0063     mutex_unlock(&mgr->lock);
0064     return ret;
0065 }
0066 
0067 struct lima_ctx *lima_ctx_get(struct lima_ctx_mgr *mgr, u32 id)
0068 {
0069     struct lima_ctx *ctx;
0070 
0071     mutex_lock(&mgr->lock);
0072     ctx = xa_load(&mgr->handles, id);
0073     if (ctx)
0074         kref_get(&ctx->refcnt);
0075     mutex_unlock(&mgr->lock);
0076     return ctx;
0077 }
0078 
0079 void lima_ctx_put(struct lima_ctx *ctx)
0080 {
0081     kref_put(&ctx->refcnt, lima_ctx_do_release);
0082 }
0083 
0084 void lima_ctx_mgr_init(struct lima_ctx_mgr *mgr)
0085 {
0086     mutex_init(&mgr->lock);
0087     xa_init_flags(&mgr->handles, XA_FLAGS_ALLOC);
0088 }
0089 
0090 void lima_ctx_mgr_fini(struct lima_ctx_mgr *mgr)
0091 {
0092     struct lima_ctx *ctx;
0093     unsigned long id;
0094 
0095     xa_for_each(&mgr->handles, id, ctx) {
0096         kref_put(&ctx->refcnt, lima_ctx_do_release);
0097     }
0098 
0099     xa_destroy(&mgr->handles);
0100     mutex_destroy(&mgr->lock);
0101 }