1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 /* 26 * Copyright 2013 Saso Kiselkov. All rights reserved. 27 * Copyright (c) 2016 by Delphix. All rights reserved. 28 */ 29 30 #ifndef _ZFS_FLETCHER_H 31 #define _ZFS_FLETCHER_H 32 33 #include <sys/types.h> 34 #include <sys/spa_checksum.h> 35 36 #ifdef __cplusplus 37 extern "C" { 38 #endif 39 40 /* 41 * fletcher checksum functions 42 * 43 * Note: Fletcher checksum methods expect buffer size to be 4B aligned. This 44 * limitation stems from the algorithm design. Performing incremental checksum 45 * without said alignment would yield different results. Therefore, the code 46 * includes assertions for the size alignment. 47 * For compatibility, it is required that some code paths calculate checksum of 48 * non-aligned buffer sizes. For this purpose, `fletcher_4_native_varsize()` 49 * checksum method is added. This method will ignore last (size % 4) bytes of 50 * the data buffer. 51 */ 52 53 void fletcher_init(zio_cksum_t *); 54 void fletcher_2_native(const void *, size_t, const void *, zio_cksum_t *); 55 void fletcher_2_byteswap(const void *, size_t, const void *, zio_cksum_t *); 56 int fletcher_2_incremental_native(void *, size_t, void *); 57 int fletcher_2_incremental_byteswap(void *, size_t, void *); 58 void fletcher_4_native(const void *, size_t, const void *, zio_cksum_t *); 59 void fletcher_4_native_varsize(const void *, size_t, zio_cksum_t *); 60 void fletcher_4_byteswap(const void *, size_t, const void *, zio_cksum_t *); 61 int fletcher_4_incremental_native(void *, size_t, void *); 62 int fletcher_4_incremental_byteswap(void *, size_t, void *); 63 int fletcher_4_impl_set(const char *selector); 64 void fletcher_4_init(void); 65 void fletcher_4_fini(void); 66 67 /* Internal fletcher ctx */ 68 69 typedef struct zfs_fletcher_superscalar { 70 uint64_t v[4]; 71 } zfs_fletcher_superscalar_t; 72 73 typedef struct zfs_fletcher_sse { 74 uint64_t v[2]; 75 } zfs_fletcher_sse_t; 76 77 typedef struct zfs_fletcher_avx { 78 uint64_t v[4]; 79 } zfs_fletcher_avx_t; 80 81 typedef struct zfs_fletcher_avx512 { 82 uint64_t v[8]; 83 } zfs_fletcher_avx512_t; 84 85 typedef union fletcher_4_ctx { 86 zio_cksum_t scalar; 87 zfs_fletcher_superscalar_t superscalar[4]; 88 #ifdef __amd64 89 zfs_fletcher_sse_t sse[4]; 90 zfs_fletcher_avx_t avx[4]; 91 zfs_fletcher_avx512_t avx512[4]; 92 #endif 93 } fletcher_4_ctx_t; 94 95 /* 96 * fletcher checksum struct 97 */ 98 typedef void (*fletcher_4_init_f)(fletcher_4_ctx_t *); 99 typedef void (*fletcher_4_fini_f)(fletcher_4_ctx_t *, zio_cksum_t *); 100 typedef void (*fletcher_4_compute_f)(fletcher_4_ctx_t *, 101 const void *, size_t); 102 103 typedef struct fletcher_4_func { 104 fletcher_4_init_f init_native; 105 fletcher_4_fini_f fini_native; 106 fletcher_4_compute_f compute_native; 107 fletcher_4_init_f init_byteswap; 108 fletcher_4_fini_f fini_byteswap; 109 fletcher_4_compute_f compute_byteswap; 110 boolean_t (*valid)(void); 111 boolean_t uses_fpu_native; 112 boolean_t uses_fpu_byteswap; 113 const char *name; 114 } __attribute__((aligned(64))) fletcher_4_ops_t; 115 116 extern const fletcher_4_ops_t fletcher_4_superscalar_ops; 117 extern const fletcher_4_ops_t fletcher_4_superscalar4_ops; 118 #ifdef __amd64 119 extern const fletcher_4_ops_t fletcher_4_avx2_ops; 120 extern const fletcher_4_ops_t fletcher_4_sse2_ops; 121 extern const fletcher_4_ops_t fletcher_4_ssse3_ops; 122 extern const fletcher_4_ops_t fletcher_4_avx512f_ops; 123 extern const fletcher_4_ops_t fletcher_4_avx512bw_ops; 124 #endif 125 126 #ifdef __cplusplus 127 } 128 #endif 129 130 #endif /* _ZFS_FLETCHER_H */ 131