* [rfc 4.16-rt patch] crypto: cryptd - serialize RT request enqueue/dequeue with a local lock
@ 2018-07-11 15:19 Mike Galbraith
2018-07-26 16:58 ` Sebastian Andrzej Siewior
0 siblings, 1 reply; 3+ messages in thread
From: Mike Galbraith @ 2018-07-11 15:19 UTC (permalink / raw)
To: linux-rt-users; +Cc: Sebastian Andrzej Siewior, Thomas Gleixner, Steven Rostedt
Note: patch is the result of code inspection...
cryptod disables preemption to provide request enqueue/dequeue exclusion,
use a LOCAL_IRQ_LOCK to do the same for RT, keeping preemption enabled.
Signed-off-by: Mike Galbraith <efault@gmx.de>
---
crypto/cryptd.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
--- a/crypto/cryptd.c
+++ b/crypto/cryptd.c
@@ -31,10 +31,12 @@
#include <linux/scatterlist.h>
#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/locallock.h>
static unsigned int cryptd_max_cpu_qlen = 1000;
module_param(cryptd_max_cpu_qlen, uint, 0);
MODULE_PARM_DESC(cryptd_max_cpu_qlen, "Set cryptd Max queue depth");
+static DEFINE_LOCAL_IRQ_LOCK(cryptod_request_lock);
struct cryptd_cpu_queue {
struct crypto_queue queue;
@@ -141,7 +143,7 @@ static int cryptd_enqueue_request(struct
struct cryptd_cpu_queue *cpu_queue;
atomic_t *refcnt;
- cpu = get_cpu();
+ cpu = local_lock_cpu(cryptod_request_lock);
cpu_queue = this_cpu_ptr(queue->cpu_queue);
err = crypto_enqueue_request(&cpu_queue->queue, request);
@@ -158,7 +160,7 @@ static int cryptd_enqueue_request(struct
atomic_inc(refcnt);
out_put_cpu:
- put_cpu();
+ local_unlock_cpu(cryptod_request_lock);
return err;
}
@@ -179,10 +181,10 @@ static void cryptd_queue_worker(struct w
* cryptd_enqueue_request() being accessed from software interrupts.
*/
local_bh_disable();
- preempt_disable();
+ local_lock(cryptod_request_lock);
backlog = crypto_get_backlog(&cpu_queue->queue);
req = crypto_dequeue_request(&cpu_queue->queue);
- preempt_enable();
+ local_unlock(cryptod_request_lock);
local_bh_enable();
if (!req)
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [rfc 4.16-rt patch] crypto: cryptd - serialize RT request enqueue/dequeue with a local lock 2018-07-11 15:19 [rfc 4.16-rt patch] crypto: cryptd - serialize RT request enqueue/dequeue with a local lock Mike Galbraith @ 2018-07-26 16:58 ` Sebastian Andrzej Siewior 2018-07-26 18:03 ` Mike Galbraith 0 siblings, 1 reply; 3+ messages in thread From: Sebastian Andrzej Siewior @ 2018-07-26 16:58 UTC (permalink / raw) To: Mike Galbraith; +Cc: linux-rt-users, Thomas Gleixner, Steven Rostedt On 2018-07-11 17:19:59 [+0200], Mike Galbraith wrote: > Note: patch is the result of code inspection... > > cryptod disables preemption to provide request enqueue/dequeue exclusion, > use a LOCAL_IRQ_LOCK to do the same for RT, keeping preemption enabled. What about this: -------- >8 From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Thu, 26 Jul 2018 18:52:00 +0200 Subject: [PATCH] crypto: cryptd - add a lock instead preempt_disable/local_bh_disable cryptd has a per-CPU lock which protected with local_bh_disable() and preempt_disable(). Add an explicit spin_lock to make the locking context more obvious and visible to lockdep. Since it is a per-CPU lock, there should be no lock contention on the actual spinlock. There is a small race-window where we could be migrated to another CPU after the cpu_queue has been obtain. This is not a problem because the actual ressource is protected by the spinlock. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- crypto/cryptd.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/crypto/cryptd.c b/crypto/cryptd.c index addca7bae33f..8ad657cddc0a 100644 --- a/crypto/cryptd.c +++ b/crypto/cryptd.c @@ -39,6 +39,7 @@ MODULE_PARM_DESC(cryptd_max_cpu_qlen, "Set cryptd Max queue depth"); struct cryptd_cpu_queue { struct crypto_queue queue; struct work_struct work; + spinlock_t qlock; }; struct cryptd_queue { @@ -117,6 +118,7 @@ static int cryptd_init_queue(struct cryptd_queue *queue, cpu_queue = per_cpu_ptr(queue->cpu_queue, cpu); crypto_init_queue(&cpu_queue->queue, max_cpu_qlen); INIT_WORK(&cpu_queue->work, cryptd_queue_worker); + spin_lock_init(&cpu_queue->qlock); } pr_info("cryptd: max_cpu_qlen set to %d\n", max_cpu_qlen); return 0; @@ -141,8 +143,10 @@ static int cryptd_enqueue_request(struct cryptd_queue *queue, struct cryptd_cpu_queue *cpu_queue; atomic_t *refcnt; - cpu = get_cpu(); - cpu_queue = this_cpu_ptr(queue->cpu_queue); + cpu_queue = raw_cpu_ptr(queue->cpu_queue); + spin_lock_bh(&cpu_queue->qlock); + cpu = smp_processor_id(); + err = crypto_enqueue_request(&cpu_queue->queue, request); refcnt = crypto_tfm_ctx(request->tfm); @@ -158,7 +162,7 @@ static int cryptd_enqueue_request(struct cryptd_queue *queue, atomic_inc(refcnt); out_put_cpu: - put_cpu(); + spin_unlock_bh(&cpu_queue->qlock); return err; } @@ -174,16 +178,11 @@ static void cryptd_queue_worker(struct work_struct *work) cpu_queue = container_of(work, struct cryptd_cpu_queue, work); /* * Only handle one request at a time to avoid hogging crypto workqueue. - * preempt_disable/enable is used to prevent being preempted by - * cryptd_enqueue_request(). local_bh_disable/enable is used to prevent - * cryptd_enqueue_request() being accessed from software interrupts. */ - local_bh_disable(); - preempt_disable(); + spin_lock_bh(&cpu_queue->qlock); backlog = crypto_get_backlog(&cpu_queue->queue); req = crypto_dequeue_request(&cpu_queue->queue); - preempt_enable(); - local_bh_enable(); + spin_unlock_bh(&cpu_queue->qlock); if (!req) return; -- 2.18.0 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [rfc 4.16-rt patch] crypto: cryptd - serialize RT request enqueue/dequeue with a local lock 2018-07-26 16:58 ` Sebastian Andrzej Siewior @ 2018-07-26 18:03 ` Mike Galbraith 0 siblings, 0 replies; 3+ messages in thread From: Mike Galbraith @ 2018-07-26 18:03 UTC (permalink / raw) To: Sebastian Andrzej Siewior; +Cc: linux-rt-users, Thomas Gleixner, Steven Rostedt On Thu, 2018-07-26 at 18:58 +0200, Sebastian Andrzej Siewior wrote: > On 2018-07-11 17:19:59 [+0200], Mike Galbraith wrote: > > Note: patch is the result of code inspection... > > > > cryptod disables preemption to provide request enqueue/dequeue exclusion, > > use a LOCAL_IRQ_LOCK to do the same for RT, keeping preemption enabled. > > What about this: Looks fine to me, I'll ask my arm-thing box for its opinion. > -------- >8 > > From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> > Date: Thu, 26 Jul 2018 18:52:00 +0200 > Subject: [PATCH] crypto: cryptd - add a lock instead > preempt_disable/local_bh_disable > > cryptd has a per-CPU lock which protected with local_bh_disable() and > preempt_disable(). > Add an explicit spin_lock to make the locking context more obvious and > visible to lockdep. Since it is a per-CPU lock, there should be no lock > contention on the actual spinlock. > There is a small race-window where we could be migrated to another CPU > after the cpu_queue has been obtain. This is not a problem because the > actual ressource is protected by the spinlock. > > Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> > --- > crypto/cryptd.c | 19 +++++++++---------- > 1 file changed, 9 insertions(+), 10 deletions(-) > > diff --git a/crypto/cryptd.c b/crypto/cryptd.c > index addca7bae33f..8ad657cddc0a 100644 > --- a/crypto/cryptd.c > +++ b/crypto/cryptd.c > @@ -39,6 +39,7 @@ MODULE_PARM_DESC(cryptd_max_cpu_qlen, "Set cryptd Max queue depth"); > struct cryptd_cpu_queue { > struct crypto_queue queue; > struct work_struct work; > + spinlock_t qlock; > }; > > struct cryptd_queue { > @@ -117,6 +118,7 @@ static int cryptd_init_queue(struct cryptd_queue *queue, > cpu_queue = per_cpu_ptr(queue->cpu_queue, cpu); > crypto_init_queue(&cpu_queue->queue, max_cpu_qlen); > INIT_WORK(&cpu_queue->work, cryptd_queue_worker); > + spin_lock_init(&cpu_queue->qlock); > } > pr_info("cryptd: max_cpu_qlen set to %d\n", max_cpu_qlen); > return 0; > @@ -141,8 +143,10 @@ static int cryptd_enqueue_request(struct cryptd_queue *queue, > struct cryptd_cpu_queue *cpu_queue; > atomic_t *refcnt; > > - cpu = get_cpu(); > - cpu_queue = this_cpu_ptr(queue->cpu_queue); > + cpu_queue = raw_cpu_ptr(queue->cpu_queue); > + spin_lock_bh(&cpu_queue->qlock); > + cpu = smp_processor_id(); > + > err = crypto_enqueue_request(&cpu_queue->queue, request); > > refcnt = crypto_tfm_ctx(request->tfm); > @@ -158,7 +162,7 @@ static int cryptd_enqueue_request(struct cryptd_queue *queue, > atomic_inc(refcnt); > > out_put_cpu: > - put_cpu(); > + spin_unlock_bh(&cpu_queue->qlock); > > return err; > } > @@ -174,16 +178,11 @@ static void cryptd_queue_worker(struct work_struct *work) > cpu_queue = container_of(work, struct cryptd_cpu_queue, work); > /* > * Only handle one request at a time to avoid hogging crypto workqueue. > - * preempt_disable/enable is used to prevent being preempted by > - * cryptd_enqueue_request(). local_bh_disable/enable is used to prevent > - * cryptd_enqueue_request() being accessed from software interrupts. > */ > - local_bh_disable(); > - preempt_disable(); > + spin_lock_bh(&cpu_queue->qlock); > backlog = crypto_get_backlog(&cpu_queue->queue); > req = crypto_dequeue_request(&cpu_queue->queue); > - preempt_enable(); > - local_bh_enable(); > + spin_unlock_bh(&cpu_queue->qlock); > > if (!req) > return; ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2018-07-26 19:21 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2018-07-11 15:19 [rfc 4.16-rt patch] crypto: cryptd - serialize RT request enqueue/dequeue with a local lock Mike Galbraith 2018-07-26 16:58 ` Sebastian Andrzej Siewior 2018-07-26 18:03 ` Mike Galbraith
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).