Fwd: [PATCH v2][for 2.6.28] powerpc/mpic: Add support for MPICs that only support a single CPU destination - Kernel

This is a discussion on Fwd: [PATCH v2][for 2.6.28] powerpc/mpic: Add support for MPICs that only support a single CPU destination - Kernel ; Greg, Can you pick this up for stable-2.6.27. - k Begin forwarded message: > From: Kumar Gala > Date: October 28, 2008 11:01:39 PM CDT > Cc: linuxppc-dev@ozlabs.org , tglx@linutronix.de , Paul Mackerras > >, davem@davemloft.net > Subject: [PATCH v2][for ...

+ Reply to Thread
Results 1 to 3 of 3

Thread: Fwd: [PATCH v2][for 2.6.28] powerpc/mpic: Add support for MPICs that only support a single CPU destination

  1. Fwd: [PATCH v2][for 2.6.28] powerpc/mpic: Add support for MPICs that only support a single CPU destination

    Greg,

    Can you pick this up for stable-2.6.27.

    - k

    Begin forwarded message:

    > From: Kumar Gala
    > Date: October 28, 2008 11:01:39 PM CDT
    > Cc: linuxppc-dev@ozlabs.org, tglx@linutronix.de, Paul Mackerras
    > >, davem@davemloft.net

    > Subject: [PATCH v2][for 2.6.28] powerpc/mpic: Add support for MPICs
    > that only support a single CPU destination
    >
    > The Freescale implementation of MPIC only allows a single CPU
    > destination
    > for non-IPI interrupts. We add a flag to the mpic_init to distinquish
    > these variants of MPIC. We pull in the irq_choose_cpu from sparc64 to
    > select a single CPU as the destination of the interrupt.
    >
    > This is to deal with the fact that the default smp affinity was
    > changed by commit 18404756765c713a0be4eb1082920c04822ce588.
    >
    > Signed-off-by: Kumar Gala
    > ---
    >
    > Changed requested by Ben to use irq_choose_cpu from sparc64 land.
    >
    > - k
    >
    > arch/powerpc/include/asm/mpic.h | 2 +
    > arch/powerpc/platforms/85xx/mpc85xx_ds.c | 3 +-
    > arch/powerpc/platforms/86xx/pic.c | 3 +-
    > arch/powerpc/sysdev/mpic.c | 59 +++++++++++++++++++++
    > +++++++--
    > 4 files changed, 61 insertions(+), 6 deletions(-)
    >
    > diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/
    > asm/mpic.h
    > index 34d9ac4..c2ccca5 100644
    > --- a/arch/powerpc/include/asm/mpic.h
    > +++ b/arch/powerpc/include/asm/mpic.h
    > @@ -355,6 +355,8 @@ struct mpic
    > #define MPIC_NO_BIAS 0x00000400
    > /* Ignore NIRQS as reported by FRR */
    > #define MPIC_BROKEN_FRR_NIRQS 0x00000800
    > +/* Destination only supports a single CPU at a time */
    > +#define MPIC_SINGLE_DEST_CPU 0x00001000
    >
    > /* MPIC HW modification ID */
    > #define MPIC_REGSET_MASK 0xf0000000
    > diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/
    > platforms/85xx/mpc85xx_ds.c
    > index 483b65c..613bf8c 100644
    > --- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
    > +++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
    > @@ -78,7 +78,8 @@ void __init mpc85xx_ds_pic_init(void)
    >
    > mpic = mpic_alloc(np, r.start,
    > MPIC_PRIMARY | MPIC_WANTS_RESET |
    > - MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS,
    > + MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS |
    > + MPIC_SINGLE_DEST_CPU,
    > 0, 256, " OpenPIC ");
    > BUG_ON(mpic == NULL);
    > of_node_put(np);
    > diff --git a/arch/powerpc/platforms/86xx/pic.c b/arch/powerpc/
    > platforms/86xx/pic.c
    > index 8881c5d..668275d 100644
    > --- a/arch/powerpc/platforms/86xx/pic.c
    > +++ b/arch/powerpc/platforms/86xx/pic.c
    > @@ -44,7 +44,8 @@ void __init mpc86xx_init_irq(void)
    >
    > mpic = mpic_alloc(np, res.start,
    > MPIC_PRIMARY | MPIC_WANTS_RESET |
    > - MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS,
    > + MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS |
    > + MPIC_SINGLE_DEST_CPU,
    > 0, 256, " MPIC ");
    > of_node_put(np);
    > BUG_ON(mpic == NULL);
    > diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
    > index 8e3478c..f6299cc 100644
    > --- a/arch/powerpc/sysdev/mpic.c
    > +++ b/arch/powerpc/sysdev/mpic.c
    > @@ -563,6 +563,51 @@ static void __init mpic_scan_ht_pics(struct
    > mpic *mpic)
    >
    > #endif /* CONFIG_MPIC_U3_HT_IRQS */
    >
    > +#ifdef CONFIG_SMP
    > +static int irq_choose_cpu(unsigned int virt_irq)
    > +{
    > + cpumask_t mask = irq_desc[virt_irq].affinity;
    > + int cpuid;
    > +
    > + if (cpus_equal(mask, CPU_MASK_ALL)) {
    > + static int irq_rover;
    > + static DEFINE_SPINLOCK(irq_rover_lock);
    > + unsigned long flags;
    > +
    > + /* Round-robin distribution... */
    > + do_round_robin:
    > + spin_lock_irqsave(&irq_rover_lock, flags);
    > +
    > + while (!cpu_online(irq_rover)) {
    > + if (++irq_rover >= NR_CPUS)
    > + irq_rover = 0;
    > + }
    > + cpuid = irq_rover;
    > + do {
    > + if (++irq_rover >= NR_CPUS)
    > + irq_rover = 0;
    > + } while (!cpu_online(irq_rover));
    > +
    > + spin_unlock_irqrestore(&irq_rover_lock, flags);
    > + } else {
    > + cpumask_t tmp;
    > +
    > + cpus_and(tmp, cpu_online_map, mask);
    > +
    > + if (cpus_empty(tmp))
    > + goto do_round_robin;
    > +
    > + cpuid = first_cpu(tmp);
    > + }
    > +
    > + return cpuid;
    > +}
    > +#else
    > +static int irq_choose_cpu(unsigned int virt_irq)
    > +{
    > + return hard_smp_processor_id();
    > +}
    > +#endif
    >
    > #define mpic_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq)
    >
    > @@ -777,12 +822,18 @@ void mpic_set_affinity(unsigned int irq,
    > cpumask_t cpumask)
    > struct mpic *mpic = mpic_from_irq(irq);
    > unsigned int src = mpic_irq_to_hw(irq);
    >
    > - cpumask_t tmp;
    > + if (mpic->flags & MPIC_SINGLE_DEST_CPU) {
    > + int cpuid = irq_choose_cpu(irq);
    >
    > - cpus_and(tmp, cpumask, cpu_online_map);
    > + mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), 1 << cpuid);
    > + } else {
    > + cpumask_t tmp;
    >
    > - mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION),
    > - mpic_physmask(cpus_addr(tmp)[0]));
    > + cpus_and(tmp, cpumask, cpu_online_map);
    > +
    > + mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION),
    > + mpic_physmask(cpus_addr(tmp)[0]));
    > + }
    > }
    >
    > static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned
    > int type)
    > --
    > 1.5.5.1
    >
    > _______________________________________________
    > Linuxppc-dev mailing list
    > Linuxppc-dev@ozlabs.org
    > https://ozlabs.org/mailman/listinfo/linuxppc-dev

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  2. Re: Fwd: [PATCH v2][for 2.6.28] powerpc/mpic: Add support for MPICs that only support a single CPU destination

    On Wed, Nov 05, 2008 at 05:38:48PM -0600, Kumar Gala wrote:
    > Greg,
    >
    > Can you pick this up for stable-2.6.27.


    I don't see this in Linus's tree right now.

    Am I missing it? Or do you know what the git commit id is?

    thanks,

    greg k-h

    >> From: Kumar Gala
    >> Date: October 28, 2008 11:01:39 PM CDT
    >> Cc: linuxppc-dev@ozlabs.org, tglx@linutronix.de, Paul Mackerras
    >> , davem@davemloft.net
    >> Subject: [PATCH v2][for 2.6.28] powerpc/mpic: Add support for MPICs that
    >> only support a single CPU destination
    >>
    >> The Freescale implementation of MPIC only allows a single CPU destination
    >> for non-IPI interrupts. We add a flag to the mpic_init to distinquish
    >> these variants of MPIC. We pull in the irq_choose_cpu from sparc64 to
    >> select a single CPU as the destination of the interrupt.
    >>
    >> This is to deal with the fact that the default smp affinity was
    >> changed by commit 18404756765c713a0be4eb1082920c04822ce588.
    >>
    >> Signed-off-by: Kumar Gala
    >> ---
    >>
    >> Changed requested by Ben to use irq_choose_cpu from sparc64 land.
    >>
    >> - k
    >>
    >> arch/powerpc/include/asm/mpic.h | 2 +
    >> arch/powerpc/platforms/85xx/mpc85xx_ds.c | 3 +-
    >> arch/powerpc/platforms/86xx/pic.c | 3 +-
    >> arch/powerpc/sysdev/mpic.c | 59
    >> ++++++++++++++++++++++++++++--
    >> 4 files changed, 61 insertions(+), 6 deletions(-)
    >>
    >> diff --git a/arch/powerpc/include/asm/mpic.h
    >> b/arch/powerpc/include/asm/mpic.h
    >> index 34d9ac4..c2ccca5 100644
    >> --- a/arch/powerpc/include/asm/mpic.h
    >> +++ b/arch/powerpc/include/asm/mpic.h
    >> @@ -355,6 +355,8 @@ struct mpic
    >> #define MPIC_NO_BIAS 0x00000400
    >> /* Ignore NIRQS as reported by FRR */
    >> #define MPIC_BROKEN_FRR_NIRQS 0x00000800
    >> +/* Destination only supports a single CPU at a time */
    >> +#define MPIC_SINGLE_DEST_CPU 0x00001000
    >>
    >> /* MPIC HW modification ID */
    >> #define MPIC_REGSET_MASK 0xf0000000
    >> diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
    >> b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
    >> index 483b65c..613bf8c 100644
    >> --- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
    >> +++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
    >> @@ -78,7 +78,8 @@ void __init mpc85xx_ds_pic_init(void)
    >>
    >> mpic = mpic_alloc(np, r.start,
    >> MPIC_PRIMARY | MPIC_WANTS_RESET |
    >> - MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS,
    >> + MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS |
    >> + MPIC_SINGLE_DEST_CPU,
    >> 0, 256, " OpenPIC ");
    >> BUG_ON(mpic == NULL);
    >> of_node_put(np);
    >> diff --git a/arch/powerpc/platforms/86xx/pic.c
    >> b/arch/powerpc/platforms/86xx/pic.c
    >> index 8881c5d..668275d 100644
    >> --- a/arch/powerpc/platforms/86xx/pic.c
    >> +++ b/arch/powerpc/platforms/86xx/pic.c
    >> @@ -44,7 +44,8 @@ void __init mpc86xx_init_irq(void)
    >>
    >> mpic = mpic_alloc(np, res.start,
    >> MPIC_PRIMARY | MPIC_WANTS_RESET |
    >> - MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS,
    >> + MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS |
    >> + MPIC_SINGLE_DEST_CPU,
    >> 0, 256, " MPIC ");
    >> of_node_put(np);
    >> BUG_ON(mpic == NULL);
    >> diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
    >> index 8e3478c..f6299cc 100644
    >> --- a/arch/powerpc/sysdev/mpic.c
    >> +++ b/arch/powerpc/sysdev/mpic.c
    >> @@ -563,6 +563,51 @@ static void __init mpic_scan_ht_pics(struct mpic
    >> *mpic)
    >>
    >> #endif /* CONFIG_MPIC_U3_HT_IRQS */
    >>
    >> +#ifdef CONFIG_SMP
    >> +static int irq_choose_cpu(unsigned int virt_irq)
    >> +{
    >> + cpumask_t mask = irq_desc[virt_irq].affinity;
    >> + int cpuid;
    >> +
    >> + if (cpus_equal(mask, CPU_MASK_ALL)) {
    >> + static int irq_rover;
    >> + static DEFINE_SPINLOCK(irq_rover_lock);
    >> + unsigned long flags;
    >> +
    >> + /* Round-robin distribution... */
    >> + do_round_robin:
    >> + spin_lock_irqsave(&irq_rover_lock, flags);
    >> +
    >> + while (!cpu_online(irq_rover)) {
    >> + if (++irq_rover >= NR_CPUS)
    >> + irq_rover = 0;
    >> + }
    >> + cpuid = irq_rover;
    >> + do {
    >> + if (++irq_rover >= NR_CPUS)
    >> + irq_rover = 0;
    >> + } while (!cpu_online(irq_rover));
    >> +
    >> + spin_unlock_irqrestore(&irq_rover_lock, flags);
    >> + } else {
    >> + cpumask_t tmp;
    >> +
    >> + cpus_and(tmp, cpu_online_map, mask);
    >> +
    >> + if (cpus_empty(tmp))
    >> + goto do_round_robin;
    >> +
    >> + cpuid = first_cpu(tmp);
    >> + }
    >> +
    >> + return cpuid;
    >> +}
    >> +#else
    >> +static int irq_choose_cpu(unsigned int virt_irq)
    >> +{
    >> + return hard_smp_processor_id();
    >> +}
    >> +#endif
    >>
    >> #define mpic_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq)
    >>
    >> @@ -777,12 +822,18 @@ void mpic_set_affinity(unsigned int irq, cpumask_t
    >> cpumask)
    >> struct mpic *mpic = mpic_from_irq(irq);
    >> unsigned int src = mpic_irq_to_hw(irq);
    >>
    >> - cpumask_t tmp;
    >> + if (mpic->flags & MPIC_SINGLE_DEST_CPU) {
    >> + int cpuid = irq_choose_cpu(irq);
    >>
    >> - cpus_and(tmp, cpumask, cpu_online_map);
    >> + mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), 1 << cpuid);
    >> + } else {
    >> + cpumask_t tmp;
    >>
    >> - mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION),
    >> - mpic_physmask(cpus_addr(tmp)[0]));
    >> + cpus_and(tmp, cpumask, cpu_online_map);
    >> +
    >> + mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION),
    >> + mpic_physmask(cpus_addr(tmp)[0]));
    >> + }
    >> }
    >>
    >> static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int
    >> type)
    >> --
    >> 1.5.5.1
    >>
    >> _______________________________________________
    >> Linuxppc-dev mailing list
    >> Linuxppc-dev@ozlabs.org
    >> https://ozlabs.org/mailman/listinfo/linuxppc-dev

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  3. Re: Fwd: [PATCH v2][for 2.6.28] powerpc/mpic: Add support for MPICs that only support a single CPU destination

    Greg KH writes:

    > > Can you pick this up for stable-2.6.27.

    >
    > I don't see this in Linus's tree right now.
    >
    > Am I missing it? Or do you know what the git commit id is?


    It's 3c10c9c45e290022ca7d2aa1ad33a0b6ed767520. I changed the title to
    "powerpc/mpic: Fix regression caused by change of default IRQ
    affinity" and expanded the patch description to emphasize that it was
    fixing a regression rather than just adding a feature.

    Paul.
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

+ Reply to Thread