Message ID | 1603448245-79429-2-git-send-email-guoren@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [1/3] irqchip/irq-sifive-plic: Fixup wrong size of xxx_PER_HART and reg base | expand |
On Fri, Oct 23, 2020 at 3:48 PM <guoren@kernel.org> wrote: > > From: Guo Ren <guoren@linux.alibaba.com> > > If "echo 3 > /proc/irq/1/smp_affinity", we want irq 1 could be > broadcast to CPU0 & CPU1 and one of them would pick up the irq > handler. > > But current implementation couldn't let multi CPUs process the > same IRQ concurrent. > > Signed-off-by: Guo Ren <guoren@linux.alibaba.com> > --- > drivers/irqchip/irq-sifive-plic.c | 23 ++++++----------------- > 1 file changed, 6 insertions(+), 17 deletions(-) > > diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c > index 2e56576..0003322 100644 > --- a/drivers/irqchip/irq-sifive-plic.c > +++ b/drivers/irqchip/irq-sifive-plic.c > @@ -114,15 +114,12 @@ static inline void plic_irq_toggle(const struct cpumask *mask, > static void plic_irq_unmask(struct irq_data *d) > { > struct cpumask amask; > - unsigned int cpu; > struct plic_priv *priv = irq_get_chip_data(d->irq); > > cpumask_and(&amask, &priv->lmask, cpu_online_mask); > - cpu = cpumask_any_and(irq_data_get_affinity_mask(d), > - &amask); > - if (WARN_ON_ONCE(cpu >= nr_cpu_ids)) > - return; > - plic_irq_toggle(cpumask_of(cpu), d, 1); > + cpumask_and(&amask, &amask, irq_data_get_affinity_mask(d)); > + > + plic_irq_toggle(&amask, d, 1); > } > > static void plic_irq_mask(struct irq_data *d) > @@ -136,24 +133,16 @@ static void plic_irq_mask(struct irq_data *d) > static int plic_set_affinity(struct irq_data *d, > const struct cpumask *mask_val, bool force) > { > - unsigned int cpu; > struct cpumask amask; > struct plic_priv *priv = irq_get_chip_data(d->irq); > > cpumask_and(&amask, &priv->lmask, mask_val); > + cpumask_and(&amask, &amask, cpu_online_mask); > > - if (force) > - cpu = cpumask_first(&amask); > - else > - cpu = cpumask_any_and(&amask, cpu_online_mask); > - > - if (cpu >= nr_cpu_ids) > - return -EINVAL; > + irq_data_update_effective_affinity(d, &amask); > > plic_irq_toggle(&priv->lmask, d, 0); > - plic_irq_toggle(cpumask_of(cpu), d, 1); > - > - irq_data_update_effective_affinity(d, cpumask_of(cpu)); > + plic_irq_toggle(&amask, d, 1); > > return IRQ_SET_MASK_OK_DONE; > } > -- > 2.7.4 > In the past, a similar patch was proposed by Zong Li (SiFive). We have good reasons to not allow multiple CPUs handle the same IRQ. Refer, https://lkml.org/lkml/2020/4/26/201 NACK from my side. Regards, Anup
On Fri, Oct 23, 2020 at 8:17 PM Anup Patel <anup@brainfault.org> wrote: > > On Fri, Oct 23, 2020 at 3:48 PM <guoren@kernel.org> wrote: > > > > From: Guo Ren <guoren@linux.alibaba.com> > > > > If "echo 3 > /proc/irq/1/smp_affinity", we want irq 1 could be > > broadcast to CPU0 & CPU1 and one of them would pick up the irq > > handler. > > > > But current implementation couldn't let multi CPUs process the > > same IRQ concurrent. > > > > Signed-off-by: Guo Ren <guoren@linux.alibaba.com> > > --- > > drivers/irqchip/irq-sifive-plic.c | 23 ++++++----------------- > > 1 file changed, 6 insertions(+), 17 deletions(-) > > > > diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c > > index 2e56576..0003322 100644 > > --- a/drivers/irqchip/irq-sifive-plic.c > > +++ b/drivers/irqchip/irq-sifive-plic.c > > @@ -114,15 +114,12 @@ static inline void plic_irq_toggle(const struct cpumask *mask, > > static void plic_irq_unmask(struct irq_data *d) > > { > > struct cpumask amask; > > - unsigned int cpu; > > struct plic_priv *priv = irq_get_chip_data(d->irq); > > > > cpumask_and(&amask, &priv->lmask, cpu_online_mask); > > - cpu = cpumask_any_and(irq_data_get_affinity_mask(d), > > - &amask); > > - if (WARN_ON_ONCE(cpu >= nr_cpu_ids)) > > - return; > > - plic_irq_toggle(cpumask_of(cpu), d, 1); > > + cpumask_and(&amask, &amask, irq_data_get_affinity_mask(d)); > > + > > + plic_irq_toggle(&amask, d, 1); > > } > > > > static void plic_irq_mask(struct irq_data *d) > > @@ -136,24 +133,16 @@ static void plic_irq_mask(struct irq_data *d) > > static int plic_set_affinity(struct irq_data *d, > > const struct cpumask *mask_val, bool force) > > { > > - unsigned int cpu; > > struct cpumask amask; > > struct plic_priv *priv = irq_get_chip_data(d->irq); > > > > cpumask_and(&amask, &priv->lmask, mask_val); > > + cpumask_and(&amask, &amask, cpu_online_mask); > > > > - if (force) > > - cpu = cpumask_first(&amask); > > - else > > - cpu = cpumask_any_and(&amask, cpu_online_mask); > > - > > - if (cpu >= nr_cpu_ids) > > - return -EINVAL; > > + irq_data_update_effective_affinity(d, &amask); > > > > plic_irq_toggle(&priv->lmask, d, 0); > > - plic_irq_toggle(cpumask_of(cpu), d, 1); > > - > > - irq_data_update_effective_affinity(d, cpumask_of(cpu)); > > + plic_irq_toggle(&amask, d, 1); > > > > return IRQ_SET_MASK_OK_DONE; > > } > > -- > > 2.7.4 > > > > In the past, a similar patch was proposed by Zong Li (SiFive). We > have good reasons to not allow multiple CPUs handle the same IRQ. > > Refer, https://lkml.org/lkml/2020/4/26/201 > > NACK from my side. Thx for sharing the information, I agree with Zong Li & Greentime's aspect: Don't limit the usage of PLIC! We could let (one hart -> one irq) as default. I also agree that using irq broadcast indiscriminately can cause performance problems. (Anup and Mark Z's view) I think you've discussed enough at that time and l won't persist the patch.
diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c index 2e56576..0003322 100644 --- a/drivers/irqchip/irq-sifive-plic.c +++ b/drivers/irqchip/irq-sifive-plic.c @@ -114,15 +114,12 @@ static inline void plic_irq_toggle(const struct cpumask *mask, static void plic_irq_unmask(struct irq_data *d) { struct cpumask amask; - unsigned int cpu; struct plic_priv *priv = irq_get_chip_data(d->irq); cpumask_and(&amask, &priv->lmask, cpu_online_mask); - cpu = cpumask_any_and(irq_data_get_affinity_mask(d), - &amask); - if (WARN_ON_ONCE(cpu >= nr_cpu_ids)) - return; - plic_irq_toggle(cpumask_of(cpu), d, 1); + cpumask_and(&amask, &amask, irq_data_get_affinity_mask(d)); + + plic_irq_toggle(&amask, d, 1); } static void plic_irq_mask(struct irq_data *d) @@ -136,24 +133,16 @@ static void plic_irq_mask(struct irq_data *d) static int plic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, bool force) { - unsigned int cpu; struct cpumask amask; struct plic_priv *priv = irq_get_chip_data(d->irq); cpumask_and(&amask, &priv->lmask, mask_val); + cpumask_and(&amask, &amask, cpu_online_mask); - if (force) - cpu = cpumask_first(&amask); - else - cpu = cpumask_any_and(&amask, cpu_online_mask); - - if (cpu >= nr_cpu_ids) - return -EINVAL; + irq_data_update_effective_affinity(d, &amask); plic_irq_toggle(&priv->lmask, d, 0); - plic_irq_toggle(cpumask_of(cpu), d, 1); - - irq_data_update_effective_affinity(d, cpumask_of(cpu)); + plic_irq_toggle(&amask, d, 1); return IRQ_SET_MASK_OK_DONE; }