[Cbe-oss-dev] Scheduler runqueue interactions
Luke Browning
LukeBrowning at us.ibm.com
Sun Feb 25 01:16:27 EST 2007
Hi Christoph,
See comment below subroutine.
Thanks, Luke
/**
* spu_activate - find a free spu for a context and execute it
* @ctx: spu context to schedule
* @flags: flags (currently ignored)
*
* Tries to find a free spu to run @ctx. If no free spu is availble
* add the context to the runqueue so it gets woken up once an spu
* is available.
*/
int spu_activate(struct spu_context *ctx, unsigned long flags)
{
if (ctx->spu)
return 0;
do {
struct spu *spu;
spu = spu_get_idle(ctx);
/*
* If this is a realtime thread we try to get it running by
* preempting a lower priority thread.
*/
if (!spu && ctx->rt_priority)
spu = find_victim(ctx);
if (spu) {
spu_bind_context(spu, ctx);
return 0;
}
spu_add_to_rq(ctx);
if (!(flags & SPU_ACTIVATE_NOWAKE))
spu_prio_wait(ctx);
spu_del_from_rq(ctx);
} while (!signal_pending(current));
return -ERESTARTSYS;
}
--------------------------
A couple of points:
1) If ctx is not fixed priority (ie. SCHED_OTHER) and SPU_ACTIVATE_NOWAKE
is specified (spu_run_init)
then you spin waiting for an spu to become idle assuming there is not a
signal pending.
do {
...
spu_add_to_rq()
spu_del_from_rq()
} while (!signal);
2) SPU_ACTIVATE_NOWAKE is a bad name as it doesn't describe what the target
is doing. In this case
the caller is requesting that ctx be put into the runnable state
without blocking. I suggest something like:
if (!(flags & SPU_ACTIVATE_NDELAY))
spu_prio_wait()
Sorry to belabour this point, but I made it in my earlier comment.
Maybe it wasn't clear.
3) this is actually the big point. The high level flow should be:
spufs_run_spu()
{
spu_run_init(); <--- the ctx is made
runnable w/o blocking.
do {
spufs_wait(); <--- the calling thread
blocks here for the first time.
...
} while ();
}
We want to avoid the context switch in spu_run_init(), since we are going
to block a few lines of code
later in spufs_run_spu() when it invokes spufs_wait(). We might as well
just wait there the first time.
spu_run_init() should just put the ctx on the runqueue and return to the
caller w/o blocking.
Here's the tricky part. spu_run_init() also performs runctl register
stuff! I think that these state changes
can be made against the saved state of the ctx and applied later by the
scheduler just as it would for
a preempted context, so these changes do not require a major restructuring
of the code. The ctx should
be put on the runqueue with its save area updated just like you would have
if it were preempted.
Luke
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ozlabs.org/pipermail/cbe-oss-dev/attachments/20070224/9946d945/attachment.htm>
More information about the cbe-oss-dev
mailing list