Re: Race condition in interrupt handling

"Mai, Haohui" <[email protected]> Tue, 13 Apr 2010 07:24:22 -0500
Newsgroups gmane.comp.micro-kernel.l4.l4ka.general
Message-ID <[email protected]>
Hi,

What happens is that the interrupt is still masked even after 
intctrl_t::unmask() is called. It seems to me that the following 
interleaving is happening:

A thread is finished handling an interrupt and try to unmask the irq by 
calling intctrl_t::unmask():
      if (redir[irq].entry.is_edge_triggered())
      {
      if (redir[irq].pending)
      {
          redir[irq].pending = false;

/**
   * (1) INTERRUPT COMES HERE
   **/
          return true; // leave IRQ masked, since there was another pending
      }

An interrupt comes in at (1) and executes the intctrl_t::handle_irq()

      bool deliver = true;

      // edge triggered IRQs are marked as pending if masked
      if ( redir[irq].entry.is_edge_triggered() &&
       redir[irq].entry.x.mask )
...
      redir[irq].pending = true;
      deliver = false;
      }

Which resets the pending to true without delivering the interrupt.

Haohui
On 04/13/2010 02:20 AM, Jan Stoess wrote:
>
> Hi Haohui,
>
> There's no line 423 in api/v4/interrupt.cc in the current HG repo, I 
> am assuming you're referring to line 86.
>
> Anyway,  thanks for the patch. Before we commit the fix, can you 
> elaborate a little bit more on the race condition you're hitting? In 
> particular, I thought APIC redir entries are modified by one dedicated 
> CPU only -- the CPU the IRQ is routed to, so races should occur only 
> during IRQ migration. While I can imagine that there might be a race 
> at times, I am also wondering if we can get away without locking every 
> modification of a redirection entry.
>
> Thanks!
>
> -Jan
>
> --
>
> Jan Stoess
>
> KIT/UKa System Architecture Group
>
> Phone: +49 (721) 608-4056
>
> Fax: +49 (721) 608-7664
>
> http://os.ibds.kit.edu/stoess
>