summaryrefslogtreecommitdiff
path: root/include/linux/crc32.h
diff options
context:
space:
mode:
authorGeorge Spelvin <linux@horizon.com>2014-06-23 15:11:54 +0200
committerDavid S. Miller <davem@davemloft.net>2014-06-25 16:03:59 -0700
commit6d514b4e7737ad75a7e7e0a3f7dde45d46341691 (patch)
tree20edf4e5f96fbf08e9e0136fec63bf13009f026a /include/linux/crc32.h
parent5433ba365f6dd9f30899188755eb4b093314732c (diff)
lib: crc32: Greatly shrink CRC combining code
There's no need for a full 32x32 matrix, when rows before the last are just shifted copies of the rows after them. There's still room for improvement (especially on X86 processors with CRC32 and PCLMUL instructions), but this is a large step in the right direction [which is in particular useful for its current user, namely SCTP checksumming over multiple skb frags[] entries, i.e. in IPVS balancing when other CRC32 offloads are not available]. The internal primitive is now called crc32_generic_shift and takes one less argument; the XOR with crc2 is done in inline wrappers. Signed-off-by: George Spelvin <linux@horizon.com> Signed-off-by: Daniel Borkmann <dborkman@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/crc32.h')
-rw-r--r--include/linux/crc32.h14
1 files changed, 12 insertions, 2 deletions
diff --git a/include/linux/crc32.h b/include/linux/crc32.h
index 7d275c4fc011..edf34e876e40 100644
--- a/include/linux/crc32.h
+++ b/include/linux/crc32.h
@@ -29,7 +29,12 @@ extern u32 crc32_be(u32 crc, unsigned char const *p, size_t len);
* with the same initializer as crc1, and crc2 seed was 0. See
* also crc32_combine_test().
*/
-extern u32 crc32_le_combine(u32 crc1, u32 crc2, size_t len2);
+u32 __attribute_const__ crc32_le_shift(u32 crc, size_t len);
+
+static inline u32 crc32_le_combine(u32 crc1, u32 crc2, size_t len2)
+{
+ return crc32_le_shift(crc1, len2) ^ crc2;
+}
extern u32 __crc32c_le(u32 crc, unsigned char const *p, size_t len);
@@ -51,7 +56,12 @@ extern u32 __crc32c_le(u32 crc, unsigned char const *p, size_t len);
* seeded with the same initializer as crc1, and crc2 seed
* was 0. See also crc32c_combine_test().
*/
-extern u32 __crc32c_le_combine(u32 crc1, u32 crc2, size_t len2);
+u32 __attribute_const__ __crc32c_le_shift(u32 crc, size_t len);
+
+static inline u32 __crc32c_le_combine(u32 crc1, u32 crc2, size_t len2)
+{
+ return __crc32c_le_shift(crc1, len2) ^ crc2;
+}
#define crc32(seed, data, length) crc32_le(seed, (unsigned char const *)(data), length)