1eda14cbcSMatt Macy /* 2eda14cbcSMatt Macy * CDDL HEADER START 3eda14cbcSMatt Macy * 4eda14cbcSMatt Macy * The contents of this file are subject to the terms of the 5eda14cbcSMatt Macy * Common Development and Distribution License (the "License"). 6eda14cbcSMatt Macy * You may not use this file except in compliance with the License. 7eda14cbcSMatt Macy * 8eda14cbcSMatt Macy * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*271171e0SMartin Matuska * or https://opensource.org/licenses/CDDL-1.0. 10eda14cbcSMatt Macy * See the License for the specific language governing permissions 11eda14cbcSMatt Macy * and limitations under the License. 12eda14cbcSMatt Macy * 13eda14cbcSMatt Macy * When distributing Covered Code, include this CDDL HEADER in each 14eda14cbcSMatt Macy * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15eda14cbcSMatt Macy * If applicable, add the following below this CDDL HEADER, with the 16eda14cbcSMatt Macy * fields enclosed by brackets "[]" replaced with your own identifying 17eda14cbcSMatt Macy * information: Portions Copyright [yyyy] [name of copyright owner] 18eda14cbcSMatt Macy * 19eda14cbcSMatt Macy * CDDL HEADER END 20eda14cbcSMatt Macy */ 21eda14cbcSMatt Macy /* 22eda14cbcSMatt Macy * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23eda14cbcSMatt Macy * Use is subject to license terms. 24eda14cbcSMatt Macy */ 25eda14cbcSMatt Macy /* 26eda14cbcSMatt Macy * Copyright 2013 Saso Kiselkov. All rights reserved. 27eda14cbcSMatt Macy */ 28eda14cbcSMatt Macy 29eda14cbcSMatt Macy #ifndef _ZFS_FLETCHER_H 3016038816SMartin Matuska #define _ZFS_FLETCHER_H extern __attribute__((visibility("default"))) 31eda14cbcSMatt Macy 32eda14cbcSMatt Macy #include <sys/types.h> 33eda14cbcSMatt Macy #include <sys/spa_checksum.h> 34eda14cbcSMatt Macy 35eda14cbcSMatt Macy #ifdef __cplusplus 36eda14cbcSMatt Macy extern "C" { 37eda14cbcSMatt Macy #endif 38eda14cbcSMatt Macy 39eda14cbcSMatt Macy /* 40eda14cbcSMatt Macy * fletcher checksum functions 41eda14cbcSMatt Macy * 42eda14cbcSMatt Macy * Note: Fletcher checksum methods expect buffer size to be 4B aligned. This 43eda14cbcSMatt Macy * limitation stems from the algorithm design. Performing incremental checksum 44eda14cbcSMatt Macy * without said alignment would yield different results. Therefore, the code 45eda14cbcSMatt Macy * includes assertions for the size alignment. 46eda14cbcSMatt Macy * For compatibility, it is required that some code paths calculate checksum of 47eda14cbcSMatt Macy * non-aligned buffer sizes. For this purpose, `fletcher_4_native_varsize()` 48eda14cbcSMatt Macy * checksum method is added. This method will ignore last (size % 4) bytes of 49eda14cbcSMatt Macy * the data buffer. 50eda14cbcSMatt Macy */ 5116038816SMartin Matuska _ZFS_FLETCHER_H void fletcher_init(zio_cksum_t *); 5216038816SMartin Matuska _ZFS_FLETCHER_H void fletcher_2_native(const void *, uint64_t, const void *, 5316038816SMartin Matuska zio_cksum_t *); 5416038816SMartin Matuska _ZFS_FLETCHER_H void fletcher_2_byteswap(const void *, uint64_t, const void *, 5516038816SMartin Matuska zio_cksum_t *); 5616038816SMartin Matuska _ZFS_FLETCHER_H void fletcher_4_native(const void *, uint64_t, const void *, 5716038816SMartin Matuska zio_cksum_t *); 5816038816SMartin Matuska _ZFS_FLETCHER_H int fletcher_2_incremental_native(void *, size_t, void *); 5916038816SMartin Matuska _ZFS_FLETCHER_H int fletcher_2_incremental_byteswap(void *, size_t, void *); 6016038816SMartin Matuska _ZFS_FLETCHER_H void fletcher_4_native_varsize(const void *, uint64_t, 6116038816SMartin Matuska zio_cksum_t *); 6216038816SMartin Matuska _ZFS_FLETCHER_H void fletcher_4_byteswap(const void *, uint64_t, const void *, 6316038816SMartin Matuska zio_cksum_t *); 6416038816SMartin Matuska _ZFS_FLETCHER_H int fletcher_4_incremental_native(void *, size_t, void *); 6516038816SMartin Matuska _ZFS_FLETCHER_H int fletcher_4_incremental_byteswap(void *, size_t, void *); 6616038816SMartin Matuska _ZFS_FLETCHER_H int fletcher_4_impl_set(const char *selector); 6716038816SMartin Matuska _ZFS_FLETCHER_H void fletcher_4_init(void); 6816038816SMartin Matuska _ZFS_FLETCHER_H void fletcher_4_fini(void); 69eda14cbcSMatt Macy 70eda14cbcSMatt Macy 71eda14cbcSMatt Macy 72eda14cbcSMatt Macy /* Internal fletcher ctx */ 73eda14cbcSMatt Macy 74eda14cbcSMatt Macy typedef struct zfs_fletcher_superscalar { 75eda14cbcSMatt Macy uint64_t v[4]; 76eda14cbcSMatt Macy } zfs_fletcher_superscalar_t; 77eda14cbcSMatt Macy 78eda14cbcSMatt Macy typedef struct zfs_fletcher_sse { 79eda14cbcSMatt Macy uint64_t v[2] __attribute__((aligned(16))); 80eda14cbcSMatt Macy } zfs_fletcher_sse_t; 81eda14cbcSMatt Macy 82eda14cbcSMatt Macy typedef struct zfs_fletcher_avx { 83eda14cbcSMatt Macy uint64_t v[4] __attribute__((aligned(32))); 84eda14cbcSMatt Macy } zfs_fletcher_avx_t; 85eda14cbcSMatt Macy 86eda14cbcSMatt Macy typedef struct zfs_fletcher_avx512 { 87eda14cbcSMatt Macy uint64_t v[8] __attribute__((aligned(64))); 88eda14cbcSMatt Macy } zfs_fletcher_avx512_t; 89eda14cbcSMatt Macy 90eda14cbcSMatt Macy typedef struct zfs_fletcher_aarch64_neon { 91eda14cbcSMatt Macy uint64_t v[2] __attribute__((aligned(16))); 92eda14cbcSMatt Macy } zfs_fletcher_aarch64_neon_t; 93eda14cbcSMatt Macy 94eda14cbcSMatt Macy 95eda14cbcSMatt Macy typedef union fletcher_4_ctx { 96eda14cbcSMatt Macy zio_cksum_t scalar; 97eda14cbcSMatt Macy zfs_fletcher_superscalar_t superscalar[4]; 98eda14cbcSMatt Macy 99eda14cbcSMatt Macy #if defined(HAVE_SSE2) || (defined(HAVE_SSE2) && defined(HAVE_SSSE3)) 100eda14cbcSMatt Macy zfs_fletcher_sse_t sse[4]; 101eda14cbcSMatt Macy #endif 102eda14cbcSMatt Macy #if defined(HAVE_AVX) && defined(HAVE_AVX2) 103eda14cbcSMatt Macy zfs_fletcher_avx_t avx[4]; 104eda14cbcSMatt Macy #endif 105eda14cbcSMatt Macy #if defined(__x86_64) && defined(HAVE_AVX512F) 106eda14cbcSMatt Macy zfs_fletcher_avx512_t avx512[4]; 107eda14cbcSMatt Macy #endif 108eda14cbcSMatt Macy #if defined(__aarch64__) 109eda14cbcSMatt Macy zfs_fletcher_aarch64_neon_t aarch64_neon[4]; 110eda14cbcSMatt Macy #endif 111eda14cbcSMatt Macy } fletcher_4_ctx_t; 112eda14cbcSMatt Macy 113eda14cbcSMatt Macy /* 114eda14cbcSMatt Macy * fletcher checksum struct 115eda14cbcSMatt Macy */ 116eda14cbcSMatt Macy typedef void (*fletcher_4_init_f)(fletcher_4_ctx_t *); 117eda14cbcSMatt Macy typedef void (*fletcher_4_fini_f)(fletcher_4_ctx_t *, zio_cksum_t *); 118eda14cbcSMatt Macy typedef void (*fletcher_4_compute_f)(fletcher_4_ctx_t *, 119eda14cbcSMatt Macy const void *, uint64_t); 120eda14cbcSMatt Macy 121eda14cbcSMatt Macy typedef struct fletcher_4_func { 122eda14cbcSMatt Macy fletcher_4_init_f init_native; 123eda14cbcSMatt Macy fletcher_4_fini_f fini_native; 124eda14cbcSMatt Macy fletcher_4_compute_f compute_native; 125eda14cbcSMatt Macy fletcher_4_init_f init_byteswap; 126eda14cbcSMatt Macy fletcher_4_fini_f fini_byteswap; 127eda14cbcSMatt Macy fletcher_4_compute_f compute_byteswap; 128eda14cbcSMatt Macy boolean_t (*valid)(void); 129eda14cbcSMatt Macy const char *name; 130eda14cbcSMatt Macy } fletcher_4_ops_t; 131eda14cbcSMatt Macy 13216038816SMartin Matuska _ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_superscalar_ops; 13316038816SMartin Matuska _ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_superscalar4_ops; 134eda14cbcSMatt Macy 135eda14cbcSMatt Macy #if defined(HAVE_SSE2) 13616038816SMartin Matuska _ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_sse2_ops; 137eda14cbcSMatt Macy #endif 138eda14cbcSMatt Macy 139eda14cbcSMatt Macy #if defined(HAVE_SSE2) && defined(HAVE_SSSE3) 14016038816SMartin Matuska _ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_ssse3_ops; 141eda14cbcSMatt Macy #endif 142eda14cbcSMatt Macy 143eda14cbcSMatt Macy #if defined(HAVE_AVX) && defined(HAVE_AVX2) 14416038816SMartin Matuska _ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_avx2_ops; 145eda14cbcSMatt Macy #endif 146eda14cbcSMatt Macy 147eda14cbcSMatt Macy #if defined(__x86_64) && defined(HAVE_AVX512F) 14816038816SMartin Matuska _ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_avx512f_ops; 149eda14cbcSMatt Macy #endif 150eda14cbcSMatt Macy 151eda14cbcSMatt Macy #if defined(__x86_64) && defined(HAVE_AVX512BW) 15216038816SMartin Matuska _ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_avx512bw_ops; 153eda14cbcSMatt Macy #endif 154eda14cbcSMatt Macy 155eda14cbcSMatt Macy #if defined(__aarch64__) 15616038816SMartin Matuska _ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_aarch64_neon_ops; 157eda14cbcSMatt Macy #endif 158eda14cbcSMatt Macy 159eda14cbcSMatt Macy #ifdef __cplusplus 160eda14cbcSMatt Macy } 161eda14cbcSMatt Macy #endif 162eda14cbcSMatt Macy 163c03c5b1cSMartin Matuska #if defined(ZFS_UBSAN_ENABLED) 164c03c5b1cSMartin Matuska #if defined(__has_attribute) 165c03c5b1cSMartin Matuska #if __has_attribute(no_sanitize_undefined) 166c03c5b1cSMartin Matuska #define ZFS_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize_undefined)) 167c03c5b1cSMartin Matuska #elif __has_attribute(no_sanitize) 168c03c5b1cSMartin Matuska #define ZFS_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined"))) 169c03c5b1cSMartin Matuska #else 170c03c5b1cSMartin Matuska #error "Compiler has to support attribute " 171c03c5b1cSMartin Matuska "`no_sanitize_undefined` or `no_sanitize(\"undefined\")`" 172c03c5b1cSMartin Matuska "when compiling with UBSan enabled" 173c03c5b1cSMartin Matuska #endif /* __has_attribute(no_sanitize_undefined) */ 174c03c5b1cSMartin Matuska #endif /* defined(__has_attribute) */ 175c03c5b1cSMartin Matuska #else 176c03c5b1cSMartin Matuska #define ZFS_NO_SANITIZE_UNDEFINED 177c03c5b1cSMartin Matuska #endif /* defined(ZFS_UBSAN_ENABLED) */ 178c03c5b1cSMartin Matuska 179eda14cbcSMatt Macy #endif /* _ZFS_FLETCHER_H */ 180