[openib-general] HP ZX1 and HP IB cards...
Grant Grundler
iod00d at hp.com
Thu Dec 9 17:12:16 PST 2004
On Thu, Dec 09, 2004 at 04:05:36PM -0800, Grant Grundler wrote:
> Roland,
> Would you consider committing the set_ci patch and backing the ncmd patch out?
Roland,
Attached is a patch that does three things (LART me for combining them,
but I can split them up later if you want):
o reverse most of the mthca_cmd_complete() patch
o add set_ci logic so consumer index is updated inside the event loop
o eliminate "work" variable (nicely simplifies the code).
If I understood the code correctly, "work" was always being set
if next_eqe_sw(eq) was non-zero.
It is so expensive to get to the interrupt handler in the first place
that if nothing needs to be done:
a) the problem is NOT in the interrupt handler.
b) the spurious set_eq_ci() is light weight enough to be in the noise
I do understand the wmb()/set_eq_ci() disturb the PCI data flows but
we shouldn't be seeing spurious interrupts either. If they are happening
often enough to disturb performance, something else is wrong.
grant
Index: hw/mthca/mthca_cmd.c
===================================================================
--- hw/mthca/mthca_cmd.c (revision 1317)
+++ hw/mthca/mthca_cmd.c (working copy)
@@ -293,12 +293,6 @@
complete(&context->done);
}
-void mthca_cmd_complete(struct mthca_dev *dev, int ncomp)
-{
- while (ncomp--)
- up(&dev->cmd.event_sem);
-}
-
static void event_timeout(unsigned long context_ptr)
{
struct mthca_cmd_context *context =
@@ -363,6 +357,7 @@
dev->cmd.free_head = context - dev->cmd.context;
spin_unlock(&dev->cmd.context_lock);
+ up(&dev->cmd.event_sem);
return err;
}
Index: hw/mthca/mthca_eq.c
===================================================================
--- hw/mthca/mthca_eq.c (revision 1317)
+++ hw/mthca/mthca_eq.c (working copy)
@@ -218,15 +218,10 @@
{
struct mthca_eqe *eqe;
int disarm_cqn;
- int work = 0;
- int ncmd = 0;
- while (1) {
- if (!next_eqe_sw(eq))
- break;
-
+ while (next_eqe_sw(eq)) {
+ int set_ci = 0;
eqe = get_eqe(eq, eq->cons_index);
- work = 1;
switch (eqe->type) {
case MTHCA_EVENT_TYPE_COMP:
@@ -275,7 +270,11 @@
be16_to_cpu(eqe->event.cmd.token),
eqe->event.cmd.status,
be64_to_cpu(eqe->event.cmd.out_param));
- ++ncmd;
+ /* cmd_event() may add more commands.
+ * The card will think the queue has overflowed if
+ * we don't tell it we've been processing events.
+ */
+ set_ci = 1;
break;
case MTHCA_EVENT_TYPE_PORT_CHANGE:
@@ -298,25 +297,25 @@
set_eqe_hw(eq, eq->cons_index);
eq->cons_index = (eq->cons_index + 1) & (eq->nent - 1);
- }
- if (work) {
- /*
- * This barrier makes sure that all updates to
- * ownership bits done by set_eqe_hw() hit memory
- * before the consumer index is updated. set_eq_ci()
- * allows the HCA to possibly write more EQ entries,
- * and we want to avoid the exceedingly unlikely
- * possibility of the HCA writing an entry and then
- * having set_eqe_hw() overwrite the owner field.
- */
- wmb();
- set_eq_ci(dev, eq->eqn, eq->cons_index);
+ if (set_ci) {
+ wmb(); /* see comment below */
+ set_eq_ci(dev, eq->eqn, eq->cons_index);
+ set_ci = 0;
+ }
}
- if (ncmd)
- mthca_cmd_complete(dev, ncmd);
-
+ /*
+ * This barrier makes sure that all updates to
+ * ownership bits done by set_eqe_hw() hit memory
+ * before the consumer index is updated. set_eq_ci()
+ * allows the HCA to possibly write more EQ entries,
+ * and we want to avoid the exceedingly unlikely
+ * possibility of the HCA writing an entry and then
+ * having set_eqe_hw() overwrite the owner field.
+ */
+ wmb();
+ set_eq_ci(dev, eq->eqn, eq->cons_index);
eq_req_not(dev, eq->eqn);
}
Index: hw/mthca/mthca_cmd.h
===================================================================
--- hw/mthca/mthca_cmd.h (revision 1317)
+++ hw/mthca/mthca_cmd.h (working copy)
@@ -205,7 +205,6 @@
void mthca_cmd_use_polling(struct mthca_dev *dev);
void mthca_cmd_event(struct mthca_dev *dev, u16 token,
u8 status, u64 out_param);
-void mthca_cmd_complete(struct mthca_dev *dev, int ncomp);
int mthca_SYS_EN(struct mthca_dev *dev, u8 *status);
int mthca_SYS_DIS(struct mthca_dev *dev, u8 *status);
More information about the general
mailing list