<html><body>
<p><tt>cbe-oss-dev-bounces+lukebrowning=us.ibm.com@ozlabs.org wrote on 02/09/2007 01:47:29 PM:<br>
<br>
&gt; On Fri, Feb 09, 2007 at 12:43:01AM +0100, Christoph Hellwig wrote:<br>
&gt; &gt; If we start a spu context with realtime priority we want it to run<br>
&gt; &gt; immediately and not wait until some other lower priority thread has<br>
&gt; &gt; finished. &nbsp;Try to find a suitable victim and use it's spu in this<br>
&gt; &gt; case.<br>
&gt; <br>
&gt; Due to a mistake in my quilt usage this is missing the changes to<br>
&gt; context.c and spufs.h. &nbsp;The full patch is below:<br>
&gt; <br>
&gt; Index: linux-2.6/arch/powerpc/platforms/cell/spufs/sched.c<br>
&gt; ===================================================================<br>
&gt; --- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/sched.c &nbsp; <br>
&gt; 2007-02-09 16:08:51.000000000 +0100<br>
&gt; +++ linux-2.6/arch/powerpc/platforms/cell/spufs/sched.c &nbsp; 2007-02-09<br>
&gt; 16:08:57.000000000 +0100<br>
&gt; @@ -282,6 +282,74 @@<br>
&gt; &nbsp;}<br>
&gt; &nbsp;<br>
&gt; &nbsp;/**<br>
&gt; + * find_victim - find a lower priority context to preempt<br>
&gt; + * @ctx: &nbsp; canidate context for running<br>
&gt; + *<br>
&gt; + * Returns the freed physical spu to run the new context on.<br>
&gt; + */<br>
&gt; +static struct spu *find_victim(struct spu_context *ctx)<br>
&gt; +{<br>
&gt; + &nbsp; struct spu_context *victim = NULL;<br>
&gt; + &nbsp; struct spu *spu;<br>
&gt; + &nbsp; int node, n;<br>
&gt; +<br>
&gt; + &nbsp; /*<br>
&gt; + &nbsp; &nbsp;* Look for a possible preemption candidate on the local node first.<br>
&gt; + &nbsp; &nbsp;* If there is no candidate look at the other nodes. &nbsp;This isn't<br>
&gt; + &nbsp; &nbsp;* exactly fair, but so far the whole spu schedule tries to keep<br>
&gt; + &nbsp; &nbsp;* a strong node affinity. &nbsp;We might want to fine-tune this in<br>
&gt; + &nbsp; &nbsp;* the future.<br>
&gt; + &nbsp; &nbsp;*/<br>
&gt; + restart:<br>
&gt; + &nbsp; node = cpu_to_node(raw_smp_processor_id());<br>
&gt; + &nbsp; for (n = 0; n &lt; MAX_NUMNODES; n++, node++) {<br>
&gt; + &nbsp; &nbsp; &nbsp;node = (node &lt; MAX_NUMNODES) ? node : 0;<br>
&gt; + &nbsp; &nbsp; &nbsp;if (!node_allowed(node))<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; continue;<br>
&gt; +<br>
&gt; + &nbsp; &nbsp; &nbsp;mutex_lock(&amp;spu_prio-&gt;active_mutex[node]);<br>
&gt; + &nbsp; &nbsp; &nbsp;list_for_each_entry(spu, &amp;spu_prio-&gt;active_list[node], list) {<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; struct spu_context *tmp = spu-&gt;ctx;<br>
&gt; +<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; if (tmp-&gt;rt_priority &lt; ctx-&gt;rt_priority &amp;&amp;<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (!victim || tmp-&gt;rt_priority &lt; victim-&gt;rt_priority))<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;victim = spu-&gt;ctx;<br>
&gt; + &nbsp; &nbsp; &nbsp;}<br>
&gt; + &nbsp; &nbsp; &nbsp;mutex_unlock(&amp;spu_prio-&gt;active_mutex[node]);<br>
&gt; +<br>
&gt; + &nbsp; &nbsp; &nbsp;if (victim) {<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; /*<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* This nests ctx-&gt;state_mutex, but we always lock<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* higher priority contexts before lower priority<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* ones, so this is safe until we introduce<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* priority inheritance schemes.<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; if (!mutex_trylock(&amp;victim-&gt;state_mutex)) {<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;victim = NULL;<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;goto restart;<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; }<br>
&gt; +<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; spu = victim-&gt;spu;<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; if (!spu) {<br>
</tt><br>
<tt>You might also want to retest the priority fields under the ctx lock to </tt><br>
<tt>make ensure that the priorities haven't changed. &nbsp;The code above uses the</tt><br>
<tt>runqueue lock, which doesn't protect these fields, right?</tt><br>
<br>
<tt>&gt; + &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/*<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; * This race can happen because we've dropped<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; * the active list mutex. &nbsp;No a problem, just<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; * restart the search.<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; */<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mutex_unlock(&amp;victim-&gt;state_mutex);<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;victim = NULL;<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;goto restart;<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; }<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; spu_unbind_context(spu, victim);<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; mutex_unlock(&amp;victim-&gt;state_mutex);<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; return spu;<br>
&gt; + &nbsp; &nbsp; &nbsp;}<br>
&gt; + &nbsp; }<br>
&gt; +<br>
&gt; + &nbsp; return NULL;<br>
&gt; +}<br>
&gt; +<br>
&gt; +/**<br>
&gt; &nbsp; * spu_activate - find a free spu for a context and execute it<br>
&gt; &nbsp; * @ctx: &nbsp; spu context to schedule<br>
&gt; &nbsp; * @flags: &nbsp; flags (currently ignored)<br>
&gt; @@ -300,6 +368,12 @@<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp;struct spu *spu;<br>
&gt; &nbsp;<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp;spu = spu_get_idle(ctx);<br>
&gt; + &nbsp; &nbsp; &nbsp;/*<br>
&gt; + &nbsp; &nbsp; &nbsp; * If this is a realtime thread we try to get it running by<br>
&gt; + &nbsp; &nbsp; &nbsp; * preempting a lower priority thread.<br>
&gt; + &nbsp; &nbsp; &nbsp; */<br>
&gt; + &nbsp; &nbsp; &nbsp;if (!spu &amp;&amp; ctx-&gt;rt_priority)<br>
&gt; + &nbsp; &nbsp; &nbsp; &nbsp; spu = find_victim(ctx);<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp;if (spu) {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; spu_bind_context(spu, ctx);<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return 0;<br>
&gt; Index: linux-2.6/arch/powerpc/platforms/cell/spufs/context.c<br>
&gt; ===================================================================<br>
&gt; --- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/context.c &nbsp; <br>
&gt; 2007-02-09 16:09:34.000000000 +0100<br>
&gt; +++ linux-2.6/arch/powerpc/platforms/cell/spufs/context.c &nbsp; <br>
&gt; 2007-02-09 16:09:56.000000000 +0100<br>
&gt; @@ -53,6 +53,7 @@<br>
&gt; &nbsp; &nbsp; ctx-&gt;owner = get_task_mm(current);<br>
&gt; &nbsp; &nbsp; if (gang)<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp;spu_gang_add_ctx(gang, ctx);<br>
&gt; + &nbsp; ctx-&gt;rt_priority = current-&gt;rt_priority;<br>
&gt; &nbsp; &nbsp; ctx-&gt;prio = current-&gt;prio;<br>
&gt; &nbsp; &nbsp; goto out;<br>
&gt; &nbsp;out_free:<br>
&gt; Index: linux-2.6/arch/powerpc/platforms/cell/spufs/spufs.h<br>
&gt; ===================================================================<br>
&gt; --- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/spufs.h &nbsp; <br>
&gt; 2007-02-09 16:09:06.000000000 +0100<br>
&gt; +++ linux-2.6/arch/powerpc/platforms/cell/spufs/spufs.h &nbsp; 2007-02-09<br>
&gt; 16:09:17.000000000 +0100<br>
&gt; @@ -81,6 +81,7 @@<br>
&gt; &nbsp; &nbsp; /* scheduler fields */<br>
&gt; &nbsp; &nbsp; &nbsp;struct list_head rq;<br>
&gt; &nbsp; &nbsp; unsigned long sched_flags;<br>
&gt; + &nbsp; unsigned long rt_priority;<br>
&gt; &nbsp; &nbsp; int prio;<br>
&gt; &nbsp;};<br>
&gt; &nbsp;<br>
&gt; _______________________________________________<br>
&gt; cbe-oss-dev mailing list<br>
&gt; cbe-oss-dev@ozlabs.org<br>
&gt; <a href="https://ozlabs.org/mailman/listinfo/cbe-oss-dev">https://ozlabs.org/mailman/listinfo/cbe-oss-dev</a><br>
</tt></body></html>