Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp746463imm; Wed, 18 Jul 2018 09:57:46 -0700 (PDT) X-Google-Smtp-Source: AAOMgpdS5CJrkw/PkrKXF3T/Yy70q8xBua0ccAVH/1nbH45Zxdo0ZKnyT/QZ4LnUUkaSFXGVKjq0 X-Received: by 2002:a62:9042:: with SMTP id a63-v6mr6026247pfe.52.1531933065988; Wed, 18 Jul 2018 09:57:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1531933065; cv=none; d=google.com; s=arc-20160816; b=AwCyFziUwBNoTDPKw0dDgKKNfRAgPO0C7d3tH/vHkoSFchUKIfhQqDyrxvbeh7PKeb OeaKvq3PZX2ff2q4gCYYqkCuUqeIdeaE8w1aMbg40bJeR6M8K06gppExB5iMEt8YhXCY yM/4MyhJUB9/gL6HGFA1VhDchE5oh0OcDONSdVpBmXfjqKB0QpDmjwwQBfa1xL3j+14E rUY/xvjoCwH4Hb/T6b/f4Y5Qc2QTwxJ+0zxvvYJEiB24uI9d2cRg6DVGkmON80q7x0uz sYzVxxgrDknUyqyA+GBG5epAZVZknQydBef6xwDpZNEyA7XwxrKPB5p9PS56p856H1zx 0QIA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=a7GhEWalAmfm+kn1ximXAziDA676mFYkseyaQPLSNEY=; b=S9qqerV1cNaJFYfxJQTSbt/s1U9hu+xri9z0ZSkHjAnPZojyT6ANro/a/t6j84yeAd bKr3uZdHMKK5x5yi0DBqC5Bw37x5Rmum8H7Y3jG6UK0QndRxCOPh4o7whTtkhV+Xi1P7 3hrlrCXx/zIsIkB94aiEaL7e2zZg5t4lZGG5I9LbiooH0H+zphHdccP3UICYfR9YoZbc 0rnH6LhndqGEvzucwyynK+mtsrt1dR7Njdd+/ABF8WlXAhpoA6qgi8AAEo2S1pObf3X6 G1QPAggftFgzzWLDMLFh66Lipkr7Q7Y2PjIt4IRG7rRctjuqWOkXRbEo5bv+qPeR2UOG 2v3g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q3-v6si3787373pgf.40.2018.07.18.09.57.31; Wed, 18 Jul 2018 09:57:45 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731596AbeGRRfY (ORCPT + 99 others); Wed, 18 Jul 2018 13:35:24 -0400 Received: from mx2.suse.de ([195.135.220.15]:47800 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1731443AbeGRRfY (ORCPT ); Wed, 18 Jul 2018 13:35:24 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 6D2CEADEC; Wed, 18 Jul 2018 16:56:34 +0000 (UTC) From: Coly Li To: linux-kernel@vger.kernel.org Cc: linux-bcache@vger.kernel.org, linux-block@vger.kernel.org, Coly Li , Andy Shevchenko , Greg Kroah-Hartman , Michael Lyle , Kent Overstreet , Linus Torvalds , Thomas Gleixner , Kate Stewart , Eric Biggers , Andrew Morton , Randy Dunlap Subject: [PATCH v4 1/3] lib: add crc64 calculation routines Date: Thu, 19 Jul 2018 00:55:43 +0800 Message-Id: <20180718165545.1622-2-colyli@suse.de> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180718165545.1622-1-colyli@suse.de> References: <20180718165545.1622-1-colyli@suse.de> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch adds 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 talbe 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. Signed-off-by: Coly Li Co-developed-by: Andy Shevchenko Signed-off-by: Andy Shevchenko Reviewed-by: Hannes Reinecke Cc: Greg Kroah-Hartman Cc: Andy Shevchenko Cc: Michael Lyle Cc: Kent Overstreet Cc: Linus Torvalds Cc: Thomas Gleixner Cc: Kate Stewart Cc: Eric Biggers Cc: Andrew Morton Cc: Randy Dunlap --- Changelog: v4: Only keep crc64_be() in lib/crc64.c, move rested bcache specific stuffs back to bcache code. Other fixes from the review comments of v3 v3: More fixes for review comments of v2 By review comments from Eric Biggers, current functions naming with 'le' is misleading. Remove 'le' from the crc function names, and use u64 to replace __le64 in parameters and return values. v2: Fix reivew comments of v1 v1: Initial version. include/linux/crc64.h | 11 +++++++ lib/.gitignore | 2 ++ lib/Kconfig | 8 +++++ lib/Makefile | 11 +++++++ lib/crc64.c | 56 +++++++++++++++++++++++++++++++++++ lib/gen_crc64table.c | 68 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 156 insertions(+) create mode 100644 include/linux/crc64.h create mode 100644 lib/crc64.c create mode 100644 lib/gen_crc64table.c diff --git a/include/linux/crc64.h b/include/linux/crc64.h new file mode 100644 index 000000000000..1fc9f0710c10 --- /dev/null +++ b/include/linux/crc64.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * See lib/crc64.c for the related specification and polynomical arithmetic. + */ +#ifndef _LINUX_CRC64_H +#define _LINUX_CRC64_H + +#include + +u64 __pure crc64_be(u64 crc, const void *p, size_t len); +#endif /* _LINUX_CRC64_H */ diff --git a/lib/.gitignore b/lib/.gitignore index 09aae85418ab..f2a39c9e5485 100644 --- a/lib/.gitignore +++ b/lib/.gitignore @@ -2,5 +2,7 @@ # Generated files # gen_crc32table +gen_crc64table crc32table.h +crc64table.h oid_registry_data.c diff --git a/lib/Kconfig b/lib/Kconfig index 706836ec314d..9c10b9852563 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -170,6 +170,14 @@ config CRC32_BIT endchoice +config CRC64 + tristate "CRC64 functions" + help + This option is provided for the case where no in-kernel-tree + modules require CRC64 functions, but a module built outside + the kernel tree does. Such modules that use library CRC64 + functions require M here. + config CRC4 tristate "CRC4 functions" help diff --git a/lib/Makefile b/lib/Makefile index 90dc5520b784..40c215181687 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -102,6 +102,7 @@ obj-$(CONFIG_CRC16) += crc16.o obj-$(CONFIG_CRC_T10DIF)+= crc-t10dif.o obj-$(CONFIG_CRC_ITU_T) += crc-itu-t.o obj-$(CONFIG_CRC32) += crc32.o +obj-$(CONFIG_CRC64) += crc64.o obj-$(CONFIG_CRC32_SELFTEST) += crc32test.o obj-$(CONFIG_CRC4) += crc4.o obj-$(CONFIG_CRC7) += crc7.o @@ -215,7 +216,9 @@ obj-$(CONFIG_FONT_SUPPORT) += fonts/ obj-$(CONFIG_PRIME_NUMBERS) += prime_numbers.o hostprogs-y := gen_crc32table +hostprogs-y += gen_crc64table clean-files := crc32table.h +clean-files += crc64table.h $(obj)/crc32.o: $(obj)/crc32table.h @@ -225,6 +228,14 @@ quiet_cmd_crc32 = GEN $@ $(obj)/crc32table.h: $(obj)/gen_crc32table $(call cmd,crc32) +$(obj)/crc64.o: $(obj)/crc64table.h + +quiet_cmd_crc64 = GEN $@ + cmd_crc64 = $< > $@ + +$(obj)/crc64table.h: $(obj)/gen_crc64table + $(call cmd,crc64) + # # Build a fast OID lookip registry from include/linux/oid_registry.h # diff --git a/lib/crc64.c b/lib/crc64.c new file mode 100644 index 000000000000..d093298ba2c6 --- /dev/null +++ b/lib/crc64.c @@ -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-driver 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 + */ + +#include +#include +#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 for a new CRC computing, 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); diff --git a/lib/gen_crc64table.c b/lib/gen_crc64table.c new file mode 100644 index 000000000000..8296b0c3ea30 --- /dev/null +++ b/lib/gen_crc64table.c @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Generate lookup table for the talbe-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-driver CRC64 calculation. + * + * See lib/crc64.c for more information about which specification + * and polynomical arithmetic that gen_crc64table.c follows to + * generate the lookup table. + * + * Copyright 2018 SUSE Linux. + * Author: Coly Li + */ +#include +#include + +#include + +#define CRC64_ECMA182_POLY 0x42F0E1EBA9EA3693ULL + +static int64_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 \n"); + printf("#include \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; +} -- 2.17.1