linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH REPOST #2] IB/ehca: In case of lost interrupts, trigger EOI to reenable interrupts
@ 2008-06-13 14:55 Stefan Roscher
  2008-06-19 22:35 ` Roland Dreier
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Stefan Roscher @ 2008-06-13 14:55 UTC (permalink / raw)
  To: Roland Dreier, LinuxPPC-Dev, LKML, OF-EWG, general; +Cc: fenkes, raisch

During corner case testing, we noticed that some versions of ehca 
do not properly transition to interrupt done in special load situations.
This can be resolved by periodically triggering EOI through H_EOI, 
if eqes are pending.

Signed-off-by: Stefan Roscher <stefan.roscher@de.ibm.com>
---
As firmware team suggested I moved the call of the EOI h_call into 
the handler function, this ensures that we will call EOI only when we 
find a valid eqe on the event queue.
Additionally I changed the calculation of the xirr value as Roland suggested.

 drivers/infiniband/hw/ehca/ehca_irq.c |    9 +++++++--
 drivers/infiniband/hw/ehca/hcp_if.c   |   10 ++++++++++
 drivers/infiniband/hw/ehca/hcp_if.h   |    1 +
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c
index ce1ab05..0792d93 100644
--- a/drivers/infiniband/hw/ehca/ehca_irq.c
+++ b/drivers/infiniband/hw/ehca/ehca_irq.c
@@ -531,7 +531,7 @@ void ehca_process_eq(struct ehca_shca *shca, int is_irq)
 {
 	struct ehca_eq *eq = &shca->eq;
 	struct ehca_eqe_cache_entry *eqe_cache = eq->eqe_cache;
-	u64 eqe_value;
+	u64 eqe_value, ret;
 	unsigned long flags;
 	int eqe_cnt, i;
 	int eq_empty = 0;
@@ -583,8 +583,13 @@ void ehca_process_eq(struct ehca_shca *shca, int is_irq)
 			ehca_dbg(&shca->ib_device,
 				 "No eqe found for irq event");
 		goto unlock_irq_spinlock;
-	} else if (!is_irq)
+	} else if (!is_irq) {
+		ret = hipz_h_eoi(eq->ist);
+		if (ret != H_SUCCESS)
+			ehca_err(&shca->ib_device,
+				 "bad return code EOI -rc = %ld\n", ret);
 		ehca_dbg(&shca->ib_device, "deadman found %x eqe", eqe_cnt);
+	}
 	if (unlikely(eqe_cnt == EHCA_EQE_CACHE_SIZE))
 		ehca_dbg(&shca->ib_device, "too many eqes for one irq event");
 	/* enable irq for new packets */
diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c
index 5245e13..415d3a4 100644
--- a/drivers/infiniband/hw/ehca/hcp_if.c
+++ b/drivers/infiniband/hw/ehca/hcp_if.c
@@ -933,3 +933,13 @@ u64 hipz_h_error_data(const struct ipz_adapter_handle adapter_handle,
 				       r_cb,
 				       0, 0, 0, 0);
 }
+
+u64 hipz_h_eoi(int irq)
+{
+	unsigned long xirr;
+
+	iosync();
+	xirr = (0xffULL << 24) | irq;
+
+	return plpar_hcall_norets(H_EOI, xirr);
+}
diff --git a/drivers/infiniband/hw/ehca/hcp_if.h b/drivers/infiniband/hw/ehca/hcp_if.h
index 60ce02b..2c3c6e0 100644
--- a/drivers/infiniband/hw/ehca/hcp_if.h
+++ b/drivers/infiniband/hw/ehca/hcp_if.h
@@ -260,5 +260,6 @@ u64 hipz_h_error_data(const struct ipz_adapter_handle adapter_handle,
 		      const u64 ressource_handle,
 		      void *rblock,
 		      unsigned long *byte_count);
+u64 hipz_h_eoi(int irq);
 
 #endif /* __HCP_IF_H__ */
-- 
1.5.5

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH REPOST #2] IB/ehca: In case of lost interrupts, trigger EOI to reenable interrupts
  2008-06-13 14:55 [PATCH REPOST #2] IB/ehca: In case of lost interrupts, trigger EOI to reenable interrupts Stefan Roscher
@ 2008-06-19 22:35 ` Roland Dreier
  2008-06-22  0:31 ` Benjamin Herrenschmidt
  2008-06-23 20:23 ` Roland Dreier
  2 siblings, 0 replies; 4+ messages in thread
From: Roland Dreier @ 2008-06-19 22:35 UTC (permalink / raw)
  To: Stefan Roscher; +Cc: fenkes, LKML, OF-EWG, LinuxPPC-Dev, raisch, general

 > During corner case testing, we noticed that some versions of ehca 
 > do not properly transition to interrupt done in special load situations.
 > This can be resolved by periodically triggering EOI through H_EOI, 
 > if eqes are pending.
 > 
 > Signed-off-by: Stefan Roscher <stefan.roscher@de.ibm.com>
 > ---
 > As firmware team suggested I moved the call of the EOI h_call into 
 > the handler function, this ensures that we will call EOI only when we 
 > find a valid eqe on the event queue.
 > Additionally I changed the calculation of the xirr value as Roland suggested.

paulus / benh -- does this version still get your ack?  Seems that fw
team is OK with it according to Stefan...

If so I will add this to my tree for 2.6.27.

 > diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c
 > index ce1ab05..0792d93 100644
 > --- a/drivers/infiniband/hw/ehca/ehca_irq.c
 > +++ b/drivers/infiniband/hw/ehca/ehca_irq.c
 > @@ -531,7 +531,7 @@ void ehca_process_eq(struct ehca_shca *shca, int is_irq)
 >  {
 >  	struct ehca_eq *eq = &shca->eq;
 >  	struct ehca_eqe_cache_entry *eqe_cache = eq->eqe_cache;
 > -	u64 eqe_value;
 > +	u64 eqe_value, ret;
 >  	unsigned long flags;
 >  	int eqe_cnt, i;
 >  	int eq_empty = 0;
 > @@ -583,8 +583,13 @@ void ehca_process_eq(struct ehca_shca *shca, int is_irq)
 >  			ehca_dbg(&shca->ib_device,
 >  				 "No eqe found for irq event");
 >  		goto unlock_irq_spinlock;
 > -	} else if (!is_irq)
 > +	} else if (!is_irq) {
 > +		ret = hipz_h_eoi(eq->ist);
 > +		if (ret != H_SUCCESS)
 > +			ehca_err(&shca->ib_device,
 > +				 "bad return code EOI -rc = %ld\n", ret);
 >  		ehca_dbg(&shca->ib_device, "deadman found %x eqe", eqe_cnt);
 > +	}
 >  	if (unlikely(eqe_cnt == EHCA_EQE_CACHE_SIZE))
 >  		ehca_dbg(&shca->ib_device, "too many eqes for one irq event");
 >  	/* enable irq for new packets */
 > diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c
 > index 5245e13..415d3a4 100644
 > --- a/drivers/infiniband/hw/ehca/hcp_if.c
 > +++ b/drivers/infiniband/hw/ehca/hcp_if.c
 > @@ -933,3 +933,13 @@ u64 hipz_h_error_data(const struct ipz_adapter_handle adapter_handle,
 >  				       r_cb,
 >  				       0, 0, 0, 0);
 >  }
 > +
 > +u64 hipz_h_eoi(int irq)
 > +{
 > +	unsigned long xirr;
 > +
 > +	iosync();
 > +	xirr = (0xffULL << 24) | irq;
 > +
 > +	return plpar_hcall_norets(H_EOI, xirr);
 > +}
 > diff --git a/drivers/infiniband/hw/ehca/hcp_if.h b/drivers/infiniband/hw/ehca/hcp_if.h
 > index 60ce02b..2c3c6e0 100644
 > --- a/drivers/infiniband/hw/ehca/hcp_if.h
 > +++ b/drivers/infiniband/hw/ehca/hcp_if.h
 > @@ -260,5 +260,6 @@ u64 hipz_h_error_data(const struct ipz_adapter_handle adapter_handle,
 >  		      const u64 ressource_handle,
 >  		      void *rblock,
 >  		      unsigned long *byte_count);
 > +u64 hipz_h_eoi(int irq);
 >  
 >  #endif /* __HCP_IF_H__ */
 > -- 
 > 1.5.5
 > 
 > 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH REPOST #2] IB/ehca: In case of lost interrupts, trigger EOI to reenable interrupts
  2008-06-13 14:55 [PATCH REPOST #2] IB/ehca: In case of lost interrupts, trigger EOI to reenable interrupts Stefan Roscher
  2008-06-19 22:35 ` Roland Dreier
@ 2008-06-22  0:31 ` Benjamin Herrenschmidt
  2008-06-23 20:23 ` Roland Dreier
  2 siblings, 0 replies; 4+ messages in thread
From: Benjamin Herrenschmidt @ 2008-06-22  0:31 UTC (permalink / raw)
  To: Stefan Roscher
  Cc: Roland Dreier, fenkes, LKML, OF-EWG, LinuxPPC-Dev, raisch,
	general

On Fri, 2008-06-13 at 16:55 +0200, Stefan Roscher wrote:
> During corner case testing, we noticed that some versions of ehca 
> do not properly transition to interrupt done in special load situations.
> This can be resolved by periodically triggering EOI through H_EOI, 
> if eqes are pending.
> 
> Signed-off-by: Stefan Roscher <stefan.roscher@de.ibm.com>

Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

---

> As firmware team suggested I moved the call of the EOI h_call into 
> the handler function, this ensures that we will call EOI only when we 
> find a valid eqe on the event queue.
> Additionally I changed the calculation of the xirr value as Roland suggested.
> 
>  drivers/infiniband/hw/ehca/ehca_irq.c |    9 +++++++--
>  drivers/infiniband/hw/ehca/hcp_if.c   |   10 ++++++++++
>  drivers/infiniband/hw/ehca/hcp_if.h   |    1 +
>  3 files changed, 18 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c
> index ce1ab05..0792d93 100644
> --- a/drivers/infiniband/hw/ehca/ehca_irq.c
> +++ b/drivers/infiniband/hw/ehca/ehca_irq.c
> @@ -531,7 +531,7 @@ void ehca_process_eq(struct ehca_shca *shca, int is_irq)
>  {
>  	struct ehca_eq *eq = &shca->eq;
>  	struct ehca_eqe_cache_entry *eqe_cache = eq->eqe_cache;
> -	u64 eqe_value;
> +	u64 eqe_value, ret;
>  	unsigned long flags;
>  	int eqe_cnt, i;
>  	int eq_empty = 0;
> @@ -583,8 +583,13 @@ void ehca_process_eq(struct ehca_shca *shca, int is_irq)
>  			ehca_dbg(&shca->ib_device,
>  				 "No eqe found for irq event");
>  		goto unlock_irq_spinlock;
> -	} else if (!is_irq)
> +	} else if (!is_irq) {
> +		ret = hipz_h_eoi(eq->ist);
> +		if (ret != H_SUCCESS)
> +			ehca_err(&shca->ib_device,
> +				 "bad return code EOI -rc = %ld\n", ret);
>  		ehca_dbg(&shca->ib_device, "deadman found %x eqe", eqe_cnt);
> +	}
>  	if (unlikely(eqe_cnt == EHCA_EQE_CACHE_SIZE))
>  		ehca_dbg(&shca->ib_device, "too many eqes for one irq event");
>  	/* enable irq for new packets */
> diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c
> index 5245e13..415d3a4 100644
> --- a/drivers/infiniband/hw/ehca/hcp_if.c
> +++ b/drivers/infiniband/hw/ehca/hcp_if.c
> @@ -933,3 +933,13 @@ u64 hipz_h_error_data(const struct ipz_adapter_handle adapter_handle,
>  				       r_cb,
>  				       0, 0, 0, 0);
>  }
> +
> +u64 hipz_h_eoi(int irq)
> +{
> +	unsigned long xirr;
> +
> +	iosync();
> +	xirr = (0xffULL << 24) | irq;
> +
> +	return plpar_hcall_norets(H_EOI, xirr);
> +}
> diff --git a/drivers/infiniband/hw/ehca/hcp_if.h b/drivers/infiniband/hw/ehca/hcp_if.h
> index 60ce02b..2c3c6e0 100644
> --- a/drivers/infiniband/hw/ehca/hcp_if.h
> +++ b/drivers/infiniband/hw/ehca/hcp_if.h
> @@ -260,5 +260,6 @@ u64 hipz_h_error_data(const struct ipz_adapter_handle adapter_handle,
>  		      const u64 ressource_handle,
>  		      void *rblock,
>  		      unsigned long *byte_count);
> +u64 hipz_h_eoi(int irq);
>  
>  #endif /* __HCP_IF_H__ */

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH REPOST #2] IB/ehca: In case of lost interrupts, trigger EOI to reenable interrupts
  2008-06-13 14:55 [PATCH REPOST #2] IB/ehca: In case of lost interrupts, trigger EOI to reenable interrupts Stefan Roscher
  2008-06-19 22:35 ` Roland Dreier
  2008-06-22  0:31 ` Benjamin Herrenschmidt
@ 2008-06-23 20:23 ` Roland Dreier
  2 siblings, 0 replies; 4+ messages in thread
From: Roland Dreier @ 2008-06-23 20:23 UTC (permalink / raw)
  To: Stefan Roscher; +Cc: fenkes, LKML, OF-EWG, LinuxPPC-Dev, raisch, general

ok, I queued this for 2.6.27.  thanks everyone

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2008-06-23 20:23 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-06-13 14:55 [PATCH REPOST #2] IB/ehca: In case of lost interrupts, trigger EOI to reenable interrupts Stefan Roscher
2008-06-19 22:35 ` Roland Dreier
2008-06-22  0:31 ` Benjamin Herrenschmidt
2008-06-23 20:23 ` Roland Dreier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).