[Cbe-oss-dev] [PATCH 02/11] powerpc/spufs: Add gang structure for standalone ctxts
Andre Detsch
adetsch at br.ibm.com
Fri Sep 12 09:37:46 EST 2008
All contexts should have a gang structure to provide a common
data abstraction for scheduling. Standalone gangs are just gangs
of one.
Signed-off-by: Luke Browning <lukebrowning at us.ibm.com>
Signed-off-by: Andre Detsch <adetsch at br.ibm.com>
---
arch/powerpc/platforms/cell/spufs/context.c | 30 +++++++++++++++++++++-----
arch/powerpc/platforms/cell/spufs/inode.c | 16 ++++++++++++-
2 files changed, 38 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/platforms/cell/spufs/context.c
b/arch/powerpc/platforms/cell/spufs/context.c
index 6653ddb..ace2273 100644
--- a/arch/powerpc/platforms/cell/spufs/context.c
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -35,14 +35,28 @@ atomic_t nr_spu_contexts = ATOMIC_INIT(0);
struct spu_context *alloc_spu_context(struct spu_gang *gang)
{
struct spu_context *ctx;
+
ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
if (!ctx)
goto out;
+
+ /* Allocate an anonymous gang if the caller did not explicitly
+ * create one so that a common data abstraction exists for
+ * the scheduler. Gangs are queued to the runqueue. In this case,
+ * the gang is a gang of one.
+ */
+ if (!gang) {
+ gang = alloc_spu_gang();
+ if (!gang)
+ goto out_free;
+ }
+
/* Binding to physical processor deferred
* until spu_activate().
*/
if (spu_init_csa(&ctx->csa))
- goto out_free;
+ goto out_free_gang;
+
spin_lock_init(&ctx->mmio_lock);
mutex_init(&ctx->mapping_lock);
kref_init(&ctx->kref);
@@ -58,15 +72,16 @@ struct spu_context *alloc_spu_context(struct spu_gang
*gang)
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_gang_add_ctx(gang, ctx);
__spu_update_sched_info(ctx);
spu_set_timeslice(ctx);
ctx->stats.util_state = SPU_UTIL_IDLE_LOADED;
atomic_inc(&nr_spu_contexts);
goto out;
+
+out_free_gang:
+ kfree(gang);
out_free:
kfree(ctx);
ctx = NULL;
@@ -76,15 +91,18 @@ out:
void destroy_spu_context(struct kref *kref)
{
+ struct spu_gang *gang;
struct spu_context *ctx;
+
ctx = container_of(kref, struct spu_context, kref);
+ gang = ctx->gang;
+
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);
+ 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));
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c
b/arch/powerpc/platforms/cell/spufs/inode.c
index 690ca7b..cf97761 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -261,18 +261,30 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry,
unsigned int flags,
{
int ret;
struct inode *inode;
- struct spu_context *ctx;
+ struct spu_context *ctx, *gang_ctx;
+ struct spu_gang *gang;
ret = -ENOSPC;
inode = spufs_new_inode(dir->i_sb, mode | S_IFDIR);
if (!inode)
goto out;
+ /* Can't mix sched and no-sched within the same gang. */
+ gang = SPUFS_I(dir)->i_gang;
+ if (gang) {
+ gang_ctx = list_first_entry(&gang->list, struct spu_context, gang_list);
+ if ((flags & SPU_CREATE_NOSCHED) ^
+ (gang_ctx->flags & SPU_CREATE_NOSCHED)) {
+ ret = -EPERM;
+ goto out_iput;
+ }
+ }
+
if (dir->i_mode & S_ISGID) {
inode->i_gid = dir->i_gid;
inode->i_mode &= S_ISGID;
}
- ctx = alloc_spu_context(SPUFS_I(dir)->i_gang); /* XXX gang */
+ ctx = alloc_spu_context(gang);
SPUFS_I(inode)->i_ctx = ctx;
if (!ctx)
goto out_iput;
--
1.5.4.1
More information about the cbe-oss-dev
mailing list