Skip to content

Commit

Permalink
IB/ipath: Fix receiving UD messages with immediate data
Browse files Browse the repository at this point in the history
This fixes a small bug in ipath_ud_rcv()'s handling of UD messages
with immediate data.  We need to test whether immediate data is
present and update the header size accordingly *before* testing the
packet size from the header against the actual received length.
Otherwise the wrong header size will be used and all messages with
immediate data will be dropped.

This bug keeps MVAPICH-UD and HP MPI from working at all on ipath devices.

Signed-off-by: Ralph Campbell <ralph.campbell@qlogic.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
  • Loading branch information
Ralph Campbell authored and Roland Dreier committed Jan 16, 2008
1 parent cdf71a1 commit 0a69631
Showing 1 changed file with 22 additions and 22 deletions.
44 changes: 22 additions & 22 deletions drivers/infiniband/hw/ipath/ipath_ud.c
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,28 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
}
}

/*
* The opcode is in the low byte when its in network order
* (top byte when in host order).
*/
opcode = be32_to_cpu(ohdr->bth[0]) >> 24;
if (qp->ibqp.qp_num > 1 &&
opcode == IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE) {
if (header_in_data) {
wc.imm_data = *(__be32 *) data;
data += sizeof(__be32);
} else
wc.imm_data = ohdr->u.ud.imm_data;
wc.wc_flags = IB_WC_WITH_IMM;
hdrsize += sizeof(u32);
} else if (opcode == IB_OPCODE_UD_SEND_ONLY) {
wc.imm_data = 0;
wc.wc_flags = 0;
} else {
dev->n_pkt_drops++;
goto bail;
}

/* Get the number of bytes the message was padded by. */
pad = (be32_to_cpu(ohdr->bth[0]) >> 20) & 3;
if (unlikely(tlen < (hdrsize + pad + 4))) {
Expand All @@ -481,28 +503,6 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
*/
wc.byte_len = tlen + sizeof(struct ib_grh);

/*
* The opcode is in the low byte when its in network order
* (top byte when in host order).
*/
opcode = be32_to_cpu(ohdr->bth[0]) >> 24;
if (qp->ibqp.qp_num > 1 &&
opcode == IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE) {
if (header_in_data) {
wc.imm_data = *(__be32 *) data;
data += sizeof(__be32);
} else
wc.imm_data = ohdr->u.ud.imm_data;
wc.wc_flags = IB_WC_WITH_IMM;
hdrsize += sizeof(u32);
} else if (opcode == IB_OPCODE_UD_SEND_ONLY) {
wc.imm_data = 0;
wc.wc_flags = 0;
} else {
dev->n_pkt_drops++;
goto bail;
}

/*
* Get the next work request entry to find where to put the data.
*/
Expand Down

0 comments on commit 0a69631

Please sign in to comment.