diff options
author | Roland Dreier <rolandd@cisco.com> | 2007-05-24 13:58:20 -0700 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2007-05-24 13:58:46 -0700 |
commit | af7707cecdfd5ca8a38b4d855070ebfc310a339f (patch) | |
tree | 5d7383c9f5f86ce8368aac20e80bd82c5a387fc3 | |
parent | 2b226be6d648f6273fe0d86b339a43e2b23f5409 (diff) | |
download | libmlx4-af7707cecdfd5ca8a38b4d855070ebfc310a339f.tar.gz |
Initialize send queue entry ownership bits
We need to initialize the owner bit of send queue WQEs to hardware
ownership whenever the QP is modified from reset to init, not just
when the QP is first allocated. This avoids having the hardware
process stale WQEs when the QP is moved to reset but not destroyed and
then modified to init again.
This is the same bug fixed in the kernel by Eli Cohen <eli@mellanox.co.il>.
Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r-- | src/mlx4.h | 1 | ||||
-rw-r--r-- | src/qp.c | 18 | ||||
-rw-r--r-- | src/verbs.c | 6 |
3 files changed, 18 insertions, 7 deletions
@@ -337,6 +337,7 @@ int mlx4_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, enum ibv_qp_attr_mask attr_mask); int mlx4_destroy_qp(struct ibv_qp *qp); void mlx4_init_qp_indices(struct mlx4_qp *qp); +void mlx4_qp_init_sq_ownership(struct mlx4_qp *qp); int mlx4_post_send(struct ibv_qp *ibqp, struct ibv_send_wr *wr, struct ibv_send_wr **bad_wr); int mlx4_post_recv(struct ibv_qp *ibqp, struct ibv_recv_wr *wr, @@ -73,6 +73,17 @@ void mlx4_init_qp_indices(struct mlx4_qp *qp) qp->rq.tail = 0; } +void mlx4_qp_init_sq_ownership(struct mlx4_qp *qp) +{ + struct mlx4_wqe_ctrl_seg *ctrl; + int i; + + for (i = 0; i < qp->sq.max; ++i) { + ctrl = get_send_wqe(qp, i); + ctrl->owner_opcode = htonl(1 << 31); + } +} + static int wq_overflow(struct mlx4_wq *wq, int nreq, struct mlx4_cq *cq) { unsigned cur; @@ -375,10 +386,8 @@ out: int mlx4_alloc_qp_buf(struct ibv_pd *pd, struct ibv_qp_cap *cap, enum ibv_qp_type type, struct mlx4_qp *qp) { - struct mlx4_wqe_ctrl_seg *ctrl; int size; int max_sq_sge; - int i; qp->rq.max_gs = cap->max_recv_sge; qp->sq.max_gs = cap->max_send_sge; @@ -461,11 +470,6 @@ int mlx4_alloc_qp_buf(struct ibv_pd *pd, struct ibv_qp_cap *cap, memset(qp->buf.buf, 0, qp->buf_size); - for (i = 0; i < qp->sq.max; ++i) { - ctrl = get_send_wqe(qp, i); - ctrl->owner_opcode = htonl(1 << 31); - } - return 0; } diff --git a/src/verbs.c b/src/verbs.c index e9b4c23..1feae9d 100644 --- a/src/verbs.c +++ b/src/verbs.c @@ -458,6 +458,12 @@ int mlx4_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, struct ibv_modify_qp cmd; int ret; + if (qp->state == IBV_QPS_RESET && + attr_mask & IBV_QP_STATE && + attr->qp_state == IBV_QPS_INIT) { + mlx4_qp_init_sq_ownership(to_mqp(qp)); + } + ret = ibv_cmd_modify_qp(qp, attr, attr_mask, &cmd, sizeof cmd); if (!ret && |