xref: /OK3568_Linux_fs/kernel/arch/powerpc/platforms/cell/spufs/gang.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * SPU file system
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Author: Arnd Bergmann <arndb@de.ibm.com>
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <linux/list.h>
11*4882a593Smuzhiyun #include <linux/slab.h>
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #include "spufs.h"
14*4882a593Smuzhiyun 
alloc_spu_gang(void)15*4882a593Smuzhiyun struct spu_gang *alloc_spu_gang(void)
16*4882a593Smuzhiyun {
17*4882a593Smuzhiyun 	struct spu_gang *gang;
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun 	gang = kzalloc(sizeof *gang, GFP_KERNEL);
20*4882a593Smuzhiyun 	if (!gang)
21*4882a593Smuzhiyun 		goto out;
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun 	kref_init(&gang->kref);
24*4882a593Smuzhiyun 	mutex_init(&gang->mutex);
25*4882a593Smuzhiyun 	mutex_init(&gang->aff_mutex);
26*4882a593Smuzhiyun 	INIT_LIST_HEAD(&gang->list);
27*4882a593Smuzhiyun 	INIT_LIST_HEAD(&gang->aff_list_head);
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun out:
30*4882a593Smuzhiyun 	return gang;
31*4882a593Smuzhiyun }
32*4882a593Smuzhiyun 
destroy_spu_gang(struct kref * kref)33*4882a593Smuzhiyun static void destroy_spu_gang(struct kref *kref)
34*4882a593Smuzhiyun {
35*4882a593Smuzhiyun 	struct spu_gang *gang;
36*4882a593Smuzhiyun 	gang = container_of(kref, struct spu_gang, kref);
37*4882a593Smuzhiyun 	WARN_ON(gang->contexts || !list_empty(&gang->list));
38*4882a593Smuzhiyun 	kfree(gang);
39*4882a593Smuzhiyun }
40*4882a593Smuzhiyun 
get_spu_gang(struct spu_gang * gang)41*4882a593Smuzhiyun struct spu_gang *get_spu_gang(struct spu_gang *gang)
42*4882a593Smuzhiyun {
43*4882a593Smuzhiyun 	kref_get(&gang->kref);
44*4882a593Smuzhiyun 	return gang;
45*4882a593Smuzhiyun }
46*4882a593Smuzhiyun 
put_spu_gang(struct spu_gang * gang)47*4882a593Smuzhiyun int put_spu_gang(struct spu_gang *gang)
48*4882a593Smuzhiyun {
49*4882a593Smuzhiyun 	return kref_put(&gang->kref, &destroy_spu_gang);
50*4882a593Smuzhiyun }
51*4882a593Smuzhiyun 
spu_gang_add_ctx(struct spu_gang * gang,struct spu_context * ctx)52*4882a593Smuzhiyun void spu_gang_add_ctx(struct spu_gang *gang, struct spu_context *ctx)
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun 	mutex_lock(&gang->mutex);
55*4882a593Smuzhiyun 	ctx->gang = get_spu_gang(gang);
56*4882a593Smuzhiyun 	list_add(&ctx->gang_list, &gang->list);
57*4882a593Smuzhiyun 	gang->contexts++;
58*4882a593Smuzhiyun 	mutex_unlock(&gang->mutex);
59*4882a593Smuzhiyun }
60*4882a593Smuzhiyun 
spu_gang_remove_ctx(struct spu_gang * gang,struct spu_context * ctx)61*4882a593Smuzhiyun void spu_gang_remove_ctx(struct spu_gang *gang, struct spu_context *ctx)
62*4882a593Smuzhiyun {
63*4882a593Smuzhiyun 	mutex_lock(&gang->mutex);
64*4882a593Smuzhiyun 	WARN_ON(ctx->gang != gang);
65*4882a593Smuzhiyun 	if (!list_empty(&ctx->aff_list)) {
66*4882a593Smuzhiyun 		list_del_init(&ctx->aff_list);
67*4882a593Smuzhiyun 		gang->aff_flags &= ~AFF_OFFSETS_SET;
68*4882a593Smuzhiyun 	}
69*4882a593Smuzhiyun 	list_del_init(&ctx->gang_list);
70*4882a593Smuzhiyun 	gang->contexts--;
71*4882a593Smuzhiyun 	mutex_unlock(&gang->mutex);
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun 	put_spu_gang(gang);
74*4882a593Smuzhiyun }
75