<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On 28 August 2013 23:35, Matthew Dillon <span dir="ltr"><<a href="mailto:dillon@apollo.backplane.com" target="_blank">dillon@apollo.backplane.com</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>
<div class="im">:<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>
</div>    Illegal.  You should not call wakeup() with a spin lock held.<br>
    You most definitely should not be calling any IPIQ functions with<br>
    a spin lock held.<br>
<br>
    You have two solutions here.  First, use a regular lock or a token<br>
    instead of a spin lock.  Second, flag the condition and issue the<br>
    wakeup() or IPIQ function after releasing the spin lock.<br>
<br>
    In DragonFly, spin locks are only intended to be used for very<br>
    short sequences of self-contained or mostly self-contained code.<br>
<br>
:But ipiq for cpu1 is full, so I enable interrupts, although I'm still on<br>
<div class="im">: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>
</div>    Critical sections do not disable interrupts, they simply prevent normal<br>
    preemptive processing (preemption by an interrupt thread or IPI)<br>
    from occuring.  Interrupts will still occur, but they will simply flag<br>
    the pending condition in mycpu->gd_reqflags, EOI the interrupt, and<br>
    immediately return.  The interrupt is then processed normally when the<br>
    critical section is exited.<br>
<br>
    However, if you issue an IPIQ operation inside a critical section which<br>
    would otherwise be forced to spin-wait due to a full IPIQ queue, it<br>
    will synchronously execute any incoming IPIs while it is spin-waiting<br>
    to avoid deadlocking the system.<br>
<br>
:Both realize the other is full and process their own queues, but they break the<br>
<div class="im">:atomicity required by the two calls to crit_enter() earlier<br>
:<br>
:What am I missing ? (Sorry for the noise).<br>
:<br>
:Thanks<br>
<br>
</div>    Programs which enter critical sections can always assume that there will<br>
    be no asynchronous atomicy breakage, but there are no guarantees regarding<br>
    synchronous atomicy.  For example, you can tsleep() just fine while<br>
    holding a critical section.  Nominal IPIQ operations fall under the same<br>
    rules.  Incoming IPIs will not be executed asynchronously but they can<br>
    still be executed synchronously if your outgoing IPI operation would<br>
    otherwise be forced to spin-wait.<br>
<br></blockquote><div><br></div><div>Thanks for the detailed reply.<br><br>I assumed synchronous atomicity had to be kept across a critical section, I had considered the tsleep case but thought it was special, since you're sleeping, it's already implied you accept losing atomicity.<br>
</div></div></div></div>