in efawin/verbs.c [403:436]
static inline int efa_poll_sub_cq(struct efa_cq *cq, struct efa_sub_cq *sub_cq,
struct efa_qp **cur_qp, struct ibv_wc *wc,
bool extended) ALWAYS_INLINE;
static inline int efa_poll_sub_cq(struct efa_cq *cq, struct efa_sub_cq *sub_cq,
struct efa_qp **cur_qp, struct ibv_wc *wc,
bool extended)
{
struct efa_context *ctx = to_efa_context(cq->verbs_cq.cq.context);
uint32_t qpn;
cq->cur_cqe = cq_next_sub_cqe_get(sub_cq);
if (!cq->cur_cqe)
return ENOENT;
qpn = cq->cur_cqe->qp_num;
if (!*cur_qp || qpn != (*cur_qp)->verbs_qp.qp.qp_num) {
/* We do not have to take the QP table lock here,
* because CQs will be locked while QPs are removed
* from the table.
*/
*cur_qp = ctx->qp_table[qpn & ctx->qp_table_sz_m1];
if (!*cur_qp)
return EINVAL;
}
if (extended) {
efa_process_ex_cqe(cq, *cur_qp);
} else {
efa_process_cqe(cq, wc, *cur_qp);
efa_wq_put_wrid_idx_unlocked(cq->cur_wq, cq->cur_cqe->req_id);
}
return 0;
}