RDMA/ocrdma: Consider multiple SGES in case of DPP
While posting inline DPP data, we are not considering multiple sges. Fix this. Signed-off-by: Naresh Gottumukkala <bgottumukkala@emulex.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
This commit is contained in:
parent
f24ceba6b6
commit
117e6dd1c5
|
@ -1820,24 +1820,42 @@ static void ocrdma_build_sges(struct ocrdma_hdr_wqe *hdr,
|
||||||
memset(sge, 0, sizeof(*sge));
|
memset(sge, 0, sizeof(*sge));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint32_t ocrdma_sglist_len(struct ib_sge *sg_list, int num_sge)
|
||||||
|
{
|
||||||
|
uint32_t total_len = 0, i;
|
||||||
|
|
||||||
|
for (i = 0; i < num_sge; i++)
|
||||||
|
total_len += sg_list[i].length;
|
||||||
|
return total_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int ocrdma_build_inline_sges(struct ocrdma_qp *qp,
|
static int ocrdma_build_inline_sges(struct ocrdma_qp *qp,
|
||||||
struct ocrdma_hdr_wqe *hdr,
|
struct ocrdma_hdr_wqe *hdr,
|
||||||
struct ocrdma_sge *sge,
|
struct ocrdma_sge *sge,
|
||||||
struct ib_send_wr *wr, u32 wqe_size)
|
struct ib_send_wr *wr, u32 wqe_size)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
char *dpp_addr;
|
||||||
|
|
||||||
if (wr->send_flags & IB_SEND_INLINE && qp->qp_type != IB_QPT_UD) {
|
if (wr->send_flags & IB_SEND_INLINE && qp->qp_type != IB_QPT_UD) {
|
||||||
if (wr->sg_list[0].length > qp->max_inline_data) {
|
hdr->total_len = ocrdma_sglist_len(wr->sg_list, wr->num_sge);
|
||||||
|
if (unlikely(hdr->total_len > qp->max_inline_data)) {
|
||||||
pr_err("%s() supported_len=0x%x,\n"
|
pr_err("%s() supported_len=0x%x,\n"
|
||||||
" unspported len req=0x%x\n", __func__,
|
" unspported len req=0x%x\n", __func__,
|
||||||
qp->max_inline_data, wr->sg_list[0].length);
|
qp->max_inline_data, hdr->total_len);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
memcpy(sge,
|
dpp_addr = (char *)sge;
|
||||||
(void *)(unsigned long)wr->sg_list[0].addr,
|
for (i = 0; i < wr->num_sge; i++) {
|
||||||
wr->sg_list[0].length);
|
memcpy(dpp_addr,
|
||||||
hdr->total_len = wr->sg_list[0].length;
|
(void *)(unsigned long)wr->sg_list[i].addr,
|
||||||
|
wr->sg_list[i].length);
|
||||||
|
dpp_addr += wr->sg_list[i].length;
|
||||||
|
}
|
||||||
|
|
||||||
wqe_size += roundup(hdr->total_len, OCRDMA_WQE_ALIGN_BYTES);
|
wqe_size += roundup(hdr->total_len, OCRDMA_WQE_ALIGN_BYTES);
|
||||||
if (0 == wr->sg_list[0].length)
|
if (0 == hdr->total_len)
|
||||||
wqe_size += sizeof(struct ocrdma_sge);
|
wqe_size += sizeof(struct ocrdma_sge);
|
||||||
hdr->cw |= (OCRDMA_TYPE_INLINE << OCRDMA_WQE_TYPE_SHIFT);
|
hdr->cw |= (OCRDMA_TYPE_INLINE << OCRDMA_WQE_TYPE_SHIFT);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue