From: Tim Chen <tim.c.chen@linux.intel.com>
To: Herbert Xu <herbert@gondor.apana.org.au>,
"H. Peter Anvin" <hpa@zytor.com>,
"David S.Miller" <davem@davemloft.net>,
Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@kernel.org>
Cc: Chandramouli Narayanan <mouli@linux.intel.com>,
Vinodh Gopal <vinodh.gopal@intel.com>,
James Guilford <james.guilford@intel.com>,
Wajdi Feghali <wajdi.k.feghali@intel.com>,
Tim Chen <tim.c.chen@linux.intel.com>,
Jussi Kivilinna <jussi.kivilinna@iki.fi>,
linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v4 7/7] crypto: SHA1 multibuffer - flush the jobs early if cpu becomes idle
Date: Fri, 11 Jul 2014 13:33:08 -0700 [thread overview]
Message-ID: <1405110788.2970.656.camel@schen9-DESK> (raw)
In-Reply-To: <cover.1405074379.git.tim.c.chen@linux.intel.com>
This patch adds a notifier to the SHA1 multi-buffer algorithm
when CPU is giong idle, so it can take advantage of the available
CPU power to flush out any partially completed jobs. This
will eliminate possible extended latency in the multi-buffer
algorithm.
Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com>
---
arch/x86/crypto/sha-mb/sha1_mb.c | 61 ++++++++++++++++++++++++++++++++++++++++
include/crypto/mcryptd.h | 1 +
2 files changed, 62 insertions(+)
diff --git a/arch/x86/crypto/sha-mb/sha1_mb.c b/arch/x86/crypto/sha-mb/sha1_mb.c
index 9c5feae..fd9b219 100644
--- a/arch/x86/crypto/sha-mb/sha1_mb.c
+++ b/arch/x86/crypto/sha-mb/sha1_mb.c
@@ -69,6 +69,7 @@
#include <asm/xcr.h>
#include <asm/xsave.h>
#include <linux/hardirq.h>
+#include <linux/sched.h>
#include <asm/fpu-internal.h>
#include "sha_mb_ctx.h"
@@ -820,6 +821,60 @@ static struct ahash_alg sha1_mb_async_alg = {
},
};
+void sha1_mb_force_flush(struct mcryptd_alg_cstate *cstate)
+{
+ struct mcryptd_hash_request_ctx *rctx;
+ struct sha1_hash_ctx *sha_ctx;
+
+ /* force flush uncompleted jobs in all data lanes before cpu becomes idle */
+ while (!list_empty(&cstate->work_list)) {
+ /* turn off flusher as we are flushing here */
+ if (cstate->flusher_engaged)
+ cstate->flusher_engaged = false;
+
+ kernel_fpu_begin();
+ sha_ctx = (struct sha1_hash_ctx *) sha1_ctx_mgr_flush(cstate->mgr);
+ kernel_fpu_end();
+ if (!sha_ctx) {
+ pr_err("sha1_mb error: nothing got flushed for non-empty list\n");
+ break;
+ }
+ rctx = cast_hash_to_mcryptd_ctx(sha_ctx);
+ sha_finish_walk(&rctx, cstate, true);
+ sha_complete_job(rctx, cstate, 0);
+ }
+
+ return;
+}
+
+void sha1_mb_earlyflush(struct work_struct *__work)
+{
+ struct mcryptd_alg_cstate *alg_cpu_state;
+
+ /* do not do early flush if other tasks are running */
+ if (nr_running_cpu(smp_processor_id()) > 1)
+ return;
+
+ alg_cpu_state = container_of(__work, struct mcryptd_alg_cstate, early_flush);
+ sha1_mb_force_flush(alg_cpu_state);
+}
+
+static int sha1_mb_idle_notifier(struct notifier_block *nb, unsigned long val,
+ void *data)
+{
+ struct mcryptd_alg_cstate *cstate =
+ this_cpu_ptr(sha1_mb_alg_state.alg_cstate);
+
+ if (val == IDLE_START && cstate->flusher_engaged)
+ queue_work_on(smp_processor_id(), kcrypto_wq, &cstate->early_flush);
+
+ return 0;
+}
+
+static struct notifier_block sha1_mb_idle_nb = {
+ .notifier_call = sha1_mb_idle_notifier,
+};
+
unsigned long sha1_mb_flusher(struct mcryptd_alg_cstate *cstate)
{
struct mcryptd_hash_request_ctx *rctx;
@@ -830,6 +885,9 @@ unsigned long sha1_mb_flusher(struct mcryptd_alg_cstate *cstate)
cur_time = jiffies;
+ if (!cstate->flusher_engaged)
+ return 0;
+
while (!list_empty(&cstate->work_list)) {
rctx = list_entry(cstate->work_list.next,
struct mcryptd_hash_request_ctx, waiter);
@@ -889,6 +947,7 @@ static int __init sha1_mb_mod_init(void)
cpu_state->next_seq_num = 0;
cpu_state->flusher_engaged = false;
INIT_DELAYED_WORK(&cpu_state->flush, mcryptd_flusher);
+ INIT_WORK(&cpu_state->early_flush, sha1_mb_earlyflush);
cpu_state->cpu = cpu;
cpu_state->alg_state = &sha1_mb_alg_state;
cpu_state->mgr = (struct sha1_ctx_mgr *) kzalloc(sizeof(struct sha1_ctx_mgr), GFP_KERNEL);
@@ -907,6 +966,7 @@ static int __init sha1_mb_mod_init(void)
if (err)
goto err1;
+ idle_notifier_register(&sha1_mb_idle_nb);
return 0;
err1:
@@ -925,6 +985,7 @@ static void __exit sha1_mb_mod_fini(void)
int cpu;
struct mcryptd_alg_cstate *cpu_state;
+ idle_notifier_unregister(&sha1_mb_idle_nb);
crypto_unregister_ahash(&sha1_mb_async_alg);
crypto_unregister_shash(&sha1_mb_shash_alg);
for_each_possible_cpu(cpu) {
diff --git a/include/crypto/mcryptd.h b/include/crypto/mcryptd.h
index b2b9055..2ef1824 100644
--- a/include/crypto/mcryptd.h
+++ b/include/crypto/mcryptd.h
@@ -82,6 +82,7 @@ struct mcryptd_alg_cstate {
unsigned next_seq_num;
bool flusher_engaged;
struct delayed_work flush;
+ struct work_struct early_flush;
int cpu;
struct mcryptd_alg_state *alg_state;
void *mgr;
--
1.7.11.7
prev parent reply other threads:[~2014-07-11 20:33 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <cover.1405074379.git.tim.c.chen@linux.intel.com>
2014-07-11 20:32 ` [PATCH v4 0/7] crypto: SHA1 multibuffer implementation Tim Chen
2014-07-11 20:32 ` [PATCH v4 1/7] crypto: SHA1 multibuffer crypto hash infrastructure Tim Chen
2014-07-11 20:32 ` [PATCH v4 2/7] crypto: SHA1 multibuffer algorithm data structures Tim Chen
2014-07-11 20:32 ` [PATCH v4 3/7] crypto: SHA1 multibuffer submit and flush routines for AVX2 Tim Chen
2014-07-11 20:32 ` [PATCH v4 4/7] crypto: SHA1 multibuffer crypto computation (x8 AVX2) Tim Chen
2014-07-11 20:33 ` [PATCH v4 5/7] crypto: SHA1 multibuffer scheduler Tim Chen
2014-07-11 20:33 ` [PATCH v4 6/7] sched: add function nr_running_cpu to expose number of tasks running on cpu Tim Chen
2014-07-12 9:25 ` Kirill Tkhai
2014-07-14 17:51 ` Tim Chen
2014-07-12 14:21 ` Tadeusz Struk
2014-07-14 23:51 ` Tim Chen
2014-07-14 10:16 ` Peter Zijlstra
2014-07-14 16:10 ` Tim Chen
2014-07-14 16:14 ` Peter Zijlstra
2014-07-14 17:05 ` Tim Chen
2014-07-14 18:17 ` Peter Zijlstra
2014-07-14 19:08 ` Tim Chen
2014-07-14 19:15 ` Peter Zijlstra
2014-07-14 19:50 ` Tim Chen
2014-07-15 9:50 ` Peter Zijlstra
2014-07-15 12:07 ` Peter Zijlstra
2014-07-15 12:59 ` Thomas Gleixner
2014-07-15 14:45 ` Mike Galbraith
2014-07-15 14:53 ` Peter Zijlstra
2014-07-15 18:06 ` Mike Galbraith
2014-07-15 19:03 ` Peter Zijlstra
2014-07-15 19:24 ` Mike Galbraith
2014-07-15 18:41 ` Tim Chen
2014-07-15 20:46 ` Thomas Gleixner
2014-07-15 18:40 ` Tim Chen
2014-07-15 18:40 ` Tim Chen
2014-07-15 13:36 ` Peter Zijlstra
2014-07-15 15:21 ` Tejun Heo
2014-07-15 16:37 ` Peter Zijlstra
2014-07-11 20:33 ` Tim Chen [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1405110788.2970.656.camel@schen9-DESK \
--to=tim.c.chen@linux.intel.com \
--cc=davem@davemloft.net \
--cc=herbert@gondor.apana.org.au \
--cc=hpa@zytor.com \
--cc=james.guilford@intel.com \
--cc=jussi.kivilinna@iki.fi \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=mouli@linux.intel.com \
--cc=peterz@infradead.org \
--cc=vinodh.gopal@intel.com \
--cc=wajdi.k.feghali@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox