@@ -229,7 +229,7 @@ static inline int mlx4_parse_cqe(struct mlx4_cq *cq,
if (!srq)
return CQ_POLL_ERR;
} else {
- if (!*cur_qp || (qpn != (*cur_qp)->verbs_qp.qp.qp_num)) {
+ if (!*cur_qp || (qpn != (*cur_qp)->qpn_cache)) {
/*
* We do not have to take the QP table lock here,
* because CQs will be locked while QPs are removed
@@ -239,7 +239,8 @@ static inline int mlx4_parse_cqe(struct mlx4_cq *cq,
if (!*cur_qp)
return CQ_POLL_ERR;
}
- srq = ((*cur_qp)->verbs_qp.qp.srq) ? to_msrq((*cur_qp)->verbs_qp.qp.srq) : NULL;
+ srq = ((*cur_qp)->type == MLX4_RSC_TYPE_SRQ) ?
+ to_msrq((*cur_qp)->verbs_qp.qp.srq) : NULL;
}
pwr_id = lazy ? &cq->ibv_cq.wr_id : &wc->wr_id;
@@ -201,6 +201,7 @@ struct mlx4_wq {
enum mlx4_rsc_type {
MLX4_RSC_TYPE_QP = 0,
MLX4_RSC_TYPE_RSS_QP = 1,
+ MLX4_RSC_TYPE_SRQ = 2,
};
struct mlx4_qp {
@@ -223,6 +224,7 @@ struct mlx4_qp {
uint8_t link_layer;
uint8_t type; /* enum mlx4_rsc_type */
uint32_t qp_cap_cache;
+ uint32_t qpn_cache;
};
struct mlx4_ah {
@@ -420,5 +422,7 @@ int mlx4_destroy_wq(struct ibv_wq *wq);
struct ibv_rwq_ind_table *mlx4_create_rwq_ind_table(struct ibv_context *context,
struct ibv_rwq_ind_table_init_attr *init_attr);
int mlx4_destroy_rwq_ind_table(struct ibv_rwq_ind_table *rwq_ind_table);
+int mlx4_post_wq_recv(struct ibv_wq *ibwq, struct ibv_recv_wr *wr,
+ struct ibv_recv_wr **bad_wr);
#endif /* MLX4_H */
@@ -509,10 +509,14 @@ out:
return ret;
}
-int mlx4_post_recv(struct ibv_qp *ibqp, struct ibv_recv_wr *wr,
- struct ibv_recv_wr **bad_wr)
+static inline int _mlx4_post_recv(struct mlx4_qp *qp, struct mlx4_cq *cq,
+ struct ibv_recv_wr *wr,
+ struct ibv_recv_wr **bad_wr)
+ ALWAYS_INLINE;
+static inline int _mlx4_post_recv(struct mlx4_qp *qp, struct mlx4_cq *cq,
+ struct ibv_recv_wr *wr,
+ struct ibv_recv_wr **bad_wr)
{
- struct mlx4_qp *qp = to_mqp(ibqp);
struct mlx4_wqe_data_seg *scat;
int ret = 0;
int nreq;
@@ -526,7 +530,7 @@ int mlx4_post_recv(struct ibv_qp *ibqp, struct ibv_recv_wr *wr,
ind = qp->rq.head & (qp->rq.wqe_cnt - 1);
for (nreq = 0; wr; ++nreq, wr = wr->next) {
- if (wq_overflow(&qp->rq, nreq, to_mcq(ibqp->recv_cq))) {
+ if (wq_overflow(&qp->rq, nreq, cq)) {
ret = ENOMEM;
*bad_wr = wr;
goto out;
@@ -572,6 +576,24 @@ out:
return ret;
}
+int mlx4_post_recv(struct ibv_qp *ibqp, struct ibv_recv_wr *wr,
+ struct ibv_recv_wr **bad_wr)
+{
+ struct mlx4_qp *qp = to_mqp(ibqp);
+ struct mlx4_cq *cq = to_mcq(ibqp->recv_cq);
+
+ return _mlx4_post_recv(qp, cq, wr, bad_wr);
+}
+
+int mlx4_post_wq_recv(struct ibv_wq *ibwq, struct ibv_recv_wr *wr,
+ struct ibv_recv_wr **bad_wr)
+{
+ struct mlx4_qp *qp = wq_to_mqp(ibwq);
+ struct mlx4_cq *cq = to_mcq(ibwq->cq);
+
+ return _mlx4_post_recv(qp, cq, wr, bad_wr);
+}
+
static int num_inline_segs(int data, enum ibv_qp_type type)
{
/*
@@ -976,6 +976,9 @@ static struct ibv_qp *create_qp_ex(struct ibv_context *context,
else
qp->sq_signal_bits = 0;
+ qp->qpn_cache = qp->verbs_qp.qp.qp_num;
+ qp->type = attr->srq ? MLX4_RSC_TYPE_SRQ : MLX4_RSC_TYPE_QP;
+
return &qp->verbs_qp.qp;
err_destroy:
@@ -1473,6 +1476,10 @@ struct ibv_wq *mlx4_create_wq(struct ibv_context *context,
qp->wq.state = IBV_WQS_RESET;
+ qp->wq.post_recv = mlx4_post_wq_recv;
+
+ qp->qpn_cache = qp->wq.wq_num;
+
return &qp->wq;
err_destroy: