diff options
author | Jack Morgenstein <jackm@mellanox.co.il> | 2008-01-24 15:53:26 -0800 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2008-01-24 15:53:26 -0800 |
commit | f2533e88c1c7daf4d5618612520eb58b0cff6373 (patch) | |
tree | 7ba37265c810183ba07a6108336298cb99f2ef84 | |
parent | 16ec68c225c41ea0e090b6200385e11e783c2ef7 (diff) | |
download | libmlx4-f2533e88c1c7daf4d5618612520eb58b0cff6373.tar.gz |
Don't use memcpy() to write blueflame sends
Some memcpy() implementations may use move-string-buffer assembly
instructions, which do not guarantee copy order into the blueflame
buffer. This causes problems when writing into a blueflame buffer, so
use our own copy function instead.
Signed-off-by: Jack Morgenstein <jackm@mellanox.co.il>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r-- | src/qp.c | 17 |
1 files changed, 16 insertions, 1 deletions
@@ -168,6 +168,20 @@ static void set_data_seg(struct mlx4_wqe_data_seg *dseg, struct ibv_sge *sg) dseg->byte_count = htonl(sg->length); } +/* + * Avoid using memcpy() to copy to BlueFlame page, since memcpy() + * implementations may use move-string-buffer assembler instructions, + * which do not guarantee order of copying. + */ +static void mlx4_bf_copy(unsigned long *dst, unsigned long *src, unsigned bytecnt) +{ + while (bytecnt > 0) { + *dst++ = *src++; + *dst++ = *src++; + bytecnt -= 2 * sizeof (long); + } +} + int mlx4_post_send(struct ibv_qp *ibqp, struct ibv_send_wr *wr, struct ibv_send_wr **bad_wr) { @@ -388,7 +402,8 @@ out: pthread_spin_lock(&ctx->bf_lock); - memcpy(ctx->bf_page + ctx->bf_offset, ctrl, align(size * 16, 64)); + mlx4_bf_copy(ctx->bf_page + ctx->bf_offset, (unsigned long *) ctrl, + align(size * 16, 64)); wc_wmb(); ctx->bf_offset ^= ctx->bf_buf_size; |