mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Exclude cipher allocation time from benchmark
For each 1 MiB of data en/decrypted, 'cryptsetup benchmark' is setting up a new AF_ALG socket, which involves 4 system calls and is included in the data en/decryption time. With high-speed ciphers (e.g. VAES optimized AES-XTS) this can measure well over 10000 AF_ALG socket setups per second. This is not representative of dm-crypt, which only allocates a cipher when the dm-crypt device is created. Therefore, allocate the AF_ALG socket once, before doing the benchmark. On AMD Ryzen 9 9950X this increases the 'cryptsetup benchmark' result of AES-256-XTS slightly, from 14000 MiB/s to 14600 MiB/s. Note that an in-kernel benchmark of the crypto API with the same block size (65536 bytes) gives 34100 MiB/s, so AF_ALG still takes more time than the en/decryption itself -- this cannot easily be addressed though. Signed-off-by: Eric Biggers <ebiggers@google.com>
This commit is contained in:
@@ -42,43 +42,36 @@ static int time_ms(struct timespec *start, struct timespec *end, double *ms)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cipher_perf_one(const char *name, const char *mode, char *buffer, size_t buffer_size,
|
||||
const char *key, size_t key_size, const char *iv, size_t iv_size, int enc)
|
||||
static int cipher_perf_one(struct crypt_cipher_kernel *cipher, char *buffer, size_t buffer_size,
|
||||
const char *iv, size_t iv_size, int enc)
|
||||
{
|
||||
struct crypt_cipher_kernel cipher;
|
||||
size_t done = 0, block = CIPHER_BLOCK_BYTES;
|
||||
int r;
|
||||
|
||||
if (buffer_size < block)
|
||||
block = buffer_size;
|
||||
|
||||
r = crypt_cipher_init_kernel(&cipher, name, mode, key, key_size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
while (done < buffer_size) {
|
||||
if ((done + block) > buffer_size)
|
||||
block = buffer_size - done;
|
||||
|
||||
if (enc)
|
||||
r = crypt_cipher_encrypt_kernel(&cipher, &buffer[done], &buffer[done],
|
||||
r = crypt_cipher_encrypt_kernel(cipher, &buffer[done], &buffer[done],
|
||||
block, iv, iv_size);
|
||||
else
|
||||
r = crypt_cipher_decrypt_kernel(&cipher, &buffer[done], &buffer[done],
|
||||
r = crypt_cipher_decrypt_kernel(cipher, &buffer[done], &buffer[done],
|
||||
block, iv, iv_size);
|
||||
if (r < 0)
|
||||
break;
|
||||
return r;
|
||||
|
||||
done += block;
|
||||
}
|
||||
|
||||
crypt_cipher_destroy_kernel(&cipher);
|
||||
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
static int cipher_measure(const char *name, const char *mode, char *buffer, size_t buffer_size,
|
||||
const char *key, size_t key_size, const char *iv, size_t iv_size,
|
||||
int encrypt, double *ms)
|
||||
|
||||
static int cipher_measure(struct crypt_cipher_kernel *cipher, char *buffer, size_t buffer_size,
|
||||
const char *iv, size_t iv_size, int encrypt, double *ms)
|
||||
{
|
||||
struct timespec start, end;
|
||||
int r;
|
||||
@@ -90,7 +83,7 @@ static int cipher_measure(const char *name, const char *mode, char *buffer, size
|
||||
if (clock_gettime(CLOCK_MONOTONIC_RAW, &start) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
r = cipher_perf_one(name, mode, buffer, buffer_size, key, key_size, iv, iv_size, encrypt);
|
||||
r = cipher_perf_one(cipher, buffer, buffer_size, iv, iv_size, encrypt);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -118,15 +111,20 @@ int crypt_cipher_perf_kernel(const char *name, const char *mode, char *buffer, s
|
||||
const char *key, size_t key_size, const char *iv, size_t iv_size,
|
||||
double *encryption_mbs, double *decryption_mbs)
|
||||
{
|
||||
struct crypt_cipher_kernel cipher;
|
||||
double ms_enc, ms_dec, ms;
|
||||
int r, repeat_enc, repeat_dec;
|
||||
|
||||
r = crypt_cipher_init_kernel(&cipher, name, mode, key, key_size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
ms_enc = 0.0;
|
||||
repeat_enc = 1;
|
||||
while (ms_enc < 1000.0) {
|
||||
r = cipher_measure(name, mode, buffer, buffer_size, key, key_size, iv, iv_size, 1, &ms);
|
||||
r = cipher_measure(&cipher, buffer, buffer_size, iv, iv_size, 1, &ms);
|
||||
if (r < 0)
|
||||
return r;
|
||||
goto out;
|
||||
ms_enc += ms;
|
||||
repeat_enc++;
|
||||
}
|
||||
@@ -134,9 +132,9 @@ int crypt_cipher_perf_kernel(const char *name, const char *mode, char *buffer, s
|
||||
ms_dec = 0.0;
|
||||
repeat_dec = 1;
|
||||
while (ms_dec < 1000.0) {
|
||||
r = cipher_measure(name, mode, buffer, buffer_size, key, key_size, iv, iv_size, 0, &ms);
|
||||
r = cipher_measure(&cipher, buffer, buffer_size, iv, iv_size, 0, &ms);
|
||||
if (r < 0)
|
||||
return r;
|
||||
goto out;
|
||||
ms_dec += ms;
|
||||
repeat_dec++;
|
||||
}
|
||||
@@ -144,5 +142,8 @@ int crypt_cipher_perf_kernel(const char *name, const char *mode, char *buffer, s
|
||||
*encryption_mbs = speed_mbs(buffer_size * repeat_enc, ms_enc);
|
||||
*decryption_mbs = speed_mbs(buffer_size * repeat_dec, ms_dec);
|
||||
|
||||
return 0;
|
||||
r = 0;
|
||||
out:
|
||||
crypt_cipher_destroy_kernel(&cipher);
|
||||
return r;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user