On Mon, 25 Jun 2019, Gleixner, Thomas wrote: > > It's actually deep idle, which makes it slow to come out and service the > interrupt. I didn't have time to check the uploaded log (wife pulled the reins :)), only a previous one, which was heavily contaminated with debug printk-s, so I quickly created a new one. That one showed hrtimer interrupts before the UART's, which was confusing a bit, but checking again, that was ~15msec before, and the core went to idle, as you wrote. > /* > * Internal function to unregister an irqaction - used to free > * regular and special interrupts that are part of the architecture. > @@ -1664,6 +1675,7 @@ static struct irqaction *__free_irq(stru > unsigned irq = desc->irq_data.irq; > struct irqaction *action, **action_ptr; > unsigned long flags; > + bool sync = false; > > WARN(in_interrupt(), "Trying to free IRQ %d from IRQ context!\n", irq); > > @@ -1702,6 +1714,8 @@ static struct irqaction *__free_irq(stru > irq_settings_clr_disable_unlazy(desc); > /* Only shutdown. Deactivate after synchronize_irq() */ > irq_shutdown(desc); > + if (irq_desc_get_chip(desc)->irq_sync) > + sync = true; > } > > #ifdef CONFIG_SMP > @@ -1729,6 +1743,9 @@ static struct irqaction *__free_irq(stru > > unregister_handler_proc(irq, action); > > + if (sync) > + sync_on_free(desc); > + > /* Make sure it's not being used on another CPU: */ > synchronize_hardirq(irq); > Actually, I tried to print IO-APIC's IRR at the end of mask_ioapic_irq() on Friday, and it always showed 0. I did that again. Here's the patch, and debug output: diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 53aa234a68..b0f655c61f 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -472,6 +472,17 @@ static void mask_ioapic_irq(struct irq_data *irq_data) raw_spin_lock_irqsave(&ioapic_lock, flags); io_apic_modify_irq(data, ~0, IO_APIC_REDIR_MASKED, &io_apic_sync); + + { + struct irq_pin_list *entry; + + for_each_irq_pin(entry, data->irq_2_pin) { + struct IO_APIC_route_entry re; + re = __ioapic_read_entry(entry->apic, entry->pin); + printk("%d -> %x\n", entry->pin, re.irr); + } + } + raw_spin_unlock_irqrestore(&ioapic_lock, flags); } # dmesg -c >/dev/null; taskset 1 cat /dev/ttyS1 & >/dev/null ; PID=$!; usleep 100000; kill $PID; dmesg -c <4>3 -> 0 <0>do_IRQ: 1.44 No irq handler for vector [1]+ Terminated taskset 1 cat /dev/ttyS1 So I assume, only the local APIC has info about the pending IRQ. But as free_irq() is running on CPU#0 and the IRQ is pending on CPU#1, CPU#0 cannot read CPU#1's local APIC, right? Or maybe I'm missing something? Robert