arch/powerpc/platforms/cell/spufs/context.c

Source file repositories/reference/linux-study-clean/arch/powerpc/platforms/cell/spufs/context.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/platforms/cell/spufs/context.c
Extension
.c
Size
4208 bytes
Lines
176
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * SPU file system -- SPU context management
 *
 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
 *
 * Author: Arnd Bergmann <arndb@de.ibm.com>
 */

#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/atomic.h>
#include <linux/sched.h>
#include <linux/sched/mm.h>

#include <asm/spu.h>
#include <asm/spu_csa.h>
#include "spufs.h"
#include "sputrace.h"


atomic_t nr_spu_contexts = ATOMIC_INIT(0);

struct spu_context *alloc_spu_context(struct spu_gang *gang)
{
	struct spu_context *ctx;

	ctx = kzalloc_obj(*ctx);
	if (!ctx)
		goto out;
	/* Binding to physical processor deferred
	 * until spu_activate().
	 */
	if (spu_init_csa(&ctx->csa))
		goto out_free;
	spin_lock_init(&ctx->mmio_lock);
	mutex_init(&ctx->mapping_lock);
	kref_init(&ctx->kref);
	mutex_init(&ctx->state_mutex);
	mutex_init(&ctx->run_mutex);
	init_waitqueue_head(&ctx->ibox_wq);
	init_waitqueue_head(&ctx->wbox_wq);
	init_waitqueue_head(&ctx->stop_wq);
	init_waitqueue_head(&ctx->mfc_wq);
	init_waitqueue_head(&ctx->run_wq);
	ctx->state = SPU_STATE_SAVED;
	ctx->ops = &spu_backing_ops;
	ctx->owner = get_task_mm(current);
	INIT_LIST_HEAD(&ctx->rq);
	INIT_LIST_HEAD(&ctx->aff_list);
	if (gang)
		spu_gang_add_ctx(gang, ctx);

	__spu_update_sched_info(ctx);
	spu_set_timeslice(ctx);
	ctx->stats.util_state = SPU_UTIL_IDLE_LOADED;
	ctx->stats.tstamp = ktime_get_ns();

	atomic_inc(&nr_spu_contexts);
	goto out;
out_free:
	kfree(ctx);
	ctx = NULL;
out:
	return ctx;
}

void destroy_spu_context(struct kref *kref)
{
	struct spu_context *ctx;
	ctx = container_of(kref, struct spu_context, kref);
	spu_context_nospu_trace(destroy_spu_context__enter, ctx);
	mutex_lock(&ctx->state_mutex);
	spu_deactivate(ctx);
	mutex_unlock(&ctx->state_mutex);
	spu_fini_csa(&ctx->csa);
	if (ctx->gang)
		spu_gang_remove_ctx(ctx->gang, ctx);
	if (ctx->prof_priv_kref)
		kref_put(ctx->prof_priv_kref, ctx->prof_priv_release);
	BUG_ON(!list_empty(&ctx->rq));
	atomic_dec(&nr_spu_contexts);
	kfree(ctx->switch_log);
	kfree(ctx);
}

struct spu_context * get_spu_context(struct spu_context *ctx)
{
	kref_get(&ctx->kref);

Annotation

Implementation Notes