@@ -348,22 +348,34 @@ static inline enum comp_state check_ack(struct rxe_qp *qp,
return COMPST_ERROR;
}
-static inline enum comp_state do_read(struct rxe_qp *qp,
- struct rxe_pkt_info *pkt,
- struct rxe_send_wqe *wqe)
+/**
+ * rxe_do_read() - Process read reply packet
+ * @qp: The queue pair
+ * @pkt: Packet info
+ * @wqe: The current work request
+ *
+ * Copy payload from incoming read reply packet into current
+ * iova.
+ *
+ * Returns: 0 on success else an error comp_state
+ */
+static inline enum comp_state rxe_do_read(struct rxe_qp *qp,
+ struct rxe_pkt_info *pkt,
+ struct rxe_send_wqe *wqe)
{
struct sk_buff *skb = PKT_TO_SKB(pkt);
- int skb_offset = 0;
- int ret;
-
- ret = rxe_copy_dma_data(skb, qp->pd, IB_ACCESS_LOCAL_WRITE,
- &wqe->dma, payload_addr(pkt),
- skb_offset, payload_size(pkt),
- RXE_COPY_TO_MR);
- if (ret) {
- wqe->status = IB_WC_LOC_PROT_ERR;
+ int nr_frags = skb_shinfo(skb)->nr_frags;
+ u8 *data_addr = payload_addr(pkt);
+ int data_len = payload_size(pkt);
+ enum rxe_mr_copy_op op = nr_frags ? RXE_FRAG_TO_MR : RXE_COPY_TO_MR;
+ int skb_offset = data_addr - skb_transport_header(skb);
+ int err;
+
+ err = rxe_copy_dma_data(skb, qp->pd, IB_ACCESS_LOCAL_WRITE,
+ &wqe->dma, data_addr,
+ skb_offset, data_len, op);
+ if (err)
return COMPST_ERROR;
- }
if (wqe->dma.resid == 0 && (pkt->mask & RXE_END_MASK))
return COMPST_COMP_ACK;
@@ -625,7 +637,7 @@ int rxe_completer(void *arg)
break;
case COMPST_READ:
- state = do_read(qp, pkt, wqe);
+ state = rxe_do_read(qp, pkt, wqe);
break;
case COMPST_ATOMIC:
Extend do_read() in rxe_comp.c to support fragmented skbs. Rename rxe_do_read(). Adjust caller's API. Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com> --- drivers/infiniband/sw/rxe/rxe_comp.c | 40 ++++++++++++++++++---------- 1 file changed, 26 insertions(+), 14 deletions(-)