Question regarding IPIQs
Christiano F. Haesbaert
haesbaert at haesbaert.org
Thu Aug 29 04:20:59 PDT 2013
On 28 August 2013 23:35, Matthew Dillon <dillon at apollo.backplane.com> wrote:
> :Hi there,
> :
> :I've been studying dragonfly for a while now and this is something I
> :could never figure out, I'm pretty sure I'm missing something and I'd
> :appreciate if someone could give me some pointers.
> :
> :Suppose the following cenario.
> :
> :Cenario A [A]
> :cpu0: on whichever context
> :cpu0: spin_lock(&a) (now in a critical section)
> :cpu0: wakeup(ident1) (ident1 has a sleeper on cpu1)
> :cpu0: lwkt_send_ipiq3(cpu1, wakeup(ident1))
>
> Illegal. You should not call wakeup() with a spin lock held.
> You most definitely should not be calling any IPIQ functions with
> a spin lock held.
>
> You have two solutions here. First, use a regular lock or a token
> instead of a spin lock. Second, flag the condition and issue the
> wakeup() or IPIQ function after releasing the spin lock.
>
> In DragonFly, spin locks are only intended to be used for very
> short sequences of self-contained or mostly self-contained code.
>
> :But ipiq for cpu1 is full, so I enable interrupts, although I'm still on
> :a critical section, process my own ipiq and spin until cpu1 queue is not
> :full, but at this point I'm still holding spin_lock a.
>
> Critical sections do not disable interrupts, they simply prevent normal
> preemptive processing (preemption by an interrupt thread or IPI)
> from occuring. Interrupts will still occur, but they will simply flag
> the pending condition in mycpu->gd_reqflags, EOI the interrupt, and
> immediately return. The interrupt is then processed normally when the
> critical section is exited.
>
> However, if you issue an IPIQ operation inside a critical section which
> would otherwise be forced to spin-wait due to a full IPIQ queue, it
> will synchronously execute any incoming IPIs while it is spin-waiting
> to avoid deadlocking the system.
>
> :Both realize the other is full and process their own queues, but they
> break the
> :atomicity required by the two calls to crit_enter() earlier
> :
> :What am I missing ? (Sorry for the noise).
> :
> :Thanks
>
> Programs which enter critical sections can always assume that there
> will
> be no asynchronous atomicy breakage, but there are no guarantees
> regarding
> synchronous atomicy. For example, you can tsleep() just fine while
> holding a critical section. Nominal IPIQ operations fall under the
> same
> rules. Incoming IPIs will not be executed asynchronously but they can
> still be executed synchronously if your outgoing IPI operation would
> otherwise be forced to spin-wait.
>
>
Thanks for the detailed reply.
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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.dragonflybsd.org/pipermail/kernel/attachments/20130829/dce3e685/attachment-0002.html>
More information about the Kernel
mailing list