[PATCH][RFC] crypto: tcrypt - Ahash tests changed to run in parallel.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This allows to test & run multiple parallel crypto ahash contexts.
Each of the test vector under the ahash speed test template is started
under a separate kthread.

Signed-off-by: Vakul Garg <vakul@xxxxxxxxxxxxx>
---
 crypto/tcrypt.c |  164 +++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 129 insertions(+), 35 deletions(-)

diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 7ae2130..e879de9 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -33,6 +33,7 @@
 #include <linux/jiffies.h>
 #include <linux/timex.h>
 #include <linux/interrupt.h>
+#include <linux/kthread.h>
 #include "tcrypt.h"
 #include "internal.h"
 
@@ -497,9 +498,9 @@ static inline int do_one_ahash_op(struct ahash_request *req, int ret)
 	}
 	return ret;
 }
-
 static int test_ahash_jiffies_digest(struct ahash_request *req, int blen,
-				     char *out, int sec)
+				     char *out, int sec,
+				     struct completion *comp)
 {
 	unsigned long start, end;
 	int bcount;
@@ -512,6 +513,11 @@ static int test_ahash_jiffies_digest(struct ahash_request *req, int blen,
 			return ret;
 	}
 
+	wait_for_completion_interruptible(comp);
+
+	pr_info("test (%5u byte blocks,%5u bytes per update,%4u updates): ",
+		blen, blen, blen/blen);
+
 	printk("%6u opers/sec, %9lu bytes/sec\n",
 	       bcount / sec, ((long)bcount * blen) / sec);
 
@@ -519,14 +525,15 @@ static int test_ahash_jiffies_digest(struct ahash_request *req, int blen,
 }
 
 static int test_ahash_jiffies(struct ahash_request *req, int blen,
-			      int plen, char *out, int sec)
+			      int plen, char *out, int sec,
+			      struct completion *comp)
 {
 	unsigned long start, end;
 	int bcount, pcount;
 	int ret;
 
 	if (plen == blen)
-		return test_ahash_jiffies_digest(req, blen, out, sec);
+		return test_ahash_jiffies_digest(req, blen, out, sec, comp);
 
 	for (start = jiffies, end = start + sec * HZ, bcount = 0;
 	     time_before(jiffies, end); bcount++) {
@@ -544,6 +551,11 @@ static int test_ahash_jiffies(struct ahash_request *req, int blen,
 			return ret;
 	}
 
+	wait_for_completion_interruptible(comp);
+
+	pr_info("test (%5u byte blocks,%5u bytes per update,%4u updates): ",
+		blen, plen, blen/plen);
+
 	pr_cont("%6u opers/sec, %9lu bytes/sec\n",
 		bcount / sec, ((long)bcount * blen) / sec);
 
@@ -551,7 +563,7 @@ static int test_ahash_jiffies(struct ahash_request *req, int blen,
 }
 
 static int test_ahash_cycles_digest(struct ahash_request *req, int blen,
-				    char *out)
+				    char *out, struct completion *comp)
 {
 	unsigned long cycles = 0;
 	int ret, i;
@@ -582,6 +594,11 @@ out:
 	if (ret)
 		return ret;
 
+	wait_for_completion_interruptible(comp);
+
+	pr_info("test (%5u byte blocks,%5u bytes per update,%4u updates): ",
+		blen, blen, blen/blen);
+
 	pr_cont("%6lu cycles/operation, %4lu cycles/byte\n",
 		cycles / 8, cycles / (8 * blen));
 
@@ -589,13 +606,13 @@ out:
 }
 
 static int test_ahash_cycles(struct ahash_request *req, int blen,
-			     int plen, char *out)
+			     int plen, char *out, struct completion *comp)
 {
 	unsigned long cycles = 0;
 	int i, pcount, ret;
 
 	if (plen == blen)
-		return test_ahash_cycles_digest(req, blen, out);
+		return test_ahash_cycles_digest(req, blen, out, comp);
 
 	/* Warm-up run. */
 	for (i = 0; i < 4; i++) {
@@ -636,51 +653,119 @@ static int test_ahash_cycles(struct ahash_request *req, int blen,
 	}
 
 out:
+
 	if (ret)
 		return ret;
 
+	wait_for_completion_interruptible(comp);
+
+	pr_info("test (%5u byte blocks,%5u bytes per update,%4u updates): ",
+		blen, plen, blen/plen);
+
 	pr_cont("%6lu cycles/operation, %4lu cycles/byte\n",
 		cycles / 8, cycles / (8 * blen));
 
 	return 0;
 }
 
-static void test_ahash_speed(const char *algo, unsigned int sec,
-			     struct hash_speed *speed)
+struct hash_test {
+	const char *algo;
+	unsigned int blen;
+	unsigned int plen;
+	unsigned int klen;
+	unsigned int sec;
+	struct completion print;
+	struct completion finish;
+};
+
+static int test_ahash_speed_thread(void *data)
 {
 	struct scatterlist sg[TVMEMSIZE];
 	struct tcrypt_result tresult;
 	struct ahash_request *req;
 	struct crypto_ahash *tfm;
 	static char output[1024];
-	int i, ret;
-
-	printk(KERN_INFO "\ntesting speed of async %s\n", algo);
+	int ret;
+	struct hash_test *test = data;
 
-	tfm = crypto_alloc_ahash(algo, 0, 0);
+	tfm = crypto_alloc_ahash(test->algo, 0, 0);
 	if (IS_ERR(tfm)) {
 		pr_err("failed to load transform for %s: %ld\n",
-		       algo, PTR_ERR(tfm));
-		return;
+		       test->algo, PTR_ERR(tfm));
+		ret = PTR_ERR(tfm);
+		goto stop;
 	}
 
 	if (crypto_ahash_digestsize(tfm) > sizeof(output)) {
 		pr_err("digestsize(%u) > outputbuffer(%zu)\n",
 		       crypto_ahash_digestsize(tfm), sizeof(output));
-		goto out;
+		ret = -EINVAL;
+		goto err;
 	}
 
 	test_hash_sg_init(sg);
 	req = ahash_request_alloc(tfm, GFP_KERNEL);
 	if (!req) {
 		pr_err("ahash request allocation failure\n");
-		goto out;
+		ret = PTR_ERR(req);
+		goto err;
 	}
 
 	init_completion(&tresult.completion);
 	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
 				   tcrypt_complete, &tresult);
 
+
+	ahash_request_set_crypt(req, sg, output, test->plen);
+
+	if (sec)
+		ret = test_ahash_jiffies(req, test->blen,
+					 test->plen, output, sec,
+					 &test->print);
+	else
+		ret = test_ahash_cycles(req, test->blen,
+					test->plen, output, &test->print);
+
+	if (ret)
+		pr_err("hashing failed ret=%d\n", ret);
+
+	ahash_request_free(req);
+
+err:
+	crypto_free_ahash(tfm);
+
+stop:
+	complete(&test->finish);
+
+	return ret;
+}
+
+
+static void test_ahash_speed(const char *algo, unsigned int sec,
+			     struct hash_speed *speed)
+{
+	int i, num_tests;
+	struct hash_test *tests;
+	struct task_struct **threads;
+
+	pr_info("\ntesting speed of async %s\n", algo);
+
+	/* Count the number of tests to be done */
+	for (i = 0; speed[i].blen != 0; i++)
+		;
+
+	threads = kzalloc(i * sizeof(struct task_struct *), GFP_KERNEL);
+	if (!threads) {
+		pr_err("Memory alloc for threads failed\n");
+		return;
+	}
+
+	tests = kzalloc(i * sizeof(struct hash_test), GFP_KERNEL);
+	if (!threads) {
+		pr_err("Memory alloc for hash tests failed\n");
+		goto err;
+	}
+
 	for (i = 0; speed[i].blen != 0; i++) {
 		if (speed[i].blen > TVMEMSIZE * PAGE_SIZE) {
 			pr_err("template (%u) too big for tvmem (%lu)\n",
@@ -688,29 +773,38 @@ static void test_ahash_speed(const char *algo, unsigned int sec,
 			break;
 		}
 
-		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);
-
-		ahash_request_set_crypt(req, sg, output, speed[i].plen);
-
-		if (sec)
-			ret = test_ahash_jiffies(req, speed[i].blen,
-						 speed[i].plen, output, sec);
-		else
-			ret = test_ahash_cycles(req, speed[i].blen,
-						speed[i].plen, output);
-
-		if (ret) {
-			pr_err("hashing failed ret=%d\n", ret);
+		tests[i].algo = algo;
+		tests[i].blen = speed[i].blen;
+		tests[i].plen = speed[i].plen;
+		tests[i].klen = speed[i].klen;
+		init_completion(&tests[i].print);
+		init_completion(&tests[i].finish);
+
+		/* Create a kthread for the test vector in template */
+		threads[i] = kthread_run(test_ahash_speed_thread, &tests[i],
+					 "tcrypt_ahash_%d", i);
+		if (IS_ERR(threads[i])) {
+			pr_err("tcrypt_ahash_%d creation failed\n", i);
 			break;
 		}
 	}
 
-	ahash_request_free(req);
+	num_tests = i;
 
-out:
-	crypto_free_ahash(tfm);
+	/* TODO: Let all threads pass a barrier so that they start
+	 * crypto tests together.
+	 */
+
+	/* Signal threads one by one for printing results and stop them*/
+	for (i = 0; i < num_tests; i++) {
+		complete(&tests[i].print);
+		/*kthread_stop(threads[i]);*/
+		wait_for_completion_interruptible(&tests[i].finish);
+	}
+
+err:
+	kfree(threads);
+	kfree(tests);
 }
 
 static inline int do_one_acipher_op(struct ablkcipher_request *req, int ret)
-- 
1.7.7.6


--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]

  Powered by Linux