Jan Kiszka wrote:
> Jan Kiszka wrote:
>> Currently, I-pipe breaks the setting of IRQ affinities through Linux,
>> the root domain. This is because migrating IRQs while they are active is
>> a tricky business on x86, requiring special measures within the IRQ ack
>> path. And as this path is now used by non-root domains, the migration
>> code had to be deactivated.
>>
>> The following patch is a proof of concept for x86-64 how to overcome
>> this unfortunate limitation (if you want to isolate RT from non-RT
>> CPUs). The approach works without adding code to critical paths. First
>> tests inside KVM indicate that things work as expected, but more testing
>> on real iron is scheduled, e.g. to check MSI IRQs which I don't have in
>> my KVM environment.
>>
> 
> Here is version 2, now also including 32-bit support (untested).
> 
> Meanwhile I've run this patch on an real dual core box with MSI, and all
> works smoothly.
>

The idea looks good in any case. I will merge this next week unless a problem
arises during testing. Thanks,

> Jan
> ---
>  arch/x86/kernel/io_apic_32.c |   24 ++++++++++++++++++++++++
>  arch/x86/kernel/io_apic_64.c |   42 
> +++++++++++++++++++++++++++++++++++++-----
>  include/asm-x86/ipipe.h      |   11 +++++++++++
>  include/asm-x86/ipipe_64.h   |    5 +++--
>  include/linux/irq.h          |    3 +++
>  5 files changed, 78 insertions(+), 7 deletions(-)
> 
> Index: b/arch/x86/kernel/io_apic_64.c
> ===================================================================
> --- a/arch/x86/kernel/io_apic_64.c
> +++ b/arch/x86/kernel/io_apic_64.c
> @@ -174,7 +174,6 @@ static inline void io_apic_modify(unsign
>       writel(value, &io_apic->data);
>  }
>  
> -#ifndef CONFIG_IPIPE
>  static bool io_apic_level_ack_pending(unsigned int irq)
>  {
>       struct irq_pin_list *entry;
> @@ -203,7 +202,6 @@ static bool io_apic_level_ack_pending(un
>  
>       return false;
>  }
> -#endif /* !CONFIG_IPIPE */
>  
>  /*
>   * Synchronize the IO-APIC and the CPU by doing
> @@ -1436,7 +1434,6 @@ unlock:
>       irq_exit();
>  }
>  
> -#ifndef CONFIG_IPIPE
>  static void irq_complete_move(unsigned int irq)
>  {
>       struct irq_cfg *cfg = irq_cfg + irq;
> @@ -1456,11 +1453,34 @@ static void irq_complete_move(unsigned i
>               cfg->move_in_progress = 0;
>       }
>  }
> -#endif
> -#elif !defined(CONFIG_IPIPE)
> +#else
>  static inline void irq_complete_move(unsigned int irq) {}
>  #endif
>  
> +#ifdef CONFIG_IPIPE
> +static void move_apic_irq(unsigned int irq)
> +{
> +     struct irq_desc *desc = &irq_desc[irq];
> +
> +     if (desc->handle_irq == &handle_edge_irq) {
> +             spin_lock(&desc->lock);
> +             irq_complete_move(irq);
> +             move_native_irq(irq);
> +             spin_unlock(&desc->lock);
> +     } else if (desc->handle_irq == &handle_fasteoi_irq) {
> +             spin_lock(&desc->lock);
> +             irq_complete_move(irq);
> +             if (unlikely(desc->status & IRQ_MOVE_PENDING)) {
> +                     if (!io_apic_level_ack_pending(irq))
> +                             move_masked_irq(irq);
> +                     unmask_IO_APIC_irq(irq);
> +             }
> +             spin_unlock(&desc->lock);
> +     } else
> +             WARN_ON_ONCE(1);
> +}
> +#endif /* CONFIG_IPIPE */
> +
>  static void ack_apic_edge(unsigned int irq)
>  {
>  #ifndef CONFIG_IPIPE
> @@ -1544,6 +1564,9 @@ static struct irq_chip ioapic_chip __rea
>       .eoi            = ack_apic_level,
>  #ifdef CONFIG_SMP
>       .set_affinity   = set_ioapic_affinity_irq,
> +#ifdef CONFIG_IPIPE
> +     .move           = move_apic_irq,
> +#endif
>  #endif
>       .retrigger      = ioapic_retrigger_irq,
>  };
> @@ -2087,6 +2110,9 @@ static struct irq_chip msi_chip = {
>       .ack            = ack_apic_edge,
>  #ifdef CONFIG_SMP
>       .set_affinity   = set_msi_irq_affinity,
> +#ifdef CONFIG_IPIPE
> +     .move           = move_apic_irq,
> +#endif
>  #endif
>       .retrigger      = ioapic_retrigger_irq,
>  };
> @@ -2156,6 +2182,9 @@ struct irq_chip dmar_msi_type = {
>       .ack = ack_apic_edge,
>  #ifdef CONFIG_SMP
>       .set_affinity = dmar_msi_set_affinity,
> +#ifdef CONFIG_IPIPE
> +     .move = move_apic_irq,
> +#endif
>  #endif
>       .retrigger = ioapic_retrigger_irq,
>  };
> @@ -2225,6 +2254,9 @@ static struct irq_chip ht_irq_chip = {
>       .ack            = ack_apic_edge,
>  #ifdef CONFIG_SMP
>       .set_affinity   = set_ht_irq_affinity,
> +#ifdef CONFIG_IPIPE
> +     .move           = move_apic_irq,
> +#endif
>  #endif
>       .retrigger      = ioapic_retrigger_irq,
>  };
> Index: b/include/asm-x86/ipipe_64.h
> ===================================================================
> --- a/include/asm-x86/ipipe_64.h
> +++ b/include/asm-x86/ipipe_64.h
> @@ -144,10 +144,11 @@ static inline void __ipipe_call_root_vir
>       do {                                                            \
>               local_irq_enable_nohead(ipd);                           \
>               if (ipd == ipipe_root_domain) {                         \
> -                     if (likely(!ipipe_virtual_irq_p(irq)))          \
> +                     if (likely(!ipipe_virtual_irq_p(irq))) {        \
> +                             __ipipe_move_root_irq(irq);             \
>                               __ipipe_call_root_xirq_handler(         \
>                                       irq, (ipd)->irqs[irq].handler); \
> -                     else                                            \
> +                     } else                                          \
>                               __ipipe_call_root_virq_handler(         \
>                                       irq, (ipd)->irqs[irq].handler,  \
>                                       (ipd)->irqs[irq].cookie);       \
> Index: b/include/linux/irq.h
> ===================================================================
> --- a/include/linux/irq.h
> +++ b/include/linux/irq.h
> @@ -111,6 +111,9 @@ struct irq_chip {
>  
>       void            (*end)(unsigned int irq);
>       void            (*set_affinity)(unsigned int irq, cpumask_t dest);
> +#ifdef CONFIG_IPIPE
> +     void            (*move)(unsigned int irq);
> +#endif /* CONFIG_IPIPE */
>       int             (*retrigger)(unsigned int irq);
>       int             (*set_type)(unsigned int irq, unsigned int flow_type);
>       int             (*set_wake)(unsigned int irq, unsigned int on);
> Index: b/arch/x86/kernel/io_apic_32.c
> ===================================================================
> --- a/arch/x86/kernel/io_apic_32.c
> +++ b/arch/x86/kernel/io_apic_32.c
> @@ -1929,6 +1929,21 @@ static unsigned int startup_ioapic_irq(u
>       return was_pending;
>  }
>  
> +#if defined(CONFIG_IPIPE) && defined(CONFIG_SMP)
> +static void move_apic_irq(unsigned int irq)
> +{
> +     struct irq_desc *desc = &irq_desc[irq];
> +
> +     if (desc->handle_irq == &handle_edge_irq ||
> +         desc->handle_irq == &handle_fasteoi_irq) {
> +             spin_lock(&desc->lock);
> +             move_native_irq(irq);
> +             spin_unlock(&desc->lock);
> +     } else
> +             WARN_ON_ONCE(1);
> +}
> +#endif /* CONFIG_IPIPE && CONFIG_SMP */
> +
>  static void ack_ioapic_irq(unsigned int irq)
>  {
>  #ifndef CONFIG_IPIPE
> @@ -2018,6 +2033,9 @@ static struct irq_chip ioapic_chip __rea
>       .eoi            = ack_ioapic_quirk_irq,
>  #ifdef CONFIG_SMP
>       .set_affinity   = set_ioapic_affinity_irq,
> +#ifdef CONFIG_IPIPE
> +     .move           = move_apic_irq,
> +#endif
>  #endif
>       .retrigger      = ioapic_retrigger_irq,
>  };
> @@ -2600,6 +2618,9 @@ static struct irq_chip msi_chip = {
>       .ack            = ack_ioapic_irq,
>  #ifdef CONFIG_SMP
>       .set_affinity   = set_msi_irq_affinity,
> +#ifdef CONFIG_IPIPE
> +     .move           = move_apic_irq,
> +#endif
>  #endif
>       .retrigger      = ioapic_retrigger_irq,
>  };
> @@ -2680,6 +2701,9 @@ static struct irq_chip ht_irq_chip = {
>       .ack            = ack_ioapic_irq,
>  #ifdef CONFIG_SMP
>       .set_affinity   = set_ht_irq_affinity,
> +#ifdef CONFIG_IPIPE
> +     .move           = move_apic_irq,
> +#endif
>  #endif
>       .retrigger      = ioapic_retrigger_irq,
>  };
> Index: b/include/asm-x86/ipipe.h
> ===================================================================
> --- a/include/asm-x86/ipipe.h
> +++ b/include/asm-x86/ipipe.h
> @@ -118,6 +118,17 @@ int __ipipe_check_tickdev(const char *de
>  
>  #define __ipipe_root_tick_p(regs)    ((regs)->flags & X86_EFLAGS_IF)
>  
> +#ifdef CONFIG_SMP
> +#define __ipipe_move_root_irq(irq)                                   \
> +     do {                                                            \
> +             struct irq_chip *chip = irq_desc[irq].chip;             \
> +             if (irq < NR_IRQS && chip->move)                        \
> +                     chip->move(irq);                                \
> +     } while (0)
> +#else /* !CONFIG_SMP */
> +#define __ipipe_move_root_irq(irq)   do { } while (0)
> +#endif /* !CONFIG_SMP */
> +
>  #else /* !CONFIG_IPIPE */
>  
>  #define ipipe_update_tick_evtdev(evtdev)     do { } while (0)
> 
> _______________________________________________
> Adeos-main mailing list
> [email protected]
> https://mail.gna.org/listinfo/adeos-main
> 


-- 
Philippe.

_______________________________________________
Adeos-main mailing list
[email protected]
https://mail.gna.org/listinfo/adeos-main

Reply via email to