mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/
synced 2025-04-19 20:58:31 +09:00
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 <ardb@kernel.org> Reviewed-by: "Martin K. Petersen" <martin.petersen@oracle.com> Acked-by: Keith Busch <kbusch@kernel.org> Link: https://lore.kernel.org/r/20250130035130.180676-6-ebiggers@kernel.org Signed-off-by: Eric Biggers <ebiggers@google.com>
This commit is contained in:
parent
23709bd3c4
commit
067bc8717a
@ -7,8 +7,24 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
u64 __pure crc64_be(u64 crc, const void *p, size_t len);
|
||||
u64 __pure crc64_nvme_generic(u64 crc, const void *p, size_t len);
|
||||
u64 crc64_be_arch(u64 crc, const u8 *p, size_t len);
|
||||
u64 crc64_be_generic(u64 crc, const u8 *p, size_t len);
|
||||
u64 crc64_nvme_arch(u64 crc, const u8 *p, size_t len);
|
||||
u64 crc64_nvme_generic(u64 crc, const u8 *p, size_t len);
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
static inline u64 crc64_be(u64 crc, const void *p, size_t len)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_CRC64_ARCH))
|
||||
return crc64_be_arch(crc, p, len);
|
||||
return crc64_be_generic(crc, p, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* crc64_nvme - Calculate CRC64-NVME
|
||||
@ -20,9 +36,11 @@ u64 __pure crc64_nvme_generic(u64 crc, const void *p, size_t len);
|
||||
* This computes the CRC64 defined in the NVME NVM Command Set Specification,
|
||||
* *including the bitwise inversion at the beginning and end*.
|
||||
*/
|
||||
static inline u64 crc64_nvme(u64 crc, const u8 *p, size_t len)
|
||||
static inline u64 crc64_nvme(u64 crc, const void *p, size_t len)
|
||||
{
|
||||
return crc64_nvme_generic(crc, p, len);
|
||||
if (IS_ENABLED(CONFIG_CRC64_ARCH))
|
||||
return ~crc64_nvme_arch(~crc, p, len);
|
||||
return ~crc64_nvme_generic(~crc, p, len);
|
||||
}
|
||||
|
||||
#endif /* _LINUX_CRC64_H */
|
||||
|
@ -201,6 +201,13 @@ config CRC64
|
||||
the kernel tree does. Such modules that use library CRC64
|
||||
functions require M here.
|
||||
|
||||
config ARCH_HAS_CRC64
|
||||
bool
|
||||
|
||||
config CRC64_ARCH
|
||||
tristate
|
||||
default CRC64 if ARCH_HAS_CRC64 && CRC_OPTIMIZATIONS
|
||||
|
||||
config CRC4
|
||||
tristate "CRC4 functions"
|
||||
help
|
||||
|
36
lib/crc64.c
36
lib/crc64.c
@ -41,38 +41,18 @@
|
||||
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)
|
||||
u64 crc64_be_generic(u64 crc, const u8 *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);
|
||||
}
|
||||
|
||||
while (len--)
|
||||
crc = (crc << 8) ^ crc64table[(crc >> 56) ^ *p++];
|
||||
return crc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crc64_be);
|
||||
EXPORT_SYMBOL_GPL(crc64_be_generic);
|
||||
|
||||
u64 __pure crc64_nvme_generic(u64 crc, const void *p, size_t len)
|
||||
u64 crc64_nvme_generic(u64 crc, const u8 *p, size_t len)
|
||||
{
|
||||
const unsigned char *_p = p;
|
||||
size_t i;
|
||||
|
||||
crc = ~crc;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
crc = (crc >> 8) ^ crc64nvmetable[(crc & 0xff) ^ *_p++];
|
||||
|
||||
return ~crc;
|
||||
while (len--)
|
||||
crc = (crc >> 8) ^ crc64nvmetable[(crc & 0xff) ^ *p++];
|
||||
return crc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crc64_nvme_generic);
|
||||
|
Loading…
x
Reference in New Issue
Block a user