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
> 


Reply via email to