On 01.03.22 21:21, Jan Kiszka wrote: > On 01.03.22 13:52, Florian Bezdeka wrote: >> The CPU hotplugging code might re-trigger a vector. In that case the >> vector is in the VECTOR_RETRIGGERED state. With this patch applied ipipe >> does no longer call BUG() for such vectors. >> > > Doesn't this also avoids a BUG for spurious vectors (provided they can > exist for other reasons than CPU offlining)?
Yes it does. Forgot to mention that... > >> This is a backport from the 4.19 and 5.4 ipipe branches handling the >> VECTOR_SHUTDOWN state. The VECTOR_SHUTDOWN case itself does not exist in >> 4.4, but the VECTOR_RETRIGGERED case does. >> >> __ipipe_handle_irq() is now synchronized with do_IRQ(). >> >> Signed-off-by: Florian Bezdeka <[email protected]> >> --- >> arch/x86/kernel/ipipe.c | 44 +++++++++++++++++++++++++++++++---------- >> 1 file changed, 34 insertions(+), 10 deletions(-) >> >> diff --git a/arch/x86/kernel/ipipe.c b/arch/x86/kernel/ipipe.c >> index 739b5c37ec7b..6020739256f9 100644 >> --- a/arch/x86/kernel/ipipe.c >> +++ b/arch/x86/kernel/ipipe.c >> @@ -33,6 +33,7 @@ >> #include <linux/mm.h> >> #include <linux/kgdb.h> >> #include <linux/ipipe_tickdev.h> >> +#include <linux/ratelimit.h> >> #include <asm/asm-offsets.h> >> #include <asm/unistd.h> >> #include <asm/processor.h> >> @@ -428,22 +429,44 @@ skip_kgdb: >> return 0; >> } >> >> +static inline int __ipipe_irq_from_vector(int vector, int *irq) >> +{ >> + struct irq_desc *desc; >> + >> + if (vector >= FIRST_SYSTEM_VECTOR) { >> + *irq = ipipe_apic_vector_irq(vector); >> + return 0; >> + } >> + >> + desc = __this_cpu_read(vector_irq[vector]); >> + if (likely(!IS_ERR_OR_NULL(desc))) { >> + *irq = irq_desc_get_irq(desc); >> + return 0; >> + } >> + >> +#ifdef CONFIG_X86_LOCAL_APIC >> + __ack_APIC_irq(); >> +#endif >> + >> + if (desc == VECTOR_UNUSED) { >> + pr_emerg_ratelimited("%s: %d.%d Unexpected IRQ trap\n", >> + __func__, smp_processor_id(), vector); >> + } else { >> + __this_cpu_write(vector_irq[vector], VECTOR_UNUSED); >> + } >> + >> + return -1; >> +} >> + >> int __ipipe_handle_irq(struct pt_regs *regs) >> { >> struct ipipe_percpu_data *p = __ipipe_raw_cpu_ptr(&ipipe_percpu); >> int irq, vector = regs->orig_ax, flags = 0; >> struct pt_regs *tick_regs; >> - struct irq_desc *desc; >> >> if (likely(vector < 0)) { >> - vector = ~vector; >> - if (vector >= FIRST_SYSTEM_VECTOR) >> - irq = ipipe_apic_vector_irq(vector); >> - else { >> - desc = __this_cpu_read(vector_irq[vector]); >> - BUG_ON(IS_ERR_OR_NULL(desc)); >> - irq = irq_desc_get_irq(desc); >> - } >> + if (__ipipe_irq_from_vector(~vector, &irq) < 0) >> + goto out; >> } else { /* Software-generated. */ >> irq = vector; >> flags = IPIPE_IRQF_NOACK; >> @@ -477,7 +500,8 @@ int __ipipe_handle_irq(struct pt_regs *regs) >> __ipipe_call_mayday(regs); >> >> ipipe_trace_irqend(irq, regs); >> - >> + >> +out: >> if (!__ipipe_root_p || >> test_bit(IPIPE_STALL_FLAG, &__ipipe_root_status)) >> return 0; > > Thanks, applied. > > Jan >
