/* * Reap one CQE from the CQ. Only used by kernel clients * during CQ normal operation. Might be called during CQ * flush for user mapped CQE array as well.
*/ int siw_reap_cqe(struct siw_cq *cq, struct ib_wc *wc)
{ struct siw_cqe *cqe; unsignedlong flags;
/* * During CQ flush, also user land CQE's may get * reaped here, which do not hold a QP reference * and do not qualify for memory extension verbs.
*/ if (likely(rdma_is_kernel_res(&cq->base_cq.res))) { if (cqe->flags & SIW_WQE_REM_INVAL) {
wc->ex.invalidate_rkey = cqe->inval_stag;
wc->wc_flags = IB_WC_WITH_INVALIDATE;
}
wc->qp = cqe->base_qp;
wc->opcode = map_wc_opcode[cqe->opcode];
wc->status = map_cqe_status[cqe->status].ib;
siw_dbg_cq(cq, "idx %u, type %d, flags %2x, id 0x%p\n",
cq->cq_get % cq->num_cqe, cqe->opcode,
cqe->flags, (void *)(uintptr_t)cqe->id);
} else { /* * A malicious user may set invalid opcode or * status in the user mmapped CQE array. * Sanity check and correct values in that case * to avoid out-of-bounds access to global arrays * for opcode and status mapping.
*/
u8 opcode = cqe->opcode;
u16 status = cqe->status;
if (opcode >= SIW_NUM_OPCODES) {
opcode = 0;
status = SIW_WC_GENERAL_ERR;
} elseif (status >= SIW_NUM_WC_STATUS) {
status = SIW_WC_GENERAL_ERR;
}
wc->opcode = map_wc_opcode[opcode];
wc->status = map_cqe_status[status].ib;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.