Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5737edd1 authored by Mark Nutter's avatar Mark Nutter Committed by Paul Mackerras
Browse files

[POWERPC] spufs: add support for nonschedulable contexts



This adds two new flags to spu_create:

SPU_CREATE_NONSCHED: create a context that is never moved
away from an SPE once it has started running. This flag
can only be used by tasks with the CAP_SYS_NICE capability.

SPU_CREATE_ISOLATED: create a nonschedulable context that
enters isolation mode upon first run. This requires the
SPU_CREATE_NONSCHED flag.

Signed-off-by: default avatarJeremy Kerr <jk@ozlabs.org>
Signed-off-by: default avatarArnd Bergmann <arnd.bergmann@de.ibm.com>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent cc21a66d
Loading
Loading
Loading
Loading
+22 −0
Original line number Original line Diff line number Diff line
@@ -1531,3 +1531,25 @@ struct tree_descr spufs_dir_contents[] = {
	{ "object-id", &spufs_object_id_ops, 0666, },
	{ "object-id", &spufs_object_id_ops, 0666, },
	{},
	{},
};
};

struct tree_descr spufs_dir_nosched_contents[] = {
	{ "mem",  &spufs_mem_fops,  0666, },
	{ "mbox", &spufs_mbox_fops, 0444, },
	{ "ibox", &spufs_ibox_fops, 0444, },
	{ "wbox", &spufs_wbox_fops, 0222, },
	{ "mbox_stat", &spufs_mbox_stat_fops, 0444, },
	{ "ibox_stat", &spufs_ibox_stat_fops, 0444, },
	{ "wbox_stat", &spufs_wbox_stat_fops, 0444, },
	{ "signal1", &spufs_signal1_fops, 0666, },
	{ "signal2", &spufs_signal2_fops, 0666, },
	{ "signal1_type", &spufs_signal1_type, 0666, },
	{ "signal2_type", &spufs_signal2_type, 0666, },
	{ "mss", &spufs_mss_fops, 0666, },
	{ "mfc", &spufs_mfc_fops, 0666, },
	{ "cntl", &spufs_cntl_fops,  0666, },
	{ "npc", &spufs_npc_ops, 0666, },
	{ "psmap", &spufs_psmap_fops, 0666, },
	{ "phys-id", &spufs_id_ops, 0666, },
	{ "object-id", &spufs_object_id_ops, 0666, },
	{},
};
+4 −1
Original line number Original line Diff line number Diff line
@@ -219,8 +219,11 @@ static char *spu_hw_get_ls(struct spu_context *ctx)


static void spu_hw_runcntl_write(struct spu_context *ctx, u32 val)
static void spu_hw_runcntl_write(struct spu_context *ctx, u32 val)
{
{
	eieio();
	spin_lock_irq(&ctx->spu->register_lock);
	if (val & SPU_RUNCNTL_ISOLATE)
		out_be64(&ctx->spu->priv2->spu_privcntl_RW, 4LL);
	out_be32(&ctx->spu->problem->spu_runcntl_RW, val);
	out_be32(&ctx->spu->problem->spu_runcntl_RW, val);
	spin_unlock_irq(&ctx->spu->register_lock);
}
}


static void spu_hw_runcntl_stop(struct spu_context *ctx)
static void spu_hw_runcntl_stop(struct spu_context *ctx)
+16 −1
Original line number Original line Diff line number Diff line
@@ -258,7 +258,12 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags,


	inode->i_op = &spufs_dir_inode_operations;
	inode->i_op = &spufs_dir_inode_operations;
	inode->i_fop = &simple_dir_operations;
	inode->i_fop = &simple_dir_operations;
	if (flags & SPU_CREATE_NOSCHED)
		ret = spufs_fill_dir(dentry, spufs_dir_nosched_contents,
					 mode, ctx);
	else
		ret = spufs_fill_dir(dentry, spufs_dir_contents, mode, ctx);
		ret = spufs_fill_dir(dentry, spufs_dir_contents, mode, ctx);

	if (ret)
	if (ret)
		goto out_free_ctx;
		goto out_free_ctx;


@@ -307,6 +312,16 @@ static int spufs_create_context(struct inode *inode,
{
{
	int ret;
	int ret;


	ret = -EPERM;
	if ((flags & SPU_CREATE_NOSCHED) &&
	    !capable(CAP_SYS_NICE))
		goto out_unlock;

	ret = -EINVAL;
	if ((flags & (SPU_CREATE_NOSCHED | SPU_CREATE_ISOLATE))
	    == SPU_CREATE_ISOLATE)
		goto out_unlock;

	ret = spufs_mkdir(inode, dentry, flags, mode & S_IRWXUGO);
	ret = spufs_mkdir(inode, dentry, flags, mode & S_IRWXUGO);
	if (ret)
	if (ret)
		goto out_unlock;
		goto out_unlock;
+8 −2
Original line number Original line Diff line number Diff line
@@ -51,11 +51,17 @@ static inline int spu_stopped(struct spu_context *ctx, u32 * stat)
static inline int spu_run_init(struct spu_context *ctx, u32 * npc)
static inline int spu_run_init(struct spu_context *ctx, u32 * npc)
{
{
	int ret;
	int ret;
	unsigned long runcntl = SPU_RUNCNTL_RUNNABLE;


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

	if (ctx->flags & SPU_CREATE_ISOLATE)
		runcntl |= SPU_RUNCNTL_ISOLATE;
	else
		ctx->ops->npc_write(ctx, *npc);
		ctx->ops->npc_write(ctx, *npc);
	ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE);

	ctx->ops->runcntl_write(ctx, runcntl);
	return 0;
	return 0;
}
}


+1 −0
Original line number Original line Diff line number Diff line
@@ -135,6 +135,7 @@ struct spufs_inode_info {
	container_of(inode, struct spufs_inode_info, vfs_inode)
	container_of(inode, struct spufs_inode_info, vfs_inode)


extern struct tree_descr spufs_dir_contents[];
extern struct tree_descr spufs_dir_contents[];
extern struct tree_descr spufs_dir_nosched_contents[];


/* system call implementation */
/* system call implementation */
long spufs_run_spu(struct file *file,
long spufs_run_spu(struct file *file,
Loading