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*4882a593Smuzhiyunstruct 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*4882a593Smuzhiyunstatic 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*4882a593Smuzhiyunstruct 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*4882a593Smuzhiyunint 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*4882a593Smuzhiyunvoid 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*4882a593Smuzhiyunvoid 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