Skip to content

Commit cbc0a40

Browse files
keithbuschaxboe
authored andcommitted
lib: add rocksoft model crc64
The NVM Express specification extended data integrity fields to 64 bits using the Rocksoft parameters. Add the poly to the crc64 table generation, and provide a generic library routine implementing the algorithm. The Rocksoft 64-bit CRC model parameters are as follows: Poly: 0xAD93D23594C93659 Initial value: 0xFFFFFFFFFFFFFFFF Reflected Input: True Reflected Output: True Xor Final: 0xFFFFFFFFFFFFFFFF Since this model used reflected bits, the implementation generates the reflected table so the result is ordered consistently. Cc: Christoph Hellwig <[email protected]> Cc: Hannes Reinecke <[email protected]> Cc: Martin K. Petersen <[email protected]> Signed-off-by: Keith Busch <[email protected]> Reviewed-by: Martin K. Petersen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent 7ee8809 commit cbc0a40

File tree

3 files changed

+70
-11
lines changed

3 files changed

+70
-11
lines changed

include/linux/crc64.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,6 @@
88
#include <linux/types.h>
99

1010
u64 __pure crc64_be(u64 crc, const void *p, size_t len);
11+
u64 __pure crc64_rocksoft_generic(u64 crc, const void *p, size_t len);
12+
1113
#endif /* _LINUX_CRC64_H */

lib/crc64.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@
2222
* x^24 + x^23 + x^22 + x^21 + x^19 + x^17 + x^13 + x^12 + x^10 + x^9 +
2323
* x^7 + x^4 + x + 1
2424
*
25+
* crc64rocksoft[256] table is from the Rocksoft specification polynomial
26+
* defined as,
27+
*
28+
* x^64 + x^63 + x^61 + x^59 + x^58 + x^56 + x^55 + x^52 + x^49 + x^48 + x^47 +
29+
* x^46 + x^44 + x^41 + x^37 + x^36 + x^34 + x^32 + x^31 + x^28 + x^26 + x^23 +
30+
* x^22 + x^19 + x^16 + x^13 + x^12 + x^10 + x^9 + x^6 + x^4 + x^3 + 1
31+
*
2532
* Copyright 2018 SUSE Linux.
2633
* Author: Coly Li <[email protected]>
2734
*/
@@ -55,3 +62,24 @@ u64 __pure crc64_be(u64 crc, const void *p, size_t len)
5562
return crc;
5663
}
5764
EXPORT_SYMBOL_GPL(crc64_be);
65+
66+
/**
67+
* crc64_rocksoft_generic - Calculate bitwise Rocksoft CRC64
68+
* @crc: seed value for computation. 0 for a new CRC calculation, or the
69+
* previous crc64 value if computing incrementally.
70+
* @p: pointer to buffer over which CRC64 is run
71+
* @len: length of buffer @p
72+
*/
73+
u64 __pure crc64_rocksoft_generic(u64 crc, const void *p, size_t len)
74+
{
75+
const unsigned char *_p = p;
76+
size_t i;
77+
78+
crc = ~crc;
79+
80+
for (i = 0; i < len; i++)
81+
crc = (crc >> 8) ^ crc64rocksofttable[(crc & 0xff) ^ *_p++];
82+
83+
return ~crc;
84+
}
85+
EXPORT_SYMBOL_GPL(crc64_rocksoft_generic);

lib/gen_crc64table.c

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,30 @@
1717
#include <stdio.h>
1818

1919
#define CRC64_ECMA182_POLY 0x42F0E1EBA9EA3693ULL
20+
#define CRC64_ROCKSOFT_POLY 0x9A6C9329AC4BC9B5ULL
2021

2122
static uint64_t crc64_table[256] = {0};
23+
static uint64_t crc64_rocksoft_table[256] = {0};
2224

23-
static void generate_crc64_table(void)
25+
static void generate_reflected_crc64_table(uint64_t table[256], uint64_t poly)
26+
{
27+
uint64_t i, j, c, crc;
28+
29+
for (i = 0; i < 256; i++) {
30+
crc = 0ULL;
31+
c = i;
32+
33+
for (j = 0; j < 8; j++) {
34+
if ((crc ^ (c >> j)) & 1)
35+
crc = (crc >> 1) ^ poly;
36+
else
37+
crc >>= 1;
38+
}
39+
table[i] = crc;
40+
}
41+
}
42+
43+
static void generate_crc64_table(uint64_t table[256], uint64_t poly)
2444
{
2545
uint64_t i, j, c, crc;
2646

@@ -30,26 +50,22 @@ static void generate_crc64_table(void)
3050

3151
for (j = 0; j < 8; j++) {
3252
if ((crc ^ c) & 0x8000000000000000ULL)
33-
crc = (crc << 1) ^ CRC64_ECMA182_POLY;
53+
crc = (crc << 1) ^ poly;
3454
else
3555
crc <<= 1;
3656
c <<= 1;
3757
}
3858

39-
crc64_table[i] = crc;
59+
table[i] = crc;
4060
}
4161
}
4262

43-
static void print_crc64_table(void)
63+
static void output_table(uint64_t table[256])
4464
{
4565
int i;
4666

47-
printf("/* this file is generated - do not edit */\n\n");
48-
printf("#include <linux/types.h>\n");
49-
printf("#include <linux/cache.h>\n\n");
50-
printf("static const u64 ____cacheline_aligned crc64table[256] = {\n");
5167
for (i = 0; i < 256; i++) {
52-
printf("\t0x%016" PRIx64 "ULL", crc64_table[i]);
68+
printf("\t0x%016" PRIx64 "ULL", table[i]);
5369
if (i & 0x1)
5470
printf(",\n");
5571
else
@@ -58,9 +74,22 @@ static void print_crc64_table(void)
5874
printf("};\n");
5975
}
6076

77+
static void print_crc64_tables(void)
78+
{
79+
printf("/* this file is generated - do not edit */\n\n");
80+
printf("#include <linux/types.h>\n");
81+
printf("#include <linux/cache.h>\n\n");
82+
printf("static const u64 ____cacheline_aligned crc64table[256] = {\n");
83+
output_table(crc64_table);
84+
85+
printf("\nstatic const u64 ____cacheline_aligned crc64rocksofttable[256] = {\n");
86+
output_table(crc64_rocksoft_table);
87+
}
88+
6189
int main(int argc, char *argv[])
6290
{
63-
generate_crc64_table();
64-
print_crc64_table();
91+
generate_crc64_table(crc64_table, CRC64_ECMA182_POLY);
92+
generate_reflected_crc64_table(crc64_rocksoft_table, CRC64_ROCKSOFT_POLY);
93+
print_crc64_tables();
6594
return 0;
6695
}

0 commit comments

Comments
 (0)