Re: [PATCH v4] riscv: Optimize crct10dif with zbc extension

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 11 Feb 2025 at 15:11, Zhihang Shao <zhihang.shao.iscas@xxxxxxxxx> wrote:
>
> The current CRC-T10DIF algorithm on RISC-V platform is based on
> table-lookup optimization.
> Given the previous work on optimizing crc32 calculations with zbc
> extension, it is believed that this will be equally effective for
> accelerating crc-t10dif.
>
> Therefore this patch offers an implementation of crc-t10dif using zbc
> extension. This can detect whether the current runtime environment
> supports zbc feature and, if so, uses it to accelerate crc-t10dif
> calculations.
>
> This patch is updated due to the patchset of updating kernel's
> CRC-T10DIF library in 6.14, which is finished by Eric Biggers.
> Also, I used crc_kunit.c to test the performance of crc-t10dif
> optimized by crc extension.
>
> Signed-off-by: Zhihang Shao <zhihang.shao.iscas@xxxxxxxxx>

You should add Eric's Acked-by and Tested-by, apart from that, feel free to add,

Reviewed-by: Chunyan Zhang <zhangchunyan@xxxxxxxxxxx>

Thanks,
Chunyan


>
> ---
> v4:
> - Use proper data types and remove #defines according
> to Eric's comments. (Eric)
> ---
> v3:
> - Rebase for Eric's crc tree. (Eric)
> ---
> v2:
> - Use crypto self-tests instead. (Eric)
> - Fix some format errors in arch/riscv/crypto/Kconfig. (Chunyan)
> ---
>  arch/riscv/Kconfig                |   1 +
>  arch/riscv/lib/Makefile           |   1 +
>  arch/riscv/lib/crc-t10dif-riscv.c | 120 ++++++++++++++++++++++++++++++
>  3 files changed, 122 insertions(+)
>  create mode 100644 arch/riscv/lib/crc-t10dif-riscv.c
>
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index 7612c52e9b1e..db1cf9666dfd 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -25,6 +25,7 @@ config RISCV
>         select ARCH_ENABLE_THP_MIGRATION if TRANSPARENT_HUGEPAGE
>         select ARCH_HAS_BINFMT_FLAT
>         select ARCH_HAS_CRC32 if RISCV_ISA_ZBC
> +       select ARCH_HAS_CRC_T10DIF if RISCV_ISA_ZBC
>         select ARCH_HAS_CURRENT_STACK_POINTER
>         select ARCH_HAS_DEBUG_VIRTUAL if MMU
>         select ARCH_HAS_DEBUG_VM_PGTABLE
> diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
> index 79368a895fee..689895b271bd 100644
> --- a/arch/riscv/lib/Makefile
> +++ b/arch/riscv/lib/Makefile
> @@ -16,6 +16,7 @@ lib-$(CONFIG_MMU)     += uaccess.o
>  lib-$(CONFIG_64BIT)    += tishift.o
>  lib-$(CONFIG_RISCV_ISA_ZICBOZ) += clear_page.o
>  obj-$(CONFIG_CRC32_ARCH)       += crc32-riscv.o
> +obj-$(CONFIG_CRC_T10DIF_ARCH) += crc-t10dif-riscv.o
>  obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
>  lib-$(CONFIG_RISCV_ISA_V)      += xor.o
>  lib-$(CONFIG_RISCV_ISA_V)      += riscv_v_helpers.o
> diff --git a/arch/riscv/lib/crc-t10dif-riscv.c b/arch/riscv/lib/crc-t10dif-riscv.c
> new file mode 100644
> index 000000000000..da90e2900ca7
> --- /dev/null
> +++ b/arch/riscv/lib/crc-t10dif-riscv.c
> @@ -0,0 +1,120 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Accelerated CRC-T10DIF implementation with RISC-V Zbc extension.
> + *
> + * Copyright (C) 2024 Institute of Software, CAS.
> + */
> +
> +#include <asm/alternative-macros.h>
> +#include <asm/byteorder.h>
> +#include <asm/hwcap.h>
> +
> +#include <linux/byteorder/generic.h>
> +#include <linux/crc-t10dif.h>
> +#include <linux/minmax.h>
> +#include <linux/module.h>
> +#include <linux/types.h>
> +
> +#define CRCT10DIF_POLY 0x8bb7
> +
> +#if __riscv_xlen == 64
> +#define CRCT10DIF_POLY_QT_BE 0xf65a57f81d33a48a
> +
> +static inline u64 crct10dif_prep(u16 crc, const __be64 *ptr)
> +{
> +       return ((u64)crc << 48) ^ __be64_to_cpu(*ptr);
> +}
> +
> +#elif __riscv_xlen == 32
> +#define CRCT10DIF_POLY_QT_BE 0xf65a57f8
> +
> +static inline u32 crct10dif_prep(u16 crc, const __be32 *ptr)
> +{
> +       return ((u32)crc << 16) ^ __be32_to_cpu(*ptr);
> +}
> +
> +#else
> +#error "Unexpected __riscv_xlen"
> +#endif
> +
> +static inline u16 crct10dif_zbc(unsigned long s)
> +{
> +       u16 crc;
> +
> +       asm volatile   (".option push\n"
> +                       ".option arch,+zbc\n"
> +                       "clmulh %0, %1, %2\n"
> +                       "xor    %0, %0, %1\n"
> +                       "clmul  %0, %0, %3\n"
> +                       ".option pop\n"
> +                       : "=&r" (crc)
> +                       : "r"(s),
> +                         "r"(CRCT10DIF_POLY_QT_BE),
> +                         "r"(CRCT10DIF_POLY)
> +                       :);
> +
> +       return crc;
> +}
> +
> +static inline u16 crct10dif_unaligned(u16 crc, const u8 *p, size_t len)
> +{
> +       size_t bits = len * 8;
> +       unsigned long s = 0;
> +       u16 crc_low = 0;
> +
> +       for (int i = 0; i < len; i++)
> +               s = *p++ | (s << 8);
> +
> +       if (len < sizeof(u16)) {
> +               s ^= crc >> (16 - bits);
> +               crc_low = crc << bits;
> +       } else {
> +               s ^= (unsigned long)crc << (bits - 16);
> +       }
> +
> +       crc = crct10dif_zbc(s);
> +       crc ^= crc_low;
> +
> +       return crc;
> +}
> +
> +u16 crc_t10dif_arch(u16 crc, const u8 *p, size_t len)
> +{
> +       size_t offset, head_len, tail_len;
> +       const __be64 *p_ul;
> +       unsigned long s;
> +
> +       asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0,
> +                            RISCV_ISA_EXT_ZBC, 1)
> +                : : : : legacy);
> +
> +       offset = (unsigned long)p & (sizeof(unsigned long) - 1);
> +       if (offset && len) {
> +               head_len = min(sizeof(unsigned long) - offset, len);
> +               crc = crct10dif_unaligned(crc, p, head_len);
> +               p += head_len;
> +               len -= head_len;
> +       }
> +
> +       tail_len = len & (sizeof(unsigned long) - 1);
> +       len = len >> ilog2(sizeof(unsigned long));
> +       p_ul = (const __be64 *)p;
> +
> +       for (int i = 0; i < len; i++) {
> +               s = crct10dif_prep(crc, p_ul);
> +               crc = crct10dif_zbc(s);
> +               p_ul++;
> +       }
> +
> +       p = (const u8 *)p_ul;
> +       if (tail_len)
> +               crc = crct10dif_unaligned(crc, p, tail_len);
> +
> +       return crc;
> +legacy:
> +       return crc_t10dif_generic(crc, p, len);
> +}
> +EXPORT_SYMBOL(crc_t10dif_arch);
> +
> +MODULE_DESCRIPTION("CRC-T10DIF using RISC-V ZBC Extension");
> +MODULE_LICENSE("GPL");
> --
> 2.47.0
>
>





[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]
  Powered by Linux