static void *get_sw_cqe(struct mlx4_cq *cq, int n)
{
- struct mlx4_cqe *cqe = get_cqe(cq, n & cq->ibv_cq.cqe);
+ struct mlx4_cqe *cqe = get_cqe(cq, n & (cq->ibv_cq.cqe - 1));
return (!!(cqe->owner_sr_opcode & MLX4_CQE_OWNER_MASK) ^
- !!(n & (cq->ibv_cq.cqe + 1))) ? NULL : cqe;
+ !!(n & cq->ibv_cq.cqe)) ? NULL : cqe;
}
static struct mlx4_cqe *next_cqe_sw(struct mlx4_cq *cq)
* from our QP and therefore don't need to be checked.
*/
for (prod_index = cq->cons_index; get_sw_cqe(cq, prod_index); ++prod_index)
- if (prod_index == cq->cons_index + cq->ibv_cq.cqe)
+ if (prod_index == cq->cons_index + cq->ibv_cq.cqe - 1)
break;
/*
* that match our QP by copying older entries on top of them.
*/
while ((int) --prod_index - (int) cq->cons_index >= 0) {
- cqe = get_cqe(cq, prod_index & cq->ibv_cq.cqe);
+ cqe = get_cqe(cq, prod_index & (cq->ibv_cq.cqe - 1));
if ((ntohl(cqe->my_qpn) & 0xffffff) == qpn) {
if (srq && !(cqe->owner_sr_opcode & MLX4_CQE_IS_SEND_MASK))
mlx4_free_srq_wqe(srq, ntohs(cqe->wqe_index));
++nfreed;
} else if (nfreed) {
- dest = get_cqe(cq, (prod_index + nfreed) & cq->ibv_cq.cqe);
+ dest = get_cqe(cq, (prod_index + nfreed) & (cq->ibv_cq.cqe - 1));
owner_bit = dest->owner_sr_opcode & MLX4_CQE_OWNER_MASK;
memcpy(dest, cqe, sizeof *cqe);
dest->owner_sr_opcode = owner_bit |
if (pthread_spin_init(&cq->lock, PTHREAD_PROCESS_PRIVATE))
goto err;
- cqe = align_queue_size(cqe + 1);
+ cqe = align_queue_size(cqe);
+
+ /* Always allocate at least two CQEs to keep things simple */
+ if (cqe < 2)
+ cqe = 2;
if (mlx4_alloc_buf(&cq->buf, cqe * MLX4_CQ_ENTRY_SIZE,
to_mdev(context->device)->page_size))
cmd.buf_addr = (uintptr_t) cq->buf.buf;
cmd.db_addr = (uintptr_t) cq->set_ci_db;
+ /* Subtract 1 from the number of entries we pass into the
+ * kernel because the kernel mlx4_ib driver will add 1 again. */
ret = ibv_cmd_create_cq(context, cqe - 1, channel, comp_vector,
&cq->ibv_cq, &cmd.ibv_cmd, sizeof cmd,
&resp.ibv_resp, sizeof resp);
goto err_db;
cq->cqn = resp.cqn;
+ /* Bump the number of entries to make up for subtracting 1 above */
+ ++cq->ibv_cq.cqe;
return &cq->ibv_cq;