<div dir="ltr">Ping, if I used the wrong list please point me to the correct one.<br><br><div class="gmail_extra"><br><br><div class="gmail_quote">On 22 August 2013 17:22, Christiano F. Haesbaert <span dir="ltr"><<a href="mailto:haesbaert@haesbaert.org" target="_blank">haesbaert@haesbaert.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi there,<br>
<br>
I've been studying dragonfly for a while now and this is something I<br>
could never figure out, I'm pretty sure I'm missing something and I'd<br>
appreciate if someone could give me some pointers.<br>
<br>
Suppose the following cenario.<br>
<br>
Cenario A [A]<br>
cpu0: on whichever context<br>
cpu0: spin_lock(&a) (now in a critical section)<br>
cpu0: wakeup(ident1) (ident1 has a sleeper on cpu1)<br>
cpu0: lwkt_send_ipiq3(cpu1, wakeup(ident1))<br>
<br>
But ipiq for cpu1 is full, so I enable interrupts, although I'm still on<br>
a critical section, process my own ipiq and spin until cpu1 queue is not<br>
full, but at this point I'm still holding spin_lock a.<br>
<br>
This is the code I'm referring to, lwkt_ipiq:221-229<br>
<br>
        while (ip->ip_windex - ip->ip_rindex > MAXCPUFIFO / 4) {<br>
            if (atomic_poll_acquire_int(&target->gd_npoll)) {<br>
                logipiq(cpu_send, func, arg1, arg2, gd, target);<br>
                cpu_send_ipiq(target->gd_cpuid);<br>
            }<br>
            KKASSERT(ip->ip_windex - ip->ip_rindex != MAXCPUFIFO - 1);<br>
            lwkt_process_ipiq();<br>
            cpu_pause();<br>
        }<br>
<br>
cpu1: ipiq is full and is running an ithread, so it's in a critical section.<br>
cpu1: spin_lock(&a);<br>
cpu1: ??deadlocked??<br>
<br>
cpu1 will never process its own ipiq, therefore cpu0 will never make progress,<br>
since cpu0 holds spin_lock a, cpu1 will never make progress as well.<br>
<br>
Would this imply that a code that may generate an ipi down the stack, may never<br>
hold a spinlock ? I understand it is very likely that there is no current path<br>
that does a wakeup holding a spinlock.<br>
<br>
Furthermore, in this cenario you end up processing your own ipiq even if you<br>
were already on a critical section, can't the ipiq callbacks actually race<br>
against the code that lead to wakeup()->lwkt_sent_ipiq3()->lwkt_process_ipiq() ?<br>
<br>
Cenario [B]<br>
Still regarding the paragraph above, what if both cpu0 and cpu1 have their ipiqs<br>
full _and_ come from a code in a critical section, as in:<br>
<br>
cpu0: cpu0 own ipiq is full<br>
cpu0: crit_enter()<br>
cpu0: crit_enter()<br>
cpu0: wakeup(ident1) (ident1 has a sleeper on cpu1)<br>
...<br>
<br>
cpu1: cpu1 own ipiq is full<br>
cpu1: crit_enter()<br>
cpu1: crit_enter()<br>
cpu1: wakeup(ident0) (ident0 has a sleeper on cpu0)<br>
...<br>
<br>
Both realize the other is full and process their own queues, but they break the<br>
atomicity required by the two calls to crit_enter() earlier<br>
<br>
What am I missing ? (Sorry for the noise).<br>
<br>
Thanks<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Christiano Farina HAESBAERT<br>
Do NOT send me html mail.<br>
</font></span></blockquote></div><br></div></div>