Skip to content

Commit 067bc87

Browse files
committed
lib/crc64: add support for arch-optimized implementations
Add support for architecture-optimized implementations of the CRC64 library functions, following the approach taken for the CRC32 and CRC-T10DIF library functions. Also take the opportunity to tweak the function prototypes: - Use 'const void *' for the lib entry points (since this is easier for users) but 'const u8 *' for the underlying arch and generic functions (since this is easier for the implementations of these functions). - Don't bother with __pure. It's an unusual optimization that doesn't help properly written code. It's a weird quirk we can do without. Reviewed-by: Ard Biesheuvel <[email protected]> Reviewed-by: "Martin K. Petersen" <[email protected]> Acked-by: Keith Busch <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Eric Biggers <[email protected]>
1 parent 23709bd commit 067bc87

File tree

3 files changed

+37
-32
lines changed

3 files changed

+37
-32
lines changed

include/linux/crc64.h

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,24 @@
77

88
#include <linux/types.h>
99

10-
u64 __pure crc64_be(u64 crc, const void *p, size_t len);
11-
u64 __pure crc64_nvme_generic(u64 crc, const void *p, size_t len);
10+
u64 crc64_be_arch(u64 crc, const u8 *p, size_t len);
11+
u64 crc64_be_generic(u64 crc, const u8 *p, size_t len);
12+
u64 crc64_nvme_arch(u64 crc, const u8 *p, size_t len);
13+
u64 crc64_nvme_generic(u64 crc, const u8 *p, size_t len);
14+
15+
/**
16+
* crc64_be - Calculate bitwise big-endian ECMA-182 CRC64
17+
* @crc: seed value for computation. 0 or (u64)~0 for a new CRC calculation,
18+
* or the previous crc64 value if computing incrementally.
19+
* @p: pointer to buffer over which CRC64 is run
20+
* @len: length of buffer @p
21+
*/
22+
static inline u64 crc64_be(u64 crc, const void *p, size_t len)
23+
{
24+
if (IS_ENABLED(CONFIG_CRC64_ARCH))
25+
return crc64_be_arch(crc, p, len);
26+
return crc64_be_generic(crc, p, len);
27+
}
1228

1329
/**
1430
* crc64_nvme - Calculate CRC64-NVME
@@ -20,9 +36,11 @@ u64 __pure crc64_nvme_generic(u64 crc, const void *p, size_t len);
2036
* This computes the CRC64 defined in the NVME NVM Command Set Specification,
2137
* *including the bitwise inversion at the beginning and end*.
2238
*/
23-
static inline u64 crc64_nvme(u64 crc, const u8 *p, size_t len)
39+
static inline u64 crc64_nvme(u64 crc, const void *p, size_t len)
2440
{
25-
return crc64_nvme_generic(crc, p, len);
41+
if (IS_ENABLED(CONFIG_CRC64_ARCH))
42+
return ~crc64_nvme_arch(~crc, p, len);
43+
return ~crc64_nvme_generic(~crc, p, len);
2644
}
2745

2846
#endif /* _LINUX_CRC64_H */

lib/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,13 @@ config CRC64
201201
the kernel tree does. Such modules that use library CRC64
202202
functions require M here.
203203

204+
config ARCH_HAS_CRC64
205+
bool
206+
207+
config CRC64_ARCH
208+
tristate
209+
default CRC64 if ARCH_HAS_CRC64 && CRC_OPTIMIZATIONS
210+
204211
config CRC4
205212
tristate "CRC4 functions"
206213
help

lib/crc64.c

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -41,38 +41,18 @@
4141
MODULE_DESCRIPTION("CRC64 calculations");
4242
MODULE_LICENSE("GPL v2");
4343

44-
/**
45-
* crc64_be - Calculate bitwise big-endian ECMA-182 CRC64
46-
* @crc: seed value for computation. 0 or (u64)~0 for a new CRC calculation,
47-
* or the previous crc64 value if computing incrementally.
48-
* @p: pointer to buffer over which CRC64 is run
49-
* @len: length of buffer @p
50-
*/
51-
u64 __pure crc64_be(u64 crc, const void *p, size_t len)
44+
u64 crc64_be_generic(u64 crc, const u8 *p, size_t len)
5245
{
53-
size_t i, t;
54-
55-
const unsigned char *_p = p;
56-
57-
for (i = 0; i < len; i++) {
58-
t = ((crc >> 56) ^ (*_p++)) & 0xFF;
59-
crc = crc64table[t] ^ (crc << 8);
60-
}
61-
46+
while (len--)
47+
crc = (crc << 8) ^ crc64table[(crc >> 56) ^ *p++];
6248
return crc;
6349
}
64-
EXPORT_SYMBOL_GPL(crc64_be);
50+
EXPORT_SYMBOL_GPL(crc64_be_generic);
6551

66-
u64 __pure crc64_nvme_generic(u64 crc, const void *p, size_t len)
52+
u64 crc64_nvme_generic(u64 crc, const u8 *p, size_t len)
6753
{
68-
const unsigned char *_p = p;
69-
size_t i;
70-
71-
crc = ~crc;
72-
73-
for (i = 0; i < len; i++)
74-
crc = (crc >> 8) ^ crc64nvmetable[(crc & 0xff) ^ *_p++];
75-
76-
return ~crc;
54+
while (len--)
55+
crc = (crc >> 8) ^ crc64nvmetable[(crc & 0xff) ^ *p++];
56+
return crc;
7757
}
7858
EXPORT_SYMBOL_GPL(crc64_nvme_generic);

0 commit comments

Comments
 (0)