From patchwork Sun Dec 17 08:29:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gilad Ben-Yossef X-Patchwork-Id: 122178 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp1514920qgn; Sun, 17 Dec 2017 00:30:39 -0800 (PST) X-Google-Smtp-Source: ACJfBou12JYo1Qi8GulWAYpBBOE3N9TjJbqOxIBFnq5Z/mqhvKjxqMBwWALHyVvoodElvdAvAF+W X-Received: by 10.101.91.193 with SMTP id o1mr16513618pgr.373.1513499439355; Sun, 17 Dec 2017 00:30:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1513499439; cv=none; d=google.com; s=arc-20160816; b=MpB2mDKzvGtGHeOg1eHh7fGCMMHnJEh1hSckIoUwcsqoanK/BTdZj3qMZgEhz/m8MI keH4VCjViVd7do2raEo34vxcDMSCeTgN3yHeF/z3Uygc3nVj1tiP9Id/QR9kwpoZe090 hQ8jBcqaA7+Kq6I205W2NqK/HiLrSGNjXNGhWO+v9lv2E73zh7MAqyz8Kh0fxPza7+P8 yuvaD+nDu6HyxS/OoXiDlBsAPPBHxPZP3H6ikeVgQZyu+Xinvv6R9pubk1jnPphwDtQT E2rWvGvrP228t8AcdhyWUhem2TfQWrn/cFfydgTlm/QZy5syJ0bLy2bZpHuAhHjviwLm 1KBw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=nOxM+wMwWlGE8OPSlCtzhQHC4CTDI/y1CLU62xf6mGk=; b=06hDSg8jTU8570p6/M+VGClabsKVfyXPc3IIx+PZKeRAdItnEYbmqReh+bzRLyzho7 BPlKmS1BHiHbUkq9Gms8p0ZLu7zqmbETPB0+1mua0rdGsPKxc0SsR+0VpAiEUuo46ETd f6hCOAKAKhyseIuMUC+2bK06/pGAvzE/dmoPwNLDtHITjLD8VNULt9kvKEhTKJSJtPBQ a/MLqoDz5kkiCv5ImAgT1jBpJxeZAHwx/wVeLFBsi1hQtXp3F4sX1az2gSWfeI0TrqYJ 2Pd1SfBDZciwe/AamwbB8VGvlkaA3GorEHVBUELbnBlG1jnKpbyTmD+yUROvwSNKDb0N zA3g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h14si7908121pln.774.2017.12.17.00.30.39; Sun, 17 Dec 2017 00:30:39 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757239AbdLQIag (ORCPT + 25 others); Sun, 17 Dec 2017 03:30:36 -0500 Received: from foss.arm.com ([217.140.101.70]:40946 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753763AbdLQIab (ORCPT ); Sun, 17 Dec 2017 03:30:31 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 075DD1435; Sun, 17 Dec 2017 00:30:31 -0800 (PST) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [217.140.101.70]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 8E0C63F24A; Sun, 17 Dec 2017 00:30:26 -0800 (PST) From: Gilad Ben-Yossef To: Herbert Xu , "David S. Miller" Cc: Ofir Drang , linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 6/6] crypto: tcrypt: add multibuf aead speed test Date: Sun, 17 Dec 2017 08:29:05 +0000 Message-Id: <1513499346-9047-7-git-send-email-gilad@benyossef.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1513499346-9047-1-git-send-email-gilad@benyossef.com> References: <1513499346-9047-1-git-send-email-gilad@benyossef.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The performance of some aead tfm providers is affected by the amount of parallelism possible with the processing. Introduce an async aead concurrent multiple buffer processing speed test to be able to test performance of such tfm providers. Signed-off-by: Gilad Ben-Yossef --- crypto/tcrypt.c | 437 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 378 insertions(+), 59 deletions(-) -- 2.7.4 diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index d617c19..58e3344 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -80,6 +80,66 @@ static char *check[] = { NULL }; +static u32 block_sizes[] = { 16, 64, 256, 1024, 8192, 0 }; +static u32 aead_sizes[] = { 16, 64, 256, 512, 1024, 2048, 4096, 8192, 0 }; + +#define XBUFSIZE 8 +#define MAX_IVLEN 32 + +static int testmgr_alloc_buf(char *buf[XBUFSIZE]) +{ + int i; + + for (i = 0; i < XBUFSIZE; i++) { + buf[i] = (void *)__get_free_page(GFP_KERNEL); + if (!buf[i]) + goto err_free_buf; + } + + return 0; + +err_free_buf: + while (i-- > 0) + free_page((unsigned long)buf[i]); + + return -ENOMEM; +} + +static void testmgr_free_buf(char *buf[XBUFSIZE]) +{ + int i; + + for (i = 0; i < XBUFSIZE; i++) + free_page((unsigned long)buf[i]); +} + +static void sg_init_aead(struct scatterlist *sg, char *xbuf[XBUFSIZE], + unsigned int buflen, const void *assoc, + unsigned int aad_size) +{ + int np = (buflen + PAGE_SIZE - 1)/PAGE_SIZE; + int k, rem; + + if (np > XBUFSIZE) { + rem = PAGE_SIZE; + np = XBUFSIZE; + } else { + rem = buflen % PAGE_SIZE; + } + + sg_init_table(sg, np + 1); + + sg_set_buf(&sg[0], assoc, aad_size); + + if (rem) + np--; + for (k = 0; k < np; k++) + sg_set_buf(&sg[k + 1], xbuf[k], PAGE_SIZE); + + if (rem) + sg_set_buf(&sg[k + 1], xbuf[k], rem); +} + static inline int do_one_aead_op(struct aead_request *req, int ret) { struct crypto_wait *wait = req->base.data; @@ -87,8 +147,44 @@ static inline int do_one_aead_op(struct aead_request *req, int ret) return crypto_wait_req(ret, wait); } -static int test_aead_jiffies(struct aead_request *req, int enc, - int blen, int secs) +struct test_mb_aead_data { + struct scatterlist sg[XBUFSIZE]; + struct scatterlist sgout[XBUFSIZE]; + struct aead_request *req; + struct crypto_wait wait; + char *xbuf[XBUFSIZE]; + char *xoutbuf[XBUFSIZE]; + char *axbuf[XBUFSIZE]; +}; + +static int do_mult_aead_op(struct test_mb_aead_data *data, int enc, + u32 num_mb) +{ + int i, rc[num_mb], err = 0; + + /* Fire up a bunch of concurrent requests */ + for (i = 0; i < num_mb; i++) { + if (enc == ENCRYPT) + rc[i] = crypto_aead_encrypt(data[i].req); + else + rc[i] = crypto_aead_decrypt(data[i].req); + } + + /* Wait for all requests to finish */ + for (i = 0; i < num_mb; i++) { + rc[i] = crypto_wait_req(rc[i], &data[i].wait); + + if (rc[i]) { + pr_info("concurrent request %d error %d\n", i, rc[i]); + err = rc[i]; + } + } + + return err; +} + +static int test_mb_aead_jiffies(struct test_mb_aead_data *data, int enc, + int blen, int secs, u32 num_mb) { unsigned long start, end; int bcount; @@ -96,21 +192,18 @@ static int test_aead_jiffies(struct aead_request *req, int enc, for (start = jiffies, end = start + secs * HZ, bcount = 0; time_before(jiffies, end); bcount++) { - if (enc) - ret = do_one_aead_op(req, crypto_aead_encrypt(req)); - else - ret = do_one_aead_op(req, crypto_aead_decrypt(req)); - + ret = do_mult_aead_op(data, enc, num_mb); if (ret) return ret; } - printk("%d operations in %d seconds (%ld bytes)\n", - bcount, secs, (long)bcount * blen); + pr_cont("%d operations in %d seconds (%ld bytes)\n", + bcount * num_mb, secs, (long)bcount * blen * num_mb); return 0; } -static int test_aead_cycles(struct aead_request *req, int enc, int blen) +static int test_mb_aead_cycles(struct test_mb_aead_data *data, int enc, + int blen, u32 num_mb) { unsigned long cycles = 0; int ret = 0; @@ -118,11 +211,7 @@ static int test_aead_cycles(struct aead_request *req, int enc, int blen) /* Warm-up run. */ for (i = 0; i < 4; i++) { - if (enc) - ret = do_one_aead_op(req, crypto_aead_encrypt(req)); - else - ret = do_one_aead_op(req, crypto_aead_decrypt(req)); - + ret = do_mult_aead_op(data, enc, num_mb); if (ret) goto out; } @@ -132,10 +221,7 @@ static int test_aead_cycles(struct aead_request *req, int enc, int blen) cycles_t start, end; start = get_cycles(); - if (enc) - ret = do_one_aead_op(req, crypto_aead_encrypt(req)); - else - ret = do_one_aead_op(req, crypto_aead_decrypt(req)); + ret = do_mult_aead_op(data, enc, num_mb); end = get_cycles(); if (ret) @@ -146,70 +232,276 @@ static int test_aead_cycles(struct aead_request *req, int enc, int blen) out: if (ret == 0) - printk("1 operation in %lu cycles (%d bytes)\n", - (cycles + 4) / 8, blen); + pr_cont("1 operation in %lu cycles (%d bytes)\n", + (cycles + 4) / (8 * num_mb), blen); return ret; } -static u32 block_sizes[] = { 16, 64, 256, 1024, 8192, 0 }; -static u32 aead_sizes[] = { 16, 64, 256, 512, 1024, 2048, 4096, 8192, 0 }; +static void test_mb_aead_speed(const char *algo, int enc, int secs, + struct aead_speed_template *template, + unsigned int tcount, u8 authsize, + unsigned int aad_size, u8 *keysize, u32 num_mb) +{ + struct test_mb_aead_data *data; + struct crypto_aead *tfm; + unsigned int i, j, iv_len; + const char *key; + const char *e; + void *assoc; + u32 *b_size; + char *iv; + int ret; -#define XBUFSIZE 8 -#define MAX_IVLEN 32 -static int testmgr_alloc_buf(char *buf[XBUFSIZE]) -{ - int i; + if (aad_size >= PAGE_SIZE) { + pr_err("associate data length (%u) too big\n", aad_size); + return; + } - for (i = 0; i < XBUFSIZE; i++) { - buf[i] = (void *)__get_free_page(GFP_KERNEL); - if (!buf[i]) - goto err_free_buf; + iv = kzalloc(MAX_IVLEN, GFP_KERNEL); + if (!iv) + return; + + if (enc == ENCRYPT) + e = "encryption"; + else + e = "decryption"; + + data = kcalloc(num_mb, sizeof(*data), GFP_KERNEL); + if (!data) + goto out_free_iv; + + tfm = crypto_alloc_aead(algo, 0, 0); + if (IS_ERR(tfm)) { + pr_err("failed to load transform for %s: %ld\n", + algo, PTR_ERR(tfm)); + goto out_free_data; } - return 0; + ret = crypto_aead_setauthsize(tfm, authsize); -err_free_buf: - while (i-- > 0) - free_page((unsigned long)buf[i]); + for (i = 0; i < num_mb; ++i) + if (testmgr_alloc_buf(data[i].xbuf)) { + while (i--) + testmgr_free_buf(data[i].xbuf); + goto out_free_tfm; + } - return -ENOMEM; + for (i = 0; i < num_mb; ++i) + if (testmgr_alloc_buf(data[i].axbuf)) { + while (i--) + testmgr_free_buf(data[i].axbuf); + goto out_free_xbuf; + } + + for (i = 0; i < num_mb; ++i) + if (testmgr_alloc_buf(data[i].xoutbuf)) { + while (i--) + testmgr_free_buf(data[i].axbuf); + goto out_free_axbuf; + } + + for (i = 0; i < num_mb; ++i) { + data[i].req = aead_request_alloc(tfm, GFP_KERNEL); + if (!data[i].req) { + pr_err("alg: skcipher: Failed to allocate request for %s\n", + algo); + while (i--) + aead_request_free(data[i].req); + goto out_free_xoutbuf; + } + } + + for (i = 0; i < num_mb; ++i) { + crypto_init_wait(&data[i].wait); + aead_request_set_callback(data[i].req, + CRYPTO_TFM_REQ_MAY_BACKLOG, + crypto_req_done, &data[i].wait); + } + + pr_info("\ntesting speed of multibuffer %s (%s) %s\n", algo, + get_driver_name(crypto_aead, tfm), e); + + i = 0; + do { + b_size = aead_sizes; + do { + if (*b_size + authsize > XBUFSIZE * PAGE_SIZE) { + pr_err("template (%u) too big for bufufer (%lu)\n", + authsize + *b_size, + XBUFSIZE * PAGE_SIZE); + goto out; + } + + pr_info("test %u (%d bit key, %d byte blocks): ", i, + *keysize * 8, *b_size); + + /* Set up tfm global state, i.e. the key */ + + memset(tvmem[0], 0xff, PAGE_SIZE); + key = tvmem[0]; + for (j = 0; j < tcount; j++) { + if (template[j].klen == *keysize) { + key = template[j].key; + break; + } + } + + crypto_aead_clear_flags(tfm, ~0); + + ret = crypto_aead_setkey(tfm, key, *keysize); + if (ret) { + pr_err("setkey() failed flags=%x\n", + crypto_aead_get_flags(tfm)); + goto out; + } + + iv_len = crypto_aead_ivsize(tfm); + if (iv_len) + memset(iv, 0xff, iv_len); + + /* Now setup per request stuff, i.e. buffers */ + + for (j = 0; j < num_mb; ++j) { + struct test_mb_aead_data *cur = &data[j]; + + assoc = cur->axbuf[0]; + memset(assoc, 0xff, aad_size); + + sg_init_aead(cur->sg, cur->xbuf, + *b_size + (enc ? 0 : authsize), + assoc, aad_size); + + sg_init_aead(cur->sgout, cur->xoutbuf, + *b_size + (enc ? authsize : 0), + assoc, aad_size); + + aead_request_set_ad(cur->req, aad_size); + + if (!enc) { + + aead_request_set_crypt(cur->req, + cur->sgout, + cur->sg, + *b_size, iv); + ret = crypto_aead_encrypt(cur->req); + ret = do_one_aead_op(cur->req, ret); + + if (ret) { + pr_err("calculating auth failed failed (%d)\n", + ret); + break; + } + } + + aead_request_set_crypt(cur->req, cur->sg, + cur->sgout, *b_size + + (enc ? 0 : authsize), + iv); + + } + + if (secs) + ret = test_mb_aead_jiffies(data, enc, *b_size, + secs, num_mb); + else + ret = test_mb_aead_cycles(data, enc, *b_size, + num_mb); + + if (ret) { + pr_err("%s() failed return code=%d\n", e, ret); + break; + } + b_size++; + i++; + } while (*b_size); + keysize++; + } while (*keysize); + +out: + for (i = 0; i < num_mb; ++i) + aead_request_free(data[i].req); +out_free_xoutbuf: + for (i = 0; i < num_mb; ++i) + testmgr_free_buf(data[i].xoutbuf); +out_free_axbuf: + for (i = 0; i < num_mb; ++i) + testmgr_free_buf(data[i].axbuf); +out_free_xbuf: + for (i = 0; i < num_mb; ++i) + testmgr_free_buf(data[i].xbuf); +out_free_tfm: + crypto_free_aead(tfm); +out_free_data: + kfree(data); +out_free_iv: + kfree(iv); } -static void testmgr_free_buf(char *buf[XBUFSIZE]) +static int test_aead_jiffies(struct aead_request *req, int enc, + int blen, int secs) { - int i; + unsigned long start, end; + int bcount; + int ret; - for (i = 0; i < XBUFSIZE; i++) - free_page((unsigned long)buf[i]); + for (start = jiffies, end = start + secs * HZ, bcount = 0; + time_before(jiffies, end); bcount++) { + if (enc) + ret = do_one_aead_op(req, crypto_aead_encrypt(req)); + else + ret = do_one_aead_op(req, crypto_aead_decrypt(req)); + + if (ret) + return ret; + } + + printk("%d operations in %d seconds (%ld bytes)\n", + bcount, secs, (long)bcount * blen); + return 0; } -static void sg_init_aead(struct scatterlist *sg, char *xbuf[XBUFSIZE], - unsigned int buflen, const void *assoc, - unsigned int aad_size) +static int test_aead_cycles(struct aead_request *req, int enc, int blen) { - int np = (buflen + PAGE_SIZE - 1)/PAGE_SIZE; - int k, rem; + unsigned long cycles = 0; + int ret = 0; + int i; - if (np > XBUFSIZE) { - rem = PAGE_SIZE; - np = XBUFSIZE; - } else { - rem = buflen % PAGE_SIZE; + /* Warm-up run. */ + for (i = 0; i < 4; i++) { + if (enc) + ret = do_one_aead_op(req, crypto_aead_encrypt(req)); + else + ret = do_one_aead_op(req, crypto_aead_decrypt(req)); + + if (ret) + goto out; } - sg_init_table(sg, np + 1); + /* The real thing. */ + for (i = 0; i < 8; i++) { + cycles_t start, end; - sg_set_buf(&sg[0], assoc, aad_size); + start = get_cycles(); + if (enc) + ret = do_one_aead_op(req, crypto_aead_encrypt(req)); + else + ret = do_one_aead_op(req, crypto_aead_decrypt(req)); + end = get_cycles(); - if (rem) - np--; - for (k = 0; k < np; k++) - sg_set_buf(&sg[k + 1], xbuf[k], PAGE_SIZE); + if (ret) + goto out; - if (rem) - sg_set_buf(&sg[k + 1], xbuf[k], rem); + cycles += end - start; + } + +out: + if (ret == 0) + printk("1 operation in %lu cycles (%d bytes)\n", + (cycles + 4) / 8, blen); + + return ret; } static void test_aead_speed(const char *algo, int enc, unsigned int secs, @@ -1912,6 +2204,33 @@ static int do_test(const char *alg, u32 type, u32 mask, int m) speed_template_32); break; + case 215: + test_mb_aead_speed("rfc4106(gcm(aes))", ENCRYPT, sec, NULL, + 0, 16, 16, aead_speed_template_20, num_mb); + test_mb_aead_speed("gcm(aes)", ENCRYPT, sec, NULL, 0, 16, 8, + speed_template_16_24_32, num_mb); + test_mb_aead_speed("rfc4106(gcm(aes))", DECRYPT, sec, NULL, + 0, 16, 16, aead_speed_template_20, num_mb); + test_mb_aead_speed("gcm(aes)", DECRYPT, sec, NULL, 0, 16, 8, + speed_template_16_24_32, num_mb); + break; + + case 216: + test_mb_aead_speed("rfc4309(ccm(aes))", ENCRYPT, sec, NULL, 0, + 16, 16, aead_speed_template_19, num_mb); + test_mb_aead_speed("rfc4309(ccm(aes))", DECRYPT, sec, NULL, 0, + 16, 16, aead_speed_template_19, num_mb); + break; + + case 217: + test_mb_aead_speed("rfc7539esp(chacha20,poly1305)", ENCRYPT, + sec, NULL, 0, 16, 8, aead_speed_template_36, + num_mb); + test_mb_aead_speed("rfc7539esp(chacha20,poly1305)", DECRYPT, + sec, NULL, 0, 16, 8, aead_speed_template_36, + num_mb); + break; + case 300: if (alg) { test_hash_speed(alg, sec, generic_hash_speed_template);