Skip to content

Commit

Permalink
providers/irdma: Fix RQ completion opcode
Browse files Browse the repository at this point in the history
The opcode written by HW, in the RQ CQE, is the
RoCEv2/iWARP protocol opcode from the received
packet and not the SW opcode as currently assumed.
Fix this by returning the raw operation type and
queue type in the CQE to irdma_process_cqe and add
2 helpers set_ib_wc_op_sq set_ib_wc_op_rq to map
IRDMA HW op types to IB op types.

Note that for iWARP, only Write with Immediate is
supported so the opcode can only be IB_WC_RECV_RDMA_WITH_IMM
when there is immediate data present.

Fixes: 14a0fc8 ("rdma-core/irdma: Implement device supported verb APIs")
Signed-off-by: Mustafa Ismail <mustafa.ismail@intel.com>
Signed-off-by: Tatyana Nikolova <tatyana.e.nikolova@intel.com>
  • Loading branch information
mustafakismail authored and tatyana-en committed Oct 28, 2022
1 parent c87c1df commit c8b3aca
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 45 deletions.
13 changes: 6 additions & 7 deletions providers/irdma/uk.c
Original file line number Diff line number Diff line change
Expand Up @@ -1089,7 +1089,7 @@ irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq, struct irdma_cq_poll_info *info)
__le64 *cqe;
struct irdma_qp_uk *qp;
struct irdma_ring *pring = NULL;
__u32 wqe_idx, q_type;
__u32 wqe_idx;
enum irdma_status_code ret_code;
bool move_cq_head = true;
__u8 polarity;
Expand Down Expand Up @@ -1160,7 +1160,7 @@ irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq, struct irdma_cq_poll_info *info)
info->ud_vlan_valid = false;
}

q_type = (__u8)FIELD_GET(IRDMA_CQ_SQ, qword3);
info->q_type = (__u8)FIELD_GET(IRDMA_CQ_SQ, qword3);
info->error = (bool)FIELD_GET(IRDMA_CQ_ERROR, qword3);
info->push_dropped = (bool)FIELD_GET(IRDMACQ_PSHDROP, qword3);
info->ipv4 = (bool)FIELD_GET(IRDMACQ_IPV4, qword3);
Expand Down Expand Up @@ -1199,8 +1199,9 @@ irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq, struct irdma_cq_poll_info *info)
}
wqe_idx = (__u32)FIELD_GET(IRDMA_CQ_WQEIDX, qword3);
info->qp_handle = (irdma_qp_handle)(uintptr_t)qp;
info->op_type = (__u8)FIELD_GET(IRDMACQ_OP, qword3);

if (q_type == IRDMA_CQE_QTYPE_RQ) {
if (info->q_type == IRDMA_CQE_QTYPE_RQ) {
__u32 array_idx;

array_idx = wqe_idx / qp->rq_wqe_size_multiplier;
Expand Down Expand Up @@ -1275,18 +1276,16 @@ irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq, struct irdma_cq_poll_info *info)
do {
__le64 *sw_wqe;
__u64 wqe_qword;
__u8 op_type;
__u32 tail;

tail = qp->sq_ring.tail;
sw_wqe = qp->sq_base[tail].elem;
get_64bit_val(sw_wqe, 24,
&wqe_qword);
op_type = (__u8)FIELD_GET(IRDMAQPSQ_OPCODE, wqe_qword);
info->op_type = op_type;
info->op_type = (__u8)FIELD_GET(IRDMAQPSQ_OPCODE, wqe_qword);
IRDMA_RING_SET_TAIL(qp->sq_ring,
tail + qp->sq_wrtrk_array[tail].quanta);
if (op_type != IRDMAQP_OP_NOP) {
if (info->op_type != IRDMAQP_OP_NOP) {
info->wr_id = qp->sq_wrtrk_array[tail].wrid;
info->bytes_xfered = qp->sq_wrtrk_array[tail].wr_len;
break;
Expand Down
1 change: 1 addition & 0 deletions providers/irdma/user.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ struct irdma_cq_poll_info {
__u16 ud_vlan;
__u8 ud_smac[6];
__u8 op_type;
__u8 q_type;
bool stag_invalid_set:1; /* or L_R_Key set */
bool push_dropped:1;
bool error:1;
Expand Down
96 changes: 58 additions & 38 deletions providers/irdma/uverbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <fcntl.h>
#include <malloc.h>
#include <linux/if_ether.h>
#include <infiniband/opcode.h>

#include "umain.h"
#include "abi.h"
Expand Down Expand Up @@ -568,6 +569,55 @@ static enum ibv_wc_status irdma_flush_err_to_ib_wc_status(enum irdma_flush_opcod
}
}

static inline void set_ib_wc_op_sq(struct irdma_cq_poll_info *cur_cqe, struct ibv_wc *entry)
{
switch (cur_cqe->op_type) {
case IRDMA_OP_TYPE_RDMA_WRITE:
case IRDMA_OP_TYPE_RDMA_WRITE_SOL:
entry->opcode = IBV_WC_RDMA_WRITE;
break;
case IRDMA_OP_TYPE_RDMA_READ:
entry->opcode = IBV_WC_RDMA_READ;
break;
case IRDMA_OP_TYPE_SEND_SOL:
case IRDMA_OP_TYPE_SEND_SOL_INV:
case IRDMA_OP_TYPE_SEND_INV:
case IRDMA_OP_TYPE_SEND:
entry->opcode = IBV_WC_SEND;
break;
case IRDMA_OP_TYPE_BIND_MW:
entry->opcode = IBV_WC_BIND_MW;
break;
case IRDMA_OP_TYPE_INV_STAG:
entry->opcode = IBV_WC_LOCAL_INV;
break;
default:
entry->status = IBV_WC_GENERAL_ERR;
}
}

static inline void set_ib_wc_op_rq(struct irdma_cq_poll_info *cur_cqe,
struct ibv_wc *entry, bool send_imm_support)
{
/**
* iWARP does not support sendImm, so the presence of Imm data
* must be WriteImm.
*/
if (!send_imm_support) {
entry->opcode = cur_cqe->imm_valid ? IBV_WC_RECV_RDMA_WITH_IMM :
IBV_WC_RECV;
return;
}
switch (cur_cqe->op_type) {
case IBV_OPCODE_RDMA_WRITE_ONLY_WITH_IMMEDIATE:
case IBV_OPCODE_RDMA_WRITE_LAST_WITH_IMMEDIATE:
entry->opcode = IBV_WC_RECV_RDMA_WITH_IMM;
break;
default:
entry->opcode = IBV_WC_RECV;
}
}

/**
* irdma_process_cqe_ext - process current cqe for extended CQ
* @cur_cqe - current cqe info
Expand Down Expand Up @@ -602,9 +652,8 @@ static void irdma_process_cqe(struct ibv_wc *entry, struct irdma_cq_poll_info *c
ib_qp = qp->back_qp;

if (cur_cqe->error) {
if (cur_cqe->comp_status == IRDMA_COMPL_STATUS_FLUSHED)
entry->status = (cur_cqe->comp_status == IRDMA_COMPL_STATUS_FLUSHED) ?
irdma_flush_err_to_ib_wc_status(cur_cqe->minor_err) : IBV_WC_GENERAL_ERR;
entry->status = (cur_cqe->comp_status == IRDMA_COMPL_STATUS_FLUSHED) ?
irdma_flush_err_to_ib_wc_status(cur_cqe->minor_err) : IBV_WC_GENERAL_ERR;
entry->vendor_err = cur_cqe->major_err << 16 |
cur_cqe->minor_err;
} else {
Expand All @@ -616,48 +665,19 @@ static void irdma_process_cqe(struct ibv_wc *entry, struct irdma_cq_poll_info *c
entry->wc_flags |= IBV_WC_WITH_IMM;
}

switch (cur_cqe->op_type) {
case IRDMA_OP_TYPE_RDMA_WRITE:
case IRDMA_OP_TYPE_RDMA_WRITE_SOL:
entry->opcode = IBV_WC_RDMA_WRITE;
break;
case IRDMA_OP_TYPE_RDMA_READ:
entry->opcode = IBV_WC_RDMA_READ;
break;
case IRDMA_OP_TYPE_SEND_SOL:
case IRDMA_OP_TYPE_SEND_SOL_INV:
case IRDMA_OP_TYPE_SEND_INV:
case IRDMA_OP_TYPE_SEND:
entry->opcode = IBV_WC_SEND;
break;
case IRDMA_OP_TYPE_BIND_MW:
entry->opcode = IBV_WC_BIND_MW;
break;
case IRDMA_OP_TYPE_REC:
entry->opcode = IBV_WC_RECV;
if (ib_qp->qp_type != IBV_QPT_UD &&
cur_cqe->stag_invalid_set) {
entry->invalidated_rkey = cur_cqe->inv_stag;
entry->wc_flags |= IBV_WC_WITH_INV;
}
break;
case IRDMA_OP_TYPE_REC_IMM:
entry->opcode = IBV_WC_RECV_RDMA_WITH_IMM;
if (cur_cqe->q_type == IRDMA_CQE_QTYPE_SQ) {
set_ib_wc_op_sq(cur_cqe, entry);
} else {
set_ib_wc_op_rq(cur_cqe, entry,
qp->qp_caps & IRDMA_SEND_WITH_IMM ?
true : false);
if (ib_qp->qp_type != IBV_QPT_UD &&
cur_cqe->stag_invalid_set) {
entry->invalidated_rkey = cur_cqe->inv_stag;
entry->wc_flags |= IBV_WC_WITH_INV;
}
break;
case IRDMA_OP_TYPE_INV_STAG:
entry->opcode = IBV_WC_LOCAL_INV;
break;
default:
entry->status = IBV_WC_GENERAL_ERR;
return;
}


if (ib_qp->qp_type == IBV_QPT_UD) {
entry->src_qp = cur_cqe->ud_src_qpn;
entry->wc_flags |= IBV_WC_GRH;
Expand Down

0 comments on commit c8b3aca

Please sign in to comment.