What it seems to me is that the CPU is running irq_thread(), and the
hardware interrupt comes in, so that the CPU executes the interrupt
handler (which is intctrl_t::handle_irq()) and causes this problem. The
whole thing happens in kernel and it is irrelevant to the delivery to
the user level handler.
handle_irq() {
...
...
local_apic.EOI();
// Interrupt re-enabled here
...
handle_interrupt();
}
handle_interrupt might switch to irq_thread(), but the hardware
interrupt is enabled by this point. So I guess the funky IRQ12
(curr=IRQ_12) could happen.
Haohui
On 04/13/2010 08:51 AM, Jan Stoess wrote:
But the current kernel runs (should, at least) non-preemptive and
irq_thread runs in kernel mode, so any pending IRQ shouldn't be
delivered until the next return to user.
Am I missing something??
-Jan
--
Jan Stoess
KIT/UKa System Architecture Group
Phone: +49 (721) 608-4056
Fax: +49 (721) 608-7664
http://os.ibds.kit.edu/stoess
*From:* Mai, Haohui [mailto:haohui....@gmail.com]
*Sent:* Tuesday, April 13, 2010 3:34 PM
*To:* Jan Stoess
*Cc:* l...@ira.uni-karlsruhe.de
*Subject:* Re: Race condition in interrupt handling
The interrupt is re-enabled by after local_apic.EOI() is called, which
means interrupt is enabled in irq_thread(). Therefore, irq_thread()
can be preempted by an interrupt at that time.
I enabled the trace statement at api/v4/interrupt.cc:172, what I can
saw during debugging is something like:
IRQ12 (curr=IRQ_12)
I do enable SMP in the kernel, but I don't think I enable any
migration right now, so everything should be running on CPU 0.
Haohui
On 04/13/2010 08:02 AM, Jan Stoess wrote:
This seems fishy to me. intctrl_t::unmask() should only be called by
irq_thread, which resides on the CPU the IRQ is routed to. Since it is
in the kernel, how can the new IRQ be delivered to the CPU at the
point you're referring to with (1) INTERRUPT COMES HERE? Again, does
this happen during IRQ migration? Maybe you can use the tracebuffer
(potentially even inserting some tracing statements at the critical
points yourself, e.g. via TRACE_IRQ_DETAILS() and tp_irq_mask, latter
of which you can set in the KDB menu, in the tracebuffer submenu "y")
and dump a corresponding trace log to this list?
Thanks again,
-Jan
--
Jan Stoess
KIT/UKa System Architecture Group
Phone: +49 (721) 608-4056
Fax: +49 (721) 608-7664
http://os.ibds.kit.edu/stoess