brintos

brintos / linux-shallow public Read only

0
0
Text · 2.0 KiB · 0e668fc Raw
103 lines · c
1// SPDX-License-Identifier: GPL-2.0 OR MIT2/* Copyright 2018-2019 Qiang Yu <yuq825@gmail.com> */3 4#include <linux/pid.h>5#include <linux/slab.h>6 7#include "lima_device.h"8#include "lima_ctx.h"9 10int lima_ctx_create(struct lima_device *dev, struct lima_ctx_mgr *mgr, u32 *id)11{12	struct lima_ctx *ctx;13	int i, err;14 15	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);16	if (!ctx)17		return -ENOMEM;18	ctx->dev = dev;19	kref_init(&ctx->refcnt);20 21	for (i = 0; i < lima_pipe_num; i++) {22		err = lima_sched_context_init(dev->pipe + i, ctx->context + i);23		if (err)24			goto err_out0;25	}26 27	err = xa_alloc(&mgr->handles, id, ctx, xa_limit_32b, GFP_KERNEL);28	if (err < 0)29		goto err_out0;30 31	ctx->pid = task_pid_nr(current);32	get_task_comm(ctx->pname, current);33 34	return 0;35 36err_out0:37	for (i--; i >= 0; i--)38		lima_sched_context_fini(dev->pipe + i, ctx->context + i);39	kfree(ctx);40	return err;41}42 43static void lima_ctx_do_release(struct kref *ref)44{45	struct lima_ctx *ctx = container_of(ref, struct lima_ctx, refcnt);46	int i;47 48	for (i = 0; i < lima_pipe_num; i++)49		lima_sched_context_fini(ctx->dev->pipe + i, ctx->context + i);50	kfree(ctx);51}52 53int lima_ctx_free(struct lima_ctx_mgr *mgr, u32 id)54{55	struct lima_ctx *ctx;56	int ret = 0;57 58	mutex_lock(&mgr->lock);59	ctx = xa_erase(&mgr->handles, id);60	if (ctx)61		kref_put(&ctx->refcnt, lima_ctx_do_release);62	else63		ret = -EINVAL;64	mutex_unlock(&mgr->lock);65	return ret;66}67 68struct lima_ctx *lima_ctx_get(struct lima_ctx_mgr *mgr, u32 id)69{70	struct lima_ctx *ctx;71 72	mutex_lock(&mgr->lock);73	ctx = xa_load(&mgr->handles, id);74	if (ctx)75		kref_get(&ctx->refcnt);76	mutex_unlock(&mgr->lock);77	return ctx;78}79 80void lima_ctx_put(struct lima_ctx *ctx)81{82	kref_put(&ctx->refcnt, lima_ctx_do_release);83}84 85void lima_ctx_mgr_init(struct lima_ctx_mgr *mgr)86{87	mutex_init(&mgr->lock);88	xa_init_flags(&mgr->handles, XA_FLAGS_ALLOC);89}90 91void lima_ctx_mgr_fini(struct lima_ctx_mgr *mgr)92{93	struct lima_ctx *ctx;94	unsigned long id;95 96	xa_for_each(&mgr->handles, id, ctx) {97		kref_put(&ctx->refcnt, lima_ctx_do_release);98	}99 100	xa_destroy(&mgr->handles);101	mutex_destroy(&mgr->lock);102}103