From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753801AbdCMXnt (ORCPT ); Mon, 13 Mar 2017 19:43:49 -0400 Received: from gate.crashing.org ([63.228.1.57]:45999 "EHLO gate.crashing.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752354AbdCMXnj (ORCPT ); Mon, 13 Mar 2017 19:43:39 -0400 Message-ID: <1489448547.2174.17.camel@kernel.crashing.org> Subject: Re: [RFC] powerpc: handle simultanneous interrupts at once From: Benjamin Herrenschmidt To: Christophe Leroy , Paul Mackerras , Michael Ellerman , Scott Wood Cc: linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Date: Tue, 14 Mar 2017 10:42:27 +1100 In-Reply-To: <20170310111152.1B3BF679C4@localhost.localdomain> References: <20170310111152.1B3BF679C4@localhost.localdomain> Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.22.5 (3.22.5-1.fc25) Mime-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, 2017-03-10 at 12:11 +0100, Christophe Leroy wrote: > It often happens to have simultanneous interrupts, for instance > when having double Ethernet attachment. With the current > implementation, we suffer the cost of kernel entry/exit for each > interrupt. > > This patch introduces a loop in __do_irq() to handle all interrupts > at once before returning. > > Signed-off-by: Christophe Leroy > --- >  arch/powerpc/include/asm/hw_irq.h |  6 ++++++ >  arch/powerpc/kernel/irq.c         | 22 +++++++++++++++------- >  2 files changed, 21 insertions(+), 7 deletions(-) > > diff --git a/arch/powerpc/include/asm/hw_irq.h > b/arch/powerpc/include/asm/hw_irq.h > index eba60416536e..d69ae5846955 100644 > --- a/arch/powerpc/include/asm/hw_irq.h > +++ b/arch/powerpc/include/asm/hw_irq.h > @@ -123,6 +123,11 @@ static inline void may_hard_irq_enable(void) >   __hard_irq_enable(); >  } >   > +static inline void may_hard_irq_disable(void) > +{ > + __hard_irq_disable(); > +} > + >  static inline bool arch_irq_disabled_regs(struct pt_regs *regs) >  { >   return !regs->softe; > @@ -204,6 +209,7 @@ static inline bool arch_irq_disabled_regs(struct > pt_regs *regs) >  } >   >  static inline void may_hard_irq_enable(void) { } > +static inline void may_hard_irq_disable(void) { } >   >  #endif /* CONFIG_PPC64 */ >   > diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c > index a018f5cae899..28aca510c166 100644 > --- a/arch/powerpc/kernel/irq.c > +++ b/arch/powerpc/kernel/irq.c > @@ -515,14 +515,22 @@ void __do_irq(struct pt_regs *regs) >    */ >   irq = ppc_md.get_irq(); >   > - /* We can hard enable interrupts now to allow perf > interrupts */ > - may_hard_irq_enable(); > + do { > + /* We can hard enable interrupts now to allow perf > interrupts */ > + may_hard_irq_enable(); > + > + /* And finally process it */ > + if (unlikely(!irq)) > + __this_cpu_inc(irq_stat.spurious_irqs); > + else > + generic_handle_irq(irq); > + > + may_hard_irq_disable(); Not sure the above is that useful. If another interrupt is pending, on ppc64 at least, you will have got it right at may_hard_irq_enable() which would have caused a hard-disable for you anyway. > - /* And finally process it */ > - if (unlikely(!irq)) > - __this_cpu_inc(irq_stat.spurious_irqs); > - else > - generic_handle_irq(irq); > + irq = ppc_md.get_irq(); > + } while (irq); > + > + may_hard_irq_enable(); >   >   trace_irq_exit(regs); >