Message ID | 20160628123352.GA17844@gondor.apana.org.au |
---|---|
State | New, archived |
Headers | show |
Series |
|
Related | show |
On 06/28/2016 02:33 PM, Herbert Xu wrote: > On Tue, Jun 28, 2016 at 12:15:43PM +0200, Krzysztof Kozlowski wrote: >> Oops: > > Thanks, there was a typo where it said k instead of j in the second > loop. > > ---8<--- > This patch resolves a number of issues with the mb speed test > function: > > * The tfm is never freed. > * Memory is allocated even when we're not using mb. > * When an error occurs we don't wait for completion for other requests. > * When an error occurs during allocation we may leak memory. > * The test function ignores plen but still runs for plen != blen. > * The backlog flag is incorrectly used (may crash). > > This patch tries to resolve all these issues as well as making > the code consistent with the existing hash speed testing function. > > Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Seems to work fine except: 1. The updates are always 1. 2. For bigger blocks it reports always 1 or 3 cycles per byte: [root@odroidxu3 ~]# modprobe tcrypt mode=423 [ 70.129206] [ 70.129206] testing speed of multibuffer sha256 (sha256-neon) [ 70.135511] test 0 ( 16 byte blocks, 16 bytes per update, 1 updates): 4597 cycles/operation, 35 cycles/byte [ 70.145826] test 2 ( 64 byte blocks, 64 bytes per update, 1 updates): 5762 cycles/operation, 11 cycles/byte [ 70.156469] test 5 ( 256 byte blocks, 256 bytes per update, 1 updates): 10687 cycles/operation, 5 cycles/byte [ 70.167125] test 8 ( 1024 byte blocks, 1024 bytes per update, 1 updates): 31485 cycles/operation, 3 cycles/byte [ 70.177919] test 12 ( 2048 byte blocks, 2048 bytes per update, 1 updates): 59281 cycles/operation, 3 cycles/byte [ 70.189780] test 16 ( 4096 byte blocks, 4096 bytes per update, 1 updates): 118097 cycles/operation, 3 cycles/byte [ 70.204117] test 21 ( 8192 byte blocks, 8192 bytes per update, 1 updates): 232309 cycles/operation, 3 cycles/byte [root@odroidxu3 ~]# modprobe tcrypt mode=422 [ 71.988248] [ 71.988248] testing speed of multibuffer sha1 (sha1-neon) [ 71.994097] test 0 ( 16 byte blocks, 16 bytes per update, 1 updates): 2506 cycles/operation, 19 cycles/byte [ 72.004547] test 2 ( 64 byte blocks, 64 bytes per update, 1 updates): 2299 cycles/operation, 4 cycles/byte [ 72.015152] test 5 ( 256 byte blocks, 256 bytes per update, 1 updates): 3535 cycles/operation, 1 cycles/byte [ 72.025807] test 8 ( 1024 byte blocks, 1024 bytes per update, 1 updates): 9403 cycles/operation, 1 cycles/byte [ 72.036401] test 12 ( 2048 byte blocks, 2048 bytes per update, 1 updates): 17142 cycles/operation, 1 cycles/byte [ 72.047058] test 16 ( 4096 byte blocks, 4096 bytes per update, 1 updates): 33109 cycles/operation, 1 cycles/byte [ 72.057821] test 21 ( 8192 byte blocks, 8192 bytes per update, 1 updates): 67750 cycles/operation, 1 cycles/byte modprobe: ERROR: could not insert 'tcrypt': Resource temporarily unavailable Is it expected? Best regards, Krzysztof
On Wed, Jun 29, 2016 at 10:16:10AM +0200, Krzysztof Kozlowski wrote: > > Seems to work fine except: > 1. The updates are always 1. Yes the test function only does digest so it's always one update. > 2. For bigger blocks it reports always 1 or 3 cycles per byte: Yes the average cycles per-byte should reach an asymptotic value. Thanks,
On 06/29/2016 10:19 AM, Herbert Xu wrote: > On Wed, Jun 29, 2016 at 10:16:10AM +0200, Krzysztof Kozlowski wrote: >> >> Seems to work fine except: >> 1. The updates are always 1. > > Yes the test function only does digest so it's always one update. > >> 2. For bigger blocks it reports always 1 or 3 cycles per byte: > > Yes the average cycles per-byte should reach an asymptotic value. Then: Tested-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Best regards, Krzysztof
I tested the latest cryptodev tree on my haswell machine and this is what I see: [ 40.402834] modprobe tcrypt mode=422 [ 40.403105] testing speed of multibuffer sha1 (sha1_mb) [ 40.403108] test 0 ( 16 byte blocks, 16 bytes per update, 1 updates): 32271 cycles/operation, 252 cycles/byte [ 40.403118] At least one hashing failed ret=-115 [ 43.218712] modprobe tcrypt mode=423 [ 43.218712] testing speed of multibuffer sha256 (sha256_mb) [ 43.218715] test 0 ( 16 byte blocks, 16 bytes per update, 1 updates): 106965 cycles/operation, 835 cycles/byte [ 43.218747] At least one hashing failed ret=-115 [ 45.346657] modprobe tcrypt mode=424 [ 45.346657] testing speed of multibuffer sha512 (sha512_mb) [ 45.346660] test 0 ( 16 byte blocks, 16 bytes per update, 1 updates): 43179 cycles/operation, 337 cycles/byte [ 45.346673] At least one hashing failed ret=-115 Don't think this is expected, is it? This is the patch which might have an issue? 72259deb3a9f2c07d18d71d7c9356754e7d88369 Thanks, Megha On Wed, 2016-06-29 at 10:28 +0200, Krzysztof Kozlowski wrote: > On 06/29/2016 10:19 AM, Herbert Xu wrote: > > On Wed, Jun 29, 2016 at 10:16:10AM +0200, Krzysztof Kozlowski wrote: > >> > >> Seems to work fine except: > >> 1. The updates are always 1. > > > > Yes the test function only does digest so it's always one update. > > > >> 2. For bigger blocks it reports always 1 or 3 cycles per byte: > > > > Yes the average cycles per-byte should reach an asymptotic value. > > Then: > Tested-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> > > Best regards, > Krzysztof >
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 1537a1c..68064fc 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -409,54 +409,61 @@ static inline int do_one_ahash_op(struct ahash_request *req, int ret) return ret; } -char ptext[4096]; -struct scatterlist sg[8][8]; -char result[8][64]; -struct ahash_request *req[8]; -struct tcrypt_result tresult[8]; -char *xbuf[8][XBUFSIZE]; -unsigned long start[8], end[8], mid; +struct test_mb_ahash_data { + struct scatterlist sg[TVMEMSIZE]; + char result[64]; + struct ahash_request *req; + struct tcrypt_result tresult; + char *xbuf[XBUFSIZE]; +}; static void test_mb_ahash_speed(const char *algo, unsigned int sec, - struct hash_speed *speed) + struct hash_speed *speed) { - unsigned int i, j, k; - void *hash_buff; - int ret = -ENOMEM; + struct test_mb_ahash_data *data; struct crypto_ahash *tfm; + unsigned long start, end; unsigned long cycles; + unsigned int i, j, k; + int ret; + + data = kzalloc(sizeof(*data) * 8, GFP_KERNEL); + if (!data) + return; tfm = crypto_alloc_ahash(algo, 0, 0); if (IS_ERR(tfm)) { pr_err("failed to load transform for %s: %ld\n", algo, PTR_ERR(tfm)); - return; + goto free_data; } + for (i = 0; i < 8; ++i) { - if (testmgr_alloc_buf(xbuf[i])) - goto out_nobuf; + if (testmgr_alloc_buf(data[i].xbuf)) + goto out; - init_completion(&tresult[i].completion); + init_completion(&data[i].tresult.completion); - req[i] = ahash_request_alloc(tfm, GFP_KERNEL); - if (!req[i]) { + data[i].req = ahash_request_alloc(tfm, GFP_KERNEL); + if (!data[i].req) { pr_err("alg: hash: Failed to allocate request for %s\n", algo); - goto out_noreq; + goto out; } - ahash_request_set_callback(req[i], CRYPTO_TFM_REQ_MAY_BACKLOG, - tcrypt_complete, &tresult[i]); - hash_buff = xbuf[i][0]; - memcpy(hash_buff, ptext, 4096); + ahash_request_set_callback(data[i].req, 0, + tcrypt_complete, &data[i].tresult); + test_hash_sg_init(data[i].sg); } - j = 0; - - pr_err("\ntesting speed of %s (%s)\n", algo, - get_driver_name(crypto_ahash, tfm)); + pr_info("\ntesting speed of multibuffer %s (%s)\n", algo, + get_driver_name(crypto_ahash, tfm)); for (i = 0; speed[i].blen != 0; i++) { + /* For some reason this only tests digests. */ + if (speed[i].blen != speed[i].plen) + continue; + if (speed[i].blen > TVMEMSIZE * PAGE_SIZE) { pr_err("template (%u) too big for tvmem (%lu)\n", speed[i].blen, TVMEMSIZE * PAGE_SIZE); @@ -466,53 +473,59 @@ static void test_mb_ahash_speed(const char *algo, unsigned int sec, if (speed[i].klen) crypto_ahash_setkey(tfm, tvmem[0], speed[i].klen); - for (k = 0; k < 8; ++k) { - sg_init_one(&sg[k][0], (void *) xbuf[k][0], - speed[i].blen); - ahash_request_set_crypt(req[k], sg[k], - result[k], speed[i].blen); - } + for (k = 0; k < 8; k++) + ahash_request_set_crypt(data[k].req, data[k].sg, + data[k].result, speed[i].blen); - pr_err("test%3u (%5u byte blocks,%5u bytes per update,%4u updates): ", + pr_info("test%3u " + "(%5u byte blocks,%5u bytes per update,%4u updates): ", i, speed[i].blen, speed[i].plen, speed[i].blen / speed[i].plen); - for (k = 0; k < 8; ++k) { - start[k] = get_cycles(); - ret = crypto_ahash_digest(req[k]); - if (ret == -EBUSY || ret == -EINPROGRESS) + start = get_cycles(); + + for (k = 0; k < 8; k++) { + ret = crypto_ahash_digest(data[k].req); + if (ret == -EINPROGRESS) continue; - if (ret) { - pr_err("alg (%s) something wrong, ret = %d ...\n", - algo, ret); - goto out; - } + + if (ret) + break; + + complete(&data[k].tresult.completion); + data[k].tresult.err = 0; } - mid = get_cycles(); - for (k = 0; k < 8; ++k) { - struct tcrypt_result *tr = &tresult[k]; + for (j = 0; j < k; j++) { + struct tcrypt_result *tr = &data[j].tresult; - ret = wait_for_completion_interruptible(&tr->completion); - if (ret) - pr_err("alg(%s): hash: digest failed\n", algo); - end[k] = get_cycles(); + wait_for_completion(&tr->completion); + if (tr->err) + ret = tr->err; } - cycles = end[7] - start[0]; - printk("\nBlock: %6lu cycles (%4lu cycles/byte)\n", - cycles, cycles / (8 * speed[i].blen)); + end = get_cycles(); + cycles = end - start; + pr_cont("%6lu cycles/operation, %4lu cycles/byte\n", + cycles, cycles / (8 * speed[i].blen)); + + if (ret) { + pr_err("At least one hashing failed ret=%d\n", ret); + break; + } } - ret = 0; out: for (k = 0; k < 8; ++k) - ahash_request_free(req[k]); -out_noreq: + ahash_request_free(data[k].req); + for (k = 0; k < 8; ++k) - testmgr_free_buf(xbuf[k]); -out_nobuf: - return; + testmgr_free_buf(data[k].xbuf); + + crypto_free_ahash(tfm); + +free_data: + kfree(data); } static int test_ahash_jiffies_digest(struct ahash_request *req, int blen,