Re: "No irq handler for vector" problem

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux