summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorAttila Fülöp <[email protected]>2020-02-10 21:59:50 +0100
committerTony Hutter <[email protected]>2020-05-12 10:53:32 -0700
commit76354f945e839a3d7b7332e32a9acc569548f8b8 (patch)
tree5ba0edcd42799bcbdaaf265385bb0dee0ddeb145 /include
parent590ababea2ed4c41ea3c769f35a5d3ae2eb13e8d (diff)
ICP: Improve AES-GCM performance
Currently SIMD accelerated AES-GCM performance is limited by two factors: a. The need to disable preemption and interrupts and save the FPU state before using it and to do the reverse when done. Due to the way the code is organized (see (b) below) we have to pay this price twice for each 16 byte GCM block processed. b. Most processing is done in C, operating on single GCM blocks. The use of SIMD instructions is limited to the AES encryption of the counter block (AES-NI) and the Galois multiplication (PCLMULQDQ). This leads to the FPU not being fully utilized for crypto operations. To solve (a) we do crypto processing in larger chunks while owning the FPU. An `icp_gcm_avx_chunk_size` module parameter was introduced to make this chunk size tweakable. It defaults to 32 KiB. This step alone roughly doubles performance. (b) is tackled by porting and using the highly optimized openssl AES-GCM assembler routines, which do all the processing (CTR, AES, GMULT) in a single routine. Both steps together result in up to 32x reduction of the time spend in the en/decryption routines, leading up to approximately 12x throughput increase for large (128 KiB) blocks. Lastly, this commit changes the default encryption algorithm from AES-CCM to AES-GCM when setting the `encryption=on` property. Reviewed-By: Brian Behlendorf <[email protected]> Reviewed-By: Jason King <[email protected]> Reviewed-By: Tom Caputi <[email protected]> Reviewed-By: Richard Laager <[email protected]> Signed-off-by: Attila Fülöp <[email protected]> Closes #9749
Diffstat (limited to 'include')
-rw-r--r--include/linux/simd_x86.h23
-rw-r--r--include/sys/zio.h2
2 files changed, 23 insertions, 2 deletions
diff --git a/include/linux/simd_x86.h b/include/linux/simd_x86.h
index 1bde1d7c9..bf44f6bf1 100644
--- a/include/linux/simd_x86.h
+++ b/include/linux/simd_x86.h
@@ -382,7 +382,8 @@ typedef enum cpuid_inst_sets {
AVX512ER,
AVX512VL,
AES,
- PCLMULQDQ
+ PCLMULQDQ,
+ MOVBE
} cpuid_inst_sets_t;
/*
@@ -406,6 +407,7 @@ typedef struct cpuid_feature_desc {
#define _AVX512VL_BIT (1U << 31) /* if used also check other levels */
#define _AES_BIT (1U << 25)
#define _PCLMULQDQ_BIT (1U << 1)
+#define _MOVBE_BIT (1U << 22)
/*
* Descriptions of supported instruction sets
@@ -433,6 +435,7 @@ static const cpuid_feature_desc_t cpuid_features[] = {
[AVX512VL] = {7U, 0U, _AVX512ER_BIT, EBX },
[AES] = {1U, 0U, _AES_BIT, ECX },
[PCLMULQDQ] = {1U, 0U, _PCLMULQDQ_BIT, ECX },
+ [MOVBE] = {1U, 0U, _MOVBE_BIT, ECX },
};
/*
@@ -505,6 +508,7 @@ CPUID_FEATURE_CHECK(avx512er, AVX512ER);
CPUID_FEATURE_CHECK(avx512vl, AVX512VL);
CPUID_FEATURE_CHECK(aes, AES);
CPUID_FEATURE_CHECK(pclmulqdq, PCLMULQDQ);
+CPUID_FEATURE_CHECK(movbe, MOVBE);
#endif /* !defined(_KERNEL) */
@@ -720,6 +724,23 @@ zfs_pclmulqdq_available(void)
}
/*
+ * Check if MOVBE instruction is available
+ */
+static inline boolean_t
+zfs_movbe_available(void)
+{
+#if defined(_KERNEL)
+#if defined(X86_FEATURE_MOVBE)
+ return (!!boot_cpu_has(X86_FEATURE_MOVBE));
+#else
+ return (B_FALSE);
+#endif
+#elif !defined(_KERNEL)
+ return (__cpuid_has_movbe());
+#endif
+}
+
+/*
* AVX-512 family of instruction sets:
*
* AVX512F Foundation
diff --git a/include/sys/zio.h b/include/sys/zio.h
index aa58fe1fa..0046230a7 100644
--- a/include/sys/zio.h
+++ b/include/sys/zio.h
@@ -118,7 +118,7 @@ enum zio_encrypt {
ZIO_CRYPT_FUNCTIONS
};
-#define ZIO_CRYPT_ON_VALUE ZIO_CRYPT_AES_256_CCM
+#define ZIO_CRYPT_ON_VALUE ZIO_CRYPT_AES_256_GCM
#define ZIO_CRYPT_DEFAULT ZIO_CRYPT_OFF
/* macros defining encryption lengths */