Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 42177
b: refs/heads/master
c: 099814b
h: refs/heads/master
i:
  42175: 5c7eecb
v: v3
  • Loading branch information
Jeremy Kerr authored and Paul Mackerras committed Oct 25, 2006
1 parent 0fa0901 commit b37eb61
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 9 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0afacde3df4c9980f505d9afd7cb0058389732ca
refs/heads/master: 099814bb1f9bd9081d7c85867f8eb8c049abc1b9
27 changes: 27 additions & 0 deletions trunk/arch/powerpc/platforms/cell/spufs/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,33 @@ void spu_unmap_mappings(struct spu_context *ctx)
unmap_mapping_range(ctx->signal2, 0, 0x4000, 1);
}

int spu_acquire_exclusive(struct spu_context *ctx)
{
int ret = 0;

down_write(&ctx->state_sema);
/* ctx is about to be freed, can't acquire any more */
if (!ctx->owner) {
ret = -EINVAL;
goto out;
}

if (ctx->state == SPU_STATE_SAVED) {
ret = spu_activate(ctx, 0);
if (ret)
goto out;
ctx->state = SPU_STATE_RUNNABLE;
} else {
/* We need to exclude userspace access to the context. */
spu_unmap_mappings(ctx);
}

out:
if (ret)
up_write(&ctx->state_sema);
return ret;
}

int spu_acquire_runnable(struct spu_context *ctx)
{
int ret = 0;
Expand Down
32 changes: 32 additions & 0 deletions trunk/arch/powerpc/platforms/cell/spufs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -1343,6 +1343,37 @@ static struct file_operations spufs_mfc_fops = {
.mmap = spufs_mfc_mmap,
};


static int spufs_recycle_open(struct inode *inode, struct file *file)
{
file->private_data = SPUFS_I(inode)->i_ctx;
return nonseekable_open(inode, file);
}

static ssize_t spufs_recycle_write(struct file *file,
const char __user *buffer, size_t size, loff_t *pos)
{
struct spu_context *ctx = file->private_data;
int ret;

if (!(ctx->flags & SPU_CREATE_ISOLATE))
return -EINVAL;

if (size < 1)
return -EINVAL;

ret = spu_recycle_isolated(ctx);

if (ret)
return ret;
return size;
}

static struct file_operations spufs_recycle_fops = {
.open = spufs_recycle_open,
.write = spufs_recycle_write,
};

static void spufs_npc_set(void *data, u64 val)
{
struct spu_context *ctx = data;
Expand Down Expand Up @@ -1551,5 +1582,6 @@ struct tree_descr spufs_dir_nosched_contents[] = {
{ "psmap", &spufs_psmap_fops, 0666, },
{ "phys-id", &spufs_id_ops, 0666, },
{ "object-id", &spufs_object_id_ops, 0666, },
{ "recycle", &spufs_recycle_fops, 0222, },
{},
};
23 changes: 15 additions & 8 deletions trunk/arch/powerpc/platforms/cell/spufs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ static int spu_setup_isolated(struct spu_context *ctx)
if (!isolated_loader)
return -ENODEV;

if ((ret = spu_acquire_runnable(ctx)) != 0)
if ((ret = spu_acquire_exclusive(ctx)) != 0)
return ret;

mfc_cntl = &ctx->spu->priv2->mfc_control_RW;
Expand Down Expand Up @@ -314,10 +314,16 @@ static int spu_setup_isolated(struct spu_context *ctx)
spu_mfc_sr1_set(ctx->spu, sr1);

out_unlock:
up_write(&ctx->state_sema);
spu_release_exclusive(ctx);
return ret;
}

int spu_recycle_isolated(struct spu_context *ctx)
{
ctx->ops->runcntl_stop(ctx);
return spu_setup_isolated(ctx);
}

static int
spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags,
int mode)
Expand All @@ -341,12 +347,6 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags,
goto out_iput;

ctx->flags = flags;
if (flags & SPU_CREATE_ISOLATE) {
ret = spu_setup_isolated(ctx);
if (ret)
goto out_iput;
}

inode->i_op = &spufs_dir_inode_operations;
inode->i_fop = &simple_dir_operations;
if (flags & SPU_CREATE_NOSCHED)
Expand Down Expand Up @@ -432,6 +432,13 @@ static int spufs_create_context(struct inode *inode,
out_unlock:
mutex_unlock(&inode->i_mutex);
out:
if (ret >= 0 && (flags & SPU_CREATE_ISOLATE)) {
int setup_err = spu_setup_isolated(
SPUFS_I(dentry->d_inode)->i_ctx);
if (setup_err)
ret = setup_err;
}

dput(dentry);
return ret;
}
Expand Down
7 changes: 7 additions & 0 deletions trunk/arch/powerpc/platforms/cell/spufs/spufs.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,13 +163,20 @@ void spu_acquire(struct spu_context *ctx);
void spu_release(struct spu_context *ctx);
int spu_acquire_runnable(struct spu_context *ctx);
void spu_acquire_saved(struct spu_context *ctx);
int spu_acquire_exclusive(struct spu_context *ctx);

static inline void spu_release_exclusive(struct spu_context *ctx)
{
up_write(&ctx->state_sema);
}

int spu_activate(struct spu_context *ctx, u64 flags);
void spu_deactivate(struct spu_context *ctx);
void spu_yield(struct spu_context *ctx);
int __init spu_sched_init(void);
void __exit spu_sched_exit(void);

int spu_recycle_isolated(struct spu_context *ctx);
/*
* spufs_wait
* Same as wait_event_interruptible(), except that here
Expand Down

0 comments on commit b37eb61

Please sign in to comment.