#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/slab.h>
+#include <asm/atomic.h>
#include <asm/spu.h>
#include <asm/spu_csa.h>
#include "spufs.h"
+
+atomic_t nr_spu_contexts = ATOMIC_INIT(0);
+
struct spu_context *alloc_spu_context(struct spu_gang *gang)
{
struct spu_context *ctx;
if (spu_init_csa(&ctx->csa))
goto out_free;
spin_lock_init(&ctx->mmio_lock);
- spin_lock_init(&ctx->mapping_lock);
+ mutex_init(&ctx->mapping_lock);
kref_init(&ctx->kref);
mutex_init(&ctx->state_mutex);
mutex_init(&ctx->run_mutex);
INIT_LIST_HEAD(&ctx->rq);
if (gang)
spu_gang_add_ctx(gang, ctx);
- ctx->rt_priority = current->rt_priority;
- ctx->policy = current->policy;
- ctx->prio = current->prio;
- INIT_DELAYED_WORK(&ctx->sched_work, spu_sched_tick);
+ ctx->cpus_allowed = current->cpus_allowed;
+ spu_set_timeslice(ctx);
+ ctx->stats.util_state = SPU_UTIL_IDLE_LOADED;
+
+ atomic_inc(&nr_spu_contexts);
goto out;
out_free:
kfree(ctx);
if (ctx->gang)
spu_gang_remove_ctx(ctx->gang, ctx);
BUG_ON(!list_empty(&ctx->rq));
+ atomic_dec(&nr_spu_contexts);
kfree(ctx);
}
void spu_unmap_mappings(struct spu_context *ctx)
{
+ mutex_lock(&ctx->mapping_lock);
if (ctx->local_store)
unmap_mapping_range(ctx->local_store, 0, LS_SIZE, 1);
if (ctx->mfc)
unmap_mapping_range(ctx->mss, 0, 0x1000, 1);
if (ctx->psmap)
unmap_mapping_range(ctx->psmap, 0, 0x20000, 1);
+ mutex_unlock(&ctx->mapping_lock);
}
/**
void spu_acquire_saved(struct spu_context *ctx)
{
spu_acquire(ctx);
- if (ctx->state != SPU_STATE_SAVED)
+ if (ctx->state != SPU_STATE_SAVED) {
+ set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags);
spu_deactivate(ctx);
+ }
+}
+
+/**
+ * spu_release_saved - unlock spu context and return it to the runqueue
+ * @ctx: context to unlock
+ */
+void spu_release_saved(struct spu_context *ctx)
+{
+ BUG_ON(ctx->state != SPU_STATE_SAVED);
+
+ if (test_and_clear_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags))
+ spu_activate(ctx, 0);
+
+ spu_release(ctx);
}