[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250129183009.GC2120662@ziepe.ca>
Date: Wed, 29 Jan 2025 14:30:09 -0400
From: Jason Gunthorpe <jgg@...pe.ca>
To: Zhu Yanjun <yanjun.zhu@...ux.dev>
Cc: Eric Biggers <ebiggers@...nel.org>, linux-rdma@...r.kernel.org,
Mustafa Ismail <mustafa.ismail@...el.com>,
Tatyana Nikolova <tatyana.e.nikolova@...el.com>,
Leon Romanovsky <leon@...nel.org>,
Zhu Yanjun <zyjzyj2000@...il.com>,
Bernard Metzler <bmt@...ich.ibm.com>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
Subject: Re: [PATCH 1/6] RDMA/rxe: handle ICRC correctly on big endian systems
On Wed, Jan 29, 2025 at 10:44:39AM +0100, Zhu Yanjun wrote:
> 在 2025/1/27 23:38, Eric Biggers 写道:
> > From: Eric Biggers <ebiggers@...gle.com>
> >
> > The usual big endian convention of InfiniBand does not apply to the
> > ICRC field, whose transmission is specified in terms of the CRC32
> > polynomial coefficients.
This patch is on to something but this is not a good explanation.
The CRC32 in IB is stored as big endian and computed in big endian,
the spec says so explicitly:
2) The CRC calculation is done in big endian byte order with the least
31 significant bit of the most significant byte being the first
bits in the 32 CRC calculation.
In this context saying it is not "big endian" doesn't seem to be quite
right..
The spec gives a sample data packet (in offset/value pairs):
0 0xF0 15 0xB3 30 0x7A 45 0x8B
1 0x12 16 0x00 31 0x05 46 0xC0
2 0x37 17 0x0D 32 0x00 47 0x69
3 0x5C 18 0xEC 33 0x00 48 0x0E
4 0x00 19 0x2A 34 0x00 49 0xD4
5 0x0E 20 0x01 35 0x0E 50 0x00
6 0x17 21 0x71 36 0xBB 51 0x00
7 0xD2 22 0x0A 37 0x88
8 0x0A 23 0x1C 38 0x4D
9 0x20 24 0x01 39 0x85
10 0x24 25 0x5D 40 0xFD
11 0x87 26 0x40 41 0x5C
12 0xFF 27 0x02 42 0xFB
13 0x87 28 0x38 43 0xA4
14 0xB1 29 0xF2 44 0x72
If you feed that to the CRC32 you should get 0x9625B75A in a CPU
register u32.
cpu_to_be32() will put it in the right order for on the wire.
Since rxe doesn't have any cpu_to_be32() on this path, I'm guessing
the Linux CRC32 implementations gives a u32 with the
value = 0x5AB72596 ie swapped.
Probably the issue here is that the Linux CRC32 and the IBTA CRC32 are
using a different mapping of LFSR bits. I love CRCs. So many different
ways to implement the same thing.
Thus, I guess, the code should really read:
linux_crc32 = swab32(be32_to_cpu(val));
Which is a NOP on x86 and requires a swap on BE.
Zhu, can you check it for Eric? (this is page 229 in the spec).
I assume the Linux CRC32 always gives the same CPU value regardless of
LE or BE?
Jason
Powered by blists - more mailing lists