Skip to content

Commit d80771c

Browse files
cdleonardherbertx
authored andcommitted
crypto: mxs-dcp - Fix wait logic on chan threads
When compiling with CONFIG_DEBUG_ATOMIC_SLEEP=y the mxs-dcp driver prints warnings such as: WARNING: CPU: 0 PID: 120 at kernel/sched/core.c:7736 __might_sleep+0x98/0x9c do not call blocking ops when !TASK_RUNNING; state=1 set at [<8081978c>] dcp_chan_thread_sha+0x3c/0x2ec The problem is that blocking ops will manipulate current->state themselves so it is not allowed to call them between set_current_state(TASK_INTERRUPTIBLE) and schedule(). Fix this by converting the per-chan mutex to a spinlock (it only protects tiny list ops anyway) and rearranging the wait logic so that callbacks are called current->state as TASK_RUNNING. Those callbacks will indeed call blocking ops themselves so this is required. Cc: <stable@vger.kernel.org> Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
1 parent add92a8 commit d80771c

File tree

1 file changed

+30
-23
lines changed

1 file changed

+30
-23
lines changed

drivers/crypto/mxs-dcp.c

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ struct dcp {
6363
struct dcp_coherent_block *coh;
6464

6565
struct completion completion[DCP_MAX_CHANS];
66-
struct mutex mutex[DCP_MAX_CHANS];
66+
spinlock_t lock[DCP_MAX_CHANS];
6767
struct task_struct *thread[DCP_MAX_CHANS];
6868
struct crypto_queue queue[DCP_MAX_CHANS];
6969
};
@@ -349,25 +349,29 @@ static int dcp_chan_thread_aes(void *data)
349349

350350
int ret;
351351

352-
do {
353-
__set_current_state(TASK_INTERRUPTIBLE);
352+
while (!kthread_should_stop()) {
353+
set_current_state(TASK_INTERRUPTIBLE);
354354

355-
mutex_lock(&sdcp->mutex[chan]);
355+
spin_lock(&sdcp->lock[chan]);
356356
backlog = crypto_get_backlog(&sdcp->queue[chan]);
357357
arq = crypto_dequeue_request(&sdcp->queue[chan]);
358-
mutex_unlock(&sdcp->mutex[chan]);
358+
spin_unlock(&sdcp->lock[chan]);
359+
360+
if (!backlog && !arq) {
361+
schedule();
362+
continue;
363+
}
364+
365+
set_current_state(TASK_RUNNING);
359366

360367
if (backlog)
361368
backlog->complete(backlog, -EINPROGRESS);
362369

363370
if (arq) {
364371
ret = mxs_dcp_aes_block_crypt(arq);
365372
arq->complete(arq, ret);
366-
continue;
367373
}
368-
369-
schedule();
370-
} while (!kthread_should_stop());
374+
}
371375

372376
return 0;
373377
}
@@ -409,9 +413,9 @@ static int mxs_dcp_aes_enqueue(struct ablkcipher_request *req, int enc, int ecb)
409413
rctx->ecb = ecb;
410414
actx->chan = DCP_CHAN_CRYPTO;
411415

412-
mutex_lock(&sdcp->mutex[actx->chan]);
416+
spin_lock(&sdcp->lock[actx->chan]);
413417
ret = crypto_enqueue_request(&sdcp->queue[actx->chan], &req->base);
414-
mutex_unlock(&sdcp->mutex[actx->chan]);
418+
spin_unlock(&sdcp->lock[actx->chan]);
415419

416420
wake_up_process(sdcp->thread[actx->chan]);
417421

@@ -640,13 +644,20 @@ static int dcp_chan_thread_sha(void *data)
640644
struct ahash_request *req;
641645
int ret, fini;
642646

643-
do {
644-
__set_current_state(TASK_INTERRUPTIBLE);
647+
while (!kthread_should_stop()) {
648+
set_current_state(TASK_INTERRUPTIBLE);
645649

646-
mutex_lock(&sdcp->mutex[chan]);
650+
spin_lock(&sdcp->lock[chan]);
647651
backlog = crypto_get_backlog(&sdcp->queue[chan]);
648652
arq = crypto_dequeue_request(&sdcp->queue[chan]);
649-
mutex_unlock(&sdcp->mutex[chan]);
653+
spin_unlock(&sdcp->lock[chan]);
654+
655+
if (!backlog && !arq) {
656+
schedule();
657+
continue;
658+
}
659+
660+
set_current_state(TASK_RUNNING);
650661

651662
if (backlog)
652663
backlog->complete(backlog, -EINPROGRESS);
@@ -658,12 +669,8 @@ static int dcp_chan_thread_sha(void *data)
658669
ret = dcp_sha_req_to_buf(arq);
659670
fini = rctx->fini;
660671
arq->complete(arq, ret);
661-
if (!fini)
662-
continue;
663672
}
664-
665-
schedule();
666-
} while (!kthread_should_stop());
673+
}
667674

668675
return 0;
669676
}
@@ -721,9 +728,9 @@ static int dcp_sha_update_fx(struct ahash_request *req, int fini)
721728
rctx->init = 1;
722729
}
723730

724-
mutex_lock(&sdcp->mutex[actx->chan]);
731+
spin_lock(&sdcp->lock[actx->chan]);
725732
ret = crypto_enqueue_request(&sdcp->queue[actx->chan], &req->base);
726-
mutex_unlock(&sdcp->mutex[actx->chan]);
733+
spin_unlock(&sdcp->lock[actx->chan]);
727734

728735
wake_up_process(sdcp->thread[actx->chan]);
729736
mutex_unlock(&actx->mutex);
@@ -997,7 +1004,7 @@ static int mxs_dcp_probe(struct platform_device *pdev)
9971004
platform_set_drvdata(pdev, sdcp);
9981005

9991006
for (i = 0; i < DCP_MAX_CHANS; i++) {
1000-
mutex_init(&sdcp->mutex[i]);
1007+
spin_lock_init(&sdcp->lock[i]);
10011008
init_completion(&sdcp->completion[i]);
10021009
crypto_init_queue(&sdcp->queue[i], 50);
10031010
}

0 commit comments

Comments
 (0)