forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Patch series "add crc64 calculation as kernel library", v5. This patchset adds basic implementation of crc64 calculation as a Linux kernel library. Since bcache already does crc64 by itself, this patchset also modifies bcache code to use the new crc64 library routine. Currently bcache is the only user of crc64 calculation, another potential user is bcachefs which is on the way to be in mainline kernel. Therefore it makes sense to make crc64 calculation to be a public library. bcache uses crc64 as storage checksum, if a change of crc lib routines results an inconsistent result, the unmatched checksum may make bcache 'think' the on-disk is corrupted, such a change should be avoided or detected as early as possible. Therefore a patch is being prepared which adds a crc test framework, to check consistency of different calculations. This patch (of 2): Add the re-write crc64 calculation routines for Linux kernel. The CRC64 polynomical arithmetic follows ECMA-182 specification, inspired by CRC paper of Dr. Ross N. Williams (see http://www.ross.net/crc/download/crc_v3.txt) and other public domain implementations. All the changes work in this way, - When Linux kernel is built, host program lib/gen_crc64table.c will be compiled to lib/gen_crc64table and executed. - The output of gen_crc64table execution is an array called as lookup table (a.k.a POLY 0x42f0e1eba9ea369) which contain 256 64-bit long numbers, this table is dumped into header file lib/crc64table.h. - Then the header file is included by lib/crc64.c for normal 64bit crc calculation. - Function declaration of the crc64 calculation routines is placed in include/linux/crc64.h Currently bcache is the only user of crc64_be(), another potential user is bcachefs which is on the way to be in mainline kernel. Therefore it makes sense to move crc64 calculation into lib/crc64.c as public code. [[email protected]: fix review comments from v4] Link: http://lkml.kernel.org/r/[email protected] Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Coly Li <[email protected]> Co-developed-by: Andy Shevchenko <[email protected]> Signed-off-by: Andy Shevchenko <[email protected]> Reviewed-by: Hannes Reinecke <[email protected]> Cc: Greg Kroah-Hartman <[email protected]> Cc: Andy Shevchenko <[email protected]> Cc: Michael Lyle <[email protected]> Cc: Kent Overstreet <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Kate Stewart <[email protected]> Cc: Eric Biggers <[email protected]> Cc: Randy Dunlap <[email protected]> Cc: Noah Massey <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
- Loading branch information
Showing
6 changed files
with
156 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
/* | ||
* See lib/crc64.c for the related specification and polynomial arithmetic. | ||
*/ | ||
#ifndef _LINUX_CRC64_H | ||
#define _LINUX_CRC64_H | ||
|
||
#include <linux/types.h> | ||
|
||
u64 __pure crc64_be(u64 crc, const void *p, size_t len); | ||
#endif /* _LINUX_CRC64_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,5 +2,7 @@ | |
# Generated files | ||
# | ||
gen_crc32table | ||
gen_crc64table | ||
crc32table.h | ||
crc64table.h | ||
oid_registry_data.c |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* Normal 64-bit CRC calculation. | ||
* | ||
* This is a basic crc64 implementation following ECMA-182 specification, | ||
* which can be found from, | ||
* http://www.ecma-international.org/publications/standards/Ecma-182.htm | ||
* | ||
* Dr. Ross N. Williams has a great document to introduce the idea of CRC | ||
* algorithm, here the CRC64 code is also inspired by the table-driven | ||
* algorithm and detail example from this paper. This paper can be found | ||
* from, | ||
* http://www.ross.net/crc/download/crc_v3.txt | ||
* | ||
* crc64table[256] is the lookup table of a table-driven 64-bit CRC | ||
* calculation, which is generated by gen_crc64table.c in kernel build | ||
* time. The polynomial of crc64 arithmetic is from ECMA-182 specification | ||
* as well, which is defined as, | ||
* | ||
* x^64 + x^62 + x^57 + x^55 + x^54 + x^53 + x^52 + x^47 + x^46 + x^45 + | ||
* x^40 + x^39 + x^38 + x^37 + x^35 + x^33 + x^32 + x^31 + x^29 + x^27 + | ||
* x^24 + x^23 + x^22 + x^21 + x^19 + x^17 + x^13 + x^12 + x^10 + x^9 + | ||
* x^7 + x^4 + x + 1 | ||
* | ||
* Copyright 2018 SUSE Linux. | ||
* Author: Coly Li <[email protected]> | ||
*/ | ||
|
||
#include <linux/module.h> | ||
#include <linux/types.h> | ||
#include "crc64table.h" | ||
|
||
MODULE_DESCRIPTION("CRC64 calculations"); | ||
MODULE_LICENSE("GPL v2"); | ||
|
||
/** | ||
* crc64_be - Calculate bitwise big-endian ECMA-182 CRC64 | ||
* @crc: seed value for computation. 0 or (u64)~0 for a new CRC calculation, | ||
or the previous crc64 value if computing incrementally. | ||
* @p: pointer to buffer over which CRC64 is run | ||
* @len: length of buffer @p | ||
*/ | ||
u64 __pure crc64_be(u64 crc, const void *p, size_t len) | ||
{ | ||
size_t i, t; | ||
|
||
const unsigned char *_p = p; | ||
|
||
for (i = 0; i < len; i++) { | ||
t = ((crc >> 56) ^ (*_p++)) & 0xFF; | ||
crc = crc64table[t] ^ (crc << 8); | ||
} | ||
|
||
return crc; | ||
} | ||
EXPORT_SYMBOL_GPL(crc64_be); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* Generate lookup table for the table-driven CRC64 calculation. | ||
* | ||
* gen_crc64table is executed in kernel build time and generates | ||
* lib/crc64table.h. This header is included by lib/crc64.c for | ||
* the table-driven CRC64 calculation. | ||
* | ||
* See lib/crc64.c for more information about which specification | ||
* and polynomial arithmetic that gen_crc64table.c follows to | ||
* generate the lookup table. | ||
* | ||
* Copyright 2018 SUSE Linux. | ||
* Author: Coly Li <[email protected]> | ||
*/ | ||
#include <inttypes.h> | ||
#include <stdio.h> | ||
|
||
#include <linux/swab.h> | ||
|
||
#define CRC64_ECMA182_POLY 0x42F0E1EBA9EA3693ULL | ||
|
||
static uint64_t crc64_table[256] = {0}; | ||
|
||
static void generate_crc64_table(void) | ||
{ | ||
uint64_t i, j, c, crc; | ||
|
||
for (i = 0; i < 256; i++) { | ||
crc = 0; | ||
c = i << 56; | ||
|
||
for (j = 0; j < 8; j++) { | ||
if ((crc ^ c) & 0x8000000000000000ULL) | ||
crc = (crc << 1) ^ CRC64_ECMA182_POLY; | ||
else | ||
crc <<= 1; | ||
c <<= 1; | ||
} | ||
|
||
crc64_table[i] = crc; | ||
} | ||
} | ||
|
||
static void print_crc64_table(void) | ||
{ | ||
int i; | ||
|
||
printf("/* this file is generated - do not edit */\n\n"); | ||
printf("#include <linux/types.h>\n"); | ||
printf("#include <linux/cache.h>\n\n"); | ||
printf("static const u64 ____cacheline_aligned crc64table[256] = {\n"); | ||
for (i = 0; i < 256; i++) { | ||
printf("\t0x%016" PRIx64 "ULL", crc64_table[i]); | ||
if (i & 0x1) | ||
printf(",\n"); | ||
else | ||
printf(", "); | ||
} | ||
printf("};\n"); | ||
} | ||
|
||
int main(int argc, char *argv[]) | ||
{ | ||
generate_crc64_table(); | ||
print_crc64_table(); | ||
return 0; | ||
} |