forked from Minki/linux
IB/ipath: Fix receiving UD messages with immediate data
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>
This commit is contained in:
parent
cdf71a10c7
commit
0a69631b28
@ -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))) {
|
||||
@ -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.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user