enum {
        MTHCA_NUM_ASYNC_EQE = 0x80,
        MTHCA_NUM_CMD_EQE   = 0x80,
+       MTHCA_NUM_SPARE_EQE = 0x80,
        MTHCA_EQ_ENTRY_SIZE = 0x20
 };
 
 {
        struct mthca_eqe *eqe;
        int disarm_cqn;
-       int  eqes_found = 0;
+       int eqes_found = 0;
+       int set_ci = 0;
 
        while ((eqe = next_eqe_sw(eq))) {
-               int set_ci = 0;
-
                /*
                 * Make sure we read EQ entry contents after we've
                 * checked the ownership bit.
                                        be16_to_cpu(eqe->event.cmd.token),
                                        eqe->event.cmd.status,
                                        be64_to_cpu(eqe->event.cmd.out_param));
-                       /*
-                        * 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:
                set_eqe_hw(eqe);
                ++eq->cons_index;
                eqes_found = 1;
+               ++set_ci;
 
-               if (unlikely(set_ci)) {
+               /*
+                * The HCA will think the queue has overflowed if we
+                * don't tell it we've been processing events.  We
+                * create our EQs with MTHCA_NUM_SPARE_EQE extra
+                * entries, so we must update our consumer index at
+                * least that often.
+                */
+               if (unlikely(set_ci >= MTHCA_NUM_SPARE_EQE)) {
                        /*
                         * Conditional on hca_type is OK here because
                         * this is a rare case, not the fast path.
        intr = (dev->mthca_flags & MTHCA_FLAG_MSI) ?
                128 : dev->eq_table.inta_pin;
 
-       err = mthca_create_eq(dev, dev->limits.num_cqs,
+       err = mthca_create_eq(dev, dev->limits.num_cqs + MTHCA_NUM_SPARE_EQE,
                              (dev->mthca_flags & MTHCA_FLAG_MSI_X) ? 128 : intr,
                              &dev->eq_table.eq[MTHCA_EQ_COMP]);
        if (err)
                goto err_out_unmap;
 
-       err = mthca_create_eq(dev, MTHCA_NUM_ASYNC_EQE,
+       err = mthca_create_eq(dev, MTHCA_NUM_ASYNC_EQE + MTHCA_NUM_SPARE_EQE,
                              (dev->mthca_flags & MTHCA_FLAG_MSI_X) ? 129 : intr,
                              &dev->eq_table.eq[MTHCA_EQ_ASYNC]);
        if (err)
                goto err_out_comp;
 
-       err = mthca_create_eq(dev, MTHCA_NUM_CMD_EQE,
+       err = mthca_create_eq(dev, MTHCA_NUM_CMD_EQE + MTHCA_NUM_SPARE_EQE,
                              (dev->mthca_flags & MTHCA_FLAG_MSI_X) ? 130 : intr,
                              &dev->eq_table.eq[MTHCA_EQ_CMD]);
        if (err)