All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michael Ellerman <michael@ellerman.id.au>
To: miltonm@bga.com
Cc: linuxppc-dev@ozlabs.org, Paul Mackerras <paulus@samba.org>
Subject: Re: [PATCH] powerpc: EOI spurious irqs during boot so they can be reenabled later
Date: Wed, 06 Aug 2008 14:53:54 +1000	[thread overview]
Message-ID: <1217998434.7893.16.camel@localhost> (raw)
In-Reply-To: <489912b6.cc.1809.1931903668@bga.com>

On Tue, 2008-08-05 at 20:55 -0600, miltonm wrote:
> ----- Original Message Follows -----
> From: Michael Ellerman <michael@ellerman.id.au>
> To: Paul Mackerras <paulus@samba.org>
> Cc: <linuxppc-dev@ozlabs.org>, Milton Miller
> <miltonm@bga.com>, Segher Boessenkool
> <segher@kernel.crashing.org>
> Subject: [PATCH] powerpc: EOI spurious irqs during boot so
> they can be reenabled later
> Date: Wed,  6 Aug 2008 12:03:37 +1000 (EST)
>  
> > In the xics code, if we receive an irq during boot that
> > hasn't been setup yet - ie. we have no reverse mapping for
> > it - we mask the irq so we don't hear from it again.
> > 
> > Later on if someone request_irq()'s that irq, we'll unmask
> > it but it will still never fire. This is because we never
> > EOI'ed the irq when we originally received it - when it
> > was spurious.
> > 
> > This can be reproduced trivially by banging the keyboard
> > while kexec'ing on a P5 LPAR, even though the hvc_console
> > driver request's the console irq, the console is
> > non-functional because we're receiving no console
> > interrupts.
> > 
>  
> which means some driver didn't disable interrupts on its
> shutdown, but I digress.

But in the case of kdump the driver never gets a chance to shutdown its
irq, but I digress too :)

> > diff --git a/arch/powerpc/platforms/pseries/xics.c
> > b/arch/powerpc/platforms/pseries/xics.c index
> > 0fc830f..4c692b2 100644 ---
> > a/arch/powerpc/platforms/pseries/xics.c +++
> > b/arch/powerpc/platforms/pseries/xics.c @@ -321,21 +321,26
> > @@ static unsigned int xics_startup(unsigned int virq)
> >      return 0;
> >  }
> >  
> > +static void xics_eoi_hwirq_direct(unsigned int hwirq)
> > +{
> > +    iosync();
> > +    direct_xirr_info_set((0xff << 24) | hwirq);
> > +}
> > +
> >  static void xics_eoi_direct(unsigned int virq)
> >  {
> > -    unsigned int irq = (unsigned int)irq_map[virq].hwirq;
> > +    xics_eoi_hwirq_direct((unsigned
> > int)irq_map[virq].hwirq); +}
> >  
> > +static void xics_eoi_hwirq_lpar(unsigned int hwirq)
> > +{
> >      iosync();
> > -    direct_xirr_info_set((0xff << 24) | irq);
> > +    lpar_xirr_info_set((0xff << 24) | hwirq);
> >  }
> >  
> > -
> >  static void xics_eoi_lpar(unsigned int virq)
> >  {
> > -    unsigned int irq = (unsigned int)irq_map[virq].hwirq;
> > -
> > -    iosync();
> > -    lpar_xirr_info_set((0xff << 24) | irq);
> > +    xics_eoi_hwirq_lpar((unsigned
> > int)irq_map[virq].hwirq);
> >  }
> >  
> >  static inline unsigned int xics_remap_irq(unsigned int
> > vec) @@ -350,9 +355,15 @@ static inline unsigned int
> > xics_remap_irq(unsigned int vec)
> >      if (likely(irq != NO_IRQ))
> >          return irq;
> >  
> > -    printk(KERN_ERR "Interrupt %u (real) is invalid,"
> > -           " disabling it.\n", vec);
> > +    pr_err("%s: no mapping for hwirq %u, disabling it.\n"
> > , __func__, vec); +
> >      xics_mask_real_irq(vec);
> > +
> > +    if (firmware_has_feature(FW_FEATURE_LPAR))
> > +        xics_eoi_hwirq_lpar(vec);
> > +    else
> > +        xics_eoi_hwirq_direct(vec);
> > +
> >      return NO_IRQ;
> >  }
>  
> 
> I really dislike this great big if in the middle of a
> function.
> we called this function from two different call sites where
> the
> choice of which to call was based on their environment.
>  
> Please move the call to eoi the hwirq to the callers, who
> know which path to take.

It's not pretty, but the alternative is worse I think:

>From 0a908825c8de6cd4c26288aba8c5b7fe3ed0a69f Mon Sep 17 00:00:00 2001
From: Michael Ellerman <michael@ellerman.id.au>
Date: Tue, 5 Aug 2008 22:34:48 +1000
Subject: [PATCH] powerpc: EOI spurious irqs during boot so they can be reenabled later

In the xics code, if we receive an irq during boot that hasn't been setup
yet - ie. we have no reverse mapping for it - we mask the irq so we don't
hear from it again.

Later on if someone request_irq()'s that irq, we'll unmask it but it will
still never fire. This is because we never EOI'ed the irq when we originally
received it - when it was spurious.

This can be reproduced trivially by banging the keyboard while kexec'ing on
a P5 LPAR, even though the hvc_console driver request's the console irq, the
console is non-functional because we're receiving no console interrupts.

So when we receive a spurious irq mask it and then EOI it.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/platforms/pseries/xics.c |   74 ++++++++++++++++++++++-----------
 1 files changed, 50 insertions(+), 24 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 0fc830f..754706c 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -90,7 +90,7 @@ static inline unsigned int direct_xirr_info_get(void)
 {
 	int cpu = smp_processor_id();
 
-	return in_be32(&xics_per_cpu[cpu]->xirr.word);
+	return in_be32(&xics_per_cpu[cpu]->xirr.word) & 0x00ffffff;
 }
 
 static inline void direct_xirr_info_set(int value)
@@ -124,7 +124,8 @@ static inline unsigned int lpar_xirr_info_get(void)
 	lpar_rc = plpar_xirr(&return_value);
 	if (lpar_rc != H_SUCCESS)
 		panic(" bad return code xirr - rc = %lx \n", lpar_rc);
-	return (unsigned int)return_value;
+
+	return (unsigned int)return_value & 0x00ffffff;
 }
 
 static inline void lpar_xirr_info_set(int value)
@@ -321,49 +322,74 @@ static unsigned int xics_startup(unsigned int virq)
 	return 0;
 }
 
+static void xics_eoi_hwirq_direct(unsigned int hwirq)
+{
+	iosync();
+	direct_xirr_info_set((0xff << 24) | hwirq);
+}
+
 static void xics_eoi_direct(unsigned int virq)
 {
-	unsigned int irq = (unsigned int)irq_map[virq].hwirq;
+	xics_eoi_hwirq_direct((unsigned int)irq_map[virq].hwirq);
+}
 
+static void xics_eoi_hwirq_lpar(unsigned int hwirq)
+{
 	iosync();
-	direct_xirr_info_set((0xff << 24) | irq);
+	lpar_xirr_info_set((0xff << 24) | hwirq);
 }
 
-
 static void xics_eoi_lpar(unsigned int virq)
 {
-	unsigned int irq = (unsigned int)irq_map[virq].hwirq;
-
-	iosync();
-	lpar_xirr_info_set((0xff << 24) | irq);
+	xics_eoi_hwirq_lpar((unsigned int)irq_map[virq].hwirq);
 }
 
 static inline unsigned int xics_remap_irq(unsigned int vec)
 {
-	unsigned int irq;
-
-	vec &= 0x00ffffff;
-
-	if (vec == XICS_IRQ_SPURIOUS)
-		return NO_IRQ;
-	irq = irq_radix_revmap(xics_host, vec);
-	if (likely(irq != NO_IRQ))
-		return irq;
+	return irq_radix_revmap(xics_host, vec);
+}
 
-	printk(KERN_ERR "Interrupt %u (real) is invalid,"
-	       " disabling it.\n", vec);
-	xics_mask_real_irq(vec);
-	return NO_IRQ;
+static void xics_report_bad_irq(unsigned int hwirq)
+{
+	pr_err("%s: no mapping for hwirq %u, disabling it.\n", __func__, hwirq);
 }
 
 static unsigned int xics_get_irq_direct(void)
 {
-	return xics_remap_irq(direct_xirr_info_get());
+	unsigned int virq, hwirq;
+
+	hwirq = direct_xirr_info_get();
+	if (hwirq == XICS_IRQ_SPURIOUS)
+		return NO_IRQ;
+
+	virq = xics_remap_irq(hwirq);
+
+	if (unlikely(virq == NO_IRQ)) {
+		xics_report_bad_irq(hwirq);
+		xics_mask_real_irq(hwirq);
+		xics_eoi_hwirq_direct(hwirq);
+	}
+
+	return virq;
 }
 
 static unsigned int xics_get_irq_lpar(void)
 {
-	return xics_remap_irq(lpar_xirr_info_get());
+	unsigned int virq, hwirq;
+
+	hwirq = lpar_xirr_info_get();
+	if (hwirq == XICS_IRQ_SPURIOUS)
+		return NO_IRQ;
+
+	virq = xics_remap_irq(hwirq);
+
+	if (unlikely(virq == NO_IRQ)) {
+		xics_report_bad_irq(hwirq);
+		xics_mask_real_irq(hwirq);
+		xics_eoi_hwirq_lpar(hwirq);
+	}
+
+	return virq;
 }
 
 #ifdef CONFIG_SMP
-- 
1.5.5

  reply	other threads:[~2008-08-06  4:53 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-08-06  2:55 [PATCH] powerpc: EOI spurious irqs during boot so they can be reenabled later miltonm
2008-08-06  4:53 ` Michael Ellerman [this message]
  -- strict thread matches above, loose matches on Subject: below --
2008-08-07  3:10 miltonm
2008-08-06  2:03 Michael Ellerman
2008-08-05 13:42 Michael Ellerman
2008-08-05 16:48 ` Segher Boessenkool
2008-08-06  1:58   ` Michael Ellerman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1217998434.7893.16.camel@localhost \
    --to=michael@ellerman.id.au \
    --cc=linuxppc-dev@ozlabs.org \
    --cc=miltonm@bga.com \
    --cc=paulus@samba.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.