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

Commit 2cf2b3b4 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Paul Mackerras
Browse files

[POWERPC] spusched: Update scheduling paramters on every spu_run



Update scheduling information on every spu_run to allow for setting
threads to realtime priority just before running them.  This requires
some slightly ugly code in spufs_run_spu because we can just update
the information unlocked if the spu is not runnable, but we need to
acquire the active_mutex when it is runnable to protect against
find_victim.  This locking scheme requires opencoding
spu_acquire_runnable in spufs_run_spu which actually is a nice cleanup
all by itself.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarArnd Bergmann <arnd.bergmann@de.ibm.com>
Signed-off-by: default avatarJeremy Kerr <jk@ozlabs.org>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent f3f59bec
Loading
Loading
Loading
Loading
+0 −11
Original line number Diff line number Diff line
@@ -54,17 +54,6 @@ struct spu_context *alloc_spu_context(struct spu_gang *gang)
	if (gang)
		spu_gang_add_ctx(gang, ctx);

	/*
	 * We do our own priority calculations, so we normally want
	 * ->static_prio to start with. Unfortunately thies field
	 * contains junk for threads with a realtime scheduling
	 * policy so we have to look at ->prio in this case.
	 */
	if (rt_prio(current->prio))
		ctx->prio = current->prio;
	else
		ctx->prio = current->static_prio;
	ctx->policy = current->policy;
	spu_set_timeslice(ctx);
	goto out;
out_free:
+16 −3
Original line number Diff line number Diff line
@@ -301,9 +301,22 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx,
	ctx->ops->master_start(ctx);
	ctx->event_return = 0;

	ret = spu_acquire_runnable(ctx, 0);
	if (ret)
		return ret;
	spu_acquire(ctx);
	if (ctx->state == SPU_STATE_SAVED) {
		__spu_update_sched_info(ctx);

		ret = spu_activate(ctx, 0);
		if (ret) {
			spu_release(ctx);
			goto out;
		}
	} else {
		/*
		 * We have to update the scheduling priority under active_mutex
		 * to protect against find_victim().
		 */
		spu_update_sched_info(ctx);
	}

	ret = spu_run_init(ctx, npc);
	if (ret) {
+27 −0
Original line number Diff line number Diff line
@@ -96,6 +96,33 @@ void spu_set_timeslice(struct spu_context *ctx)
		ctx->time_slice = SCALE_PRIO(DEF_SPU_TIMESLICE, ctx->prio);
}

/*
 * Update scheduling information from the owning thread.
 */
void __spu_update_sched_info(struct spu_context *ctx)
{
	/*
	 * We do our own priority calculations, so we normally want
	 * ->static_prio to start with. Unfortunately thies field
	 * contains junk for threads with a realtime scheduling
	 * policy so we have to look at ->prio in this case.
	 */
	if (rt_prio(current->prio))
		ctx->prio = current->prio;
	else
		ctx->prio = current->static_prio;
	ctx->policy = current->policy;
}

void spu_update_sched_info(struct spu_context *ctx)
{
	int node = ctx->spu->node;

	mutex_lock(&spu_prio->active_mutex[node]);
	__spu_update_sched_info(ctx);
	mutex_unlock(&spu_prio->active_mutex[node]);
}

static inline int node_allowed(int node)
{
	cpumask_t mask;
+2 −0
Original line number Diff line number Diff line
@@ -195,6 +195,8 @@ int spu_activate(struct spu_context *ctx, unsigned long flags);
void spu_deactivate(struct spu_context *ctx);
void spu_yield(struct spu_context *ctx);
void spu_set_timeslice(struct spu_context *ctx);
void spu_update_sched_info(struct spu_context *ctx);
void __spu_update_sched_info(struct spu_context *ctx);
int __init spu_sched_init(void);
void __exit spu_sched_exit(void);