aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Dreier <rolandd@cisco.com>2007-05-24 13:58:20 -0700
committerRoland Dreier <rolandd@cisco.com>2007-05-24 13:58:46 -0700
commitaf7707cecdfd5ca8a38b4d855070ebfc310a339f (patch)
tree5d7383c9f5f86ce8368aac20e80bd82c5a387fc3
parent2b226be6d648f6273fe0d86b339a43e2b23f5409 (diff)
downloadlibmlx4-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.h1
-rw-r--r--src/qp.c18
-rw-r--r--src/verbs.c6
3 files changed, 18 insertions, 7 deletions
diff --git a/src/mlx4.h b/src/mlx4.h
index 3c7b2cf..e29f456 100644
--- a/src/mlx4.h
+++ b/src/mlx4.h
@@ -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,
diff --git a/src/qp.c b/src/qp.c
index bff3f33..fa20dfa 100644
--- a/src/qp.c
+++ b/src/qp.c
@@ -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 &&