Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp3001056imu; Sun, 9 Dec 2018 14:47:05 -0800 (PST) X-Google-Smtp-Source: AFSGD/VWyYaBbKo9Fk2NfT7V/20byZ6w/HAuw6Ho3uVod4tBMx36BXjR2NzJhGwm3ylrOaeuryhC X-Received: by 2002:a62:68c5:: with SMTP id d188mr10481660pfc.194.1544395624932; Sun, 09 Dec 2018 14:47:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544395624; cv=none; d=google.com; s=arc-20160816; b=RNAAz7oxezs6Vqyry2gjvloJa6RFs0DIbdaWakEGwJCAtpgDZgiPT8XbslBY3wJeQb 1ilLgYzmIjiJH451MOn/mv+FoqfKDQlo7eHclBE+om9b0mQB/mSd8mL3UhWYsVnVgwtR zwR1KSQZiF4g+auJLaqUuWWLne/oEcdRy/tPN7cjAENcJgUSv0LosVpRYBnGIbkKqoCt qMGs5r3IlEpcERsRsQUKfSGoOZk1+YlDBjI6Vey3FftQ2/zG7PSX89dtq/3LSiGuPcA0 3f2lSS/VjB5XsdLLzebUagnDP0w65WEo61TXxML0+KJIFEyvUmyVACzE9dKQg7PRXnj/ Zowg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:subject:message-id:date:cc:to :from:mime-version:content-transfer-encoding:content-disposition; bh=Izr5HxdMbOhWH/mApPHborP7k25m8vMlwzQUxqpPvPw=; b=Sz6mtWsxER3DfZv6J5I5BIyeUFA6UvrbnItJp9efifdTp2Cqbr2GjqUmwKVmcZl5Lh QV9y0moeSdbmWwbSbQ2MuBw0WCCnsxib2sm2MqhcA4elzc40EjcClpGnGgvlRiSiGOxU qAqncnxQncIVJeHsPMyQOfhs1OTzytTt7nIlT9bxPGAav1QfaSFLcUB8ErtblJeQ0cXe xsDm6fE80wE8ne4XBgv1FyhAYhUyIDI16g/EYpVMH2BFl9cAOEKPH2lIICwXm17P9E0h f7JJ0rH4F7dTYB6H68PM9IkpzmKp4ioZ0xQsPSyX5+IHatvsWwvZAc5FSliGU8qnSZxW +MeQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 2si8811467pfd.154.2018.12.09.14.46.49; Sun, 09 Dec 2018 14:47:04 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726899AbeLIV4A (ORCPT + 99 others); Sun, 9 Dec 2018 16:56:00 -0500 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:35926 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726668AbeLIVzd (ORCPT ); Sun, 9 Dec 2018 16:55:33 -0500 Received: from pub.yeoldevic.com ([81.174.156.145] helo=deadeye) by shadbolt.decadent.org.uk with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1gW72w-0002ib-D2; Sun, 09 Dec 2018 21:55:30 +0000 Received: from ben by deadeye with local (Exim 4.91) (envelope-from ) id 1gW72j-0003c6-ID; Sun, 09 Dec 2018 21:55:17 +0000 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, "Herbert Xu" , "Leonard Crestez" Date: Sun, 09 Dec 2018 21:50:33 +0000 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) X-Patchwork-Hint: ignore Subject: [PATCH 3.16 271/328] crypto: mxs-dcp - Fix wait logic on chan threads In-Reply-To: X-SA-Exim-Connect-IP: 81.174.156.145 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.16.62-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Leonard Crestez commit d80771c08363ad7fbf0f56f5301e7ca65065c582 upstream. 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. Signed-off-by: Leonard Crestez Signed-off-by: Herbert Xu Signed-off-by: Ben Hutchings --- drivers/crypto/mxs-dcp.c | 53 +++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 23 deletions(-) --- a/drivers/crypto/mxs-dcp.c +++ b/drivers/crypto/mxs-dcp.c @@ -63,7 +63,7 @@ struct dcp { struct dcp_coherent_block *coh; struct completion completion[DCP_MAX_CHANS]; - struct mutex mutex[DCP_MAX_CHANS]; + spinlock_t lock[DCP_MAX_CHANS]; struct task_struct *thread[DCP_MAX_CHANS]; struct crypto_queue queue[DCP_MAX_CHANS]; }; @@ -349,13 +349,20 @@ static int dcp_chan_thread_aes(void *dat int ret; - do { - __set_current_state(TASK_INTERRUPTIBLE); + while (!kthread_should_stop()) { + set_current_state(TASK_INTERRUPTIBLE); - mutex_lock(&sdcp->mutex[chan]); + spin_lock(&sdcp->lock[chan]); backlog = crypto_get_backlog(&sdcp->queue[chan]); arq = crypto_dequeue_request(&sdcp->queue[chan]); - mutex_unlock(&sdcp->mutex[chan]); + spin_unlock(&sdcp->lock[chan]); + + if (!backlog && !arq) { + schedule(); + continue; + } + + set_current_state(TASK_RUNNING); if (backlog) backlog->complete(backlog, -EINPROGRESS); @@ -363,11 +370,8 @@ static int dcp_chan_thread_aes(void *dat if (arq) { ret = mxs_dcp_aes_block_crypt(arq); arq->complete(arq, ret); - continue; } - - schedule(); - } while (!kthread_should_stop()); + } return 0; } @@ -407,9 +411,9 @@ static int mxs_dcp_aes_enqueue(struct ab rctx->ecb = ecb; actx->chan = DCP_CHAN_CRYPTO; - mutex_lock(&sdcp->mutex[actx->chan]); + spin_lock(&sdcp->lock[actx->chan]); ret = crypto_enqueue_request(&sdcp->queue[actx->chan], &req->base); - mutex_unlock(&sdcp->mutex[actx->chan]); + spin_unlock(&sdcp->lock[actx->chan]); wake_up_process(sdcp->thread[actx->chan]); @@ -645,13 +649,20 @@ static int dcp_chan_thread_sha(void *dat struct ahash_request *req; int ret, fini; - do { - __set_current_state(TASK_INTERRUPTIBLE); + while (!kthread_should_stop()) { + set_current_state(TASK_INTERRUPTIBLE); - mutex_lock(&sdcp->mutex[chan]); + spin_lock(&sdcp->lock[chan]); backlog = crypto_get_backlog(&sdcp->queue[chan]); arq = crypto_dequeue_request(&sdcp->queue[chan]); - mutex_unlock(&sdcp->mutex[chan]); + spin_unlock(&sdcp->lock[chan]); + + if (!backlog && !arq) { + schedule(); + continue; + } + + set_current_state(TASK_RUNNING); if (backlog) backlog->complete(backlog, -EINPROGRESS); @@ -663,12 +674,8 @@ static int dcp_chan_thread_sha(void *dat ret = dcp_sha_req_to_buf(arq); fini = rctx->fini; arq->complete(arq, ret); - if (!fini) - continue; } - - schedule(); - } while (!kthread_should_stop()); + } return 0; } @@ -726,9 +733,9 @@ static int dcp_sha_update_fx(struct ahas rctx->init = 1; } - mutex_lock(&sdcp->mutex[actx->chan]); + spin_lock(&sdcp->lock[actx->chan]); ret = crypto_enqueue_request(&sdcp->queue[actx->chan], &req->base); - mutex_unlock(&sdcp->mutex[actx->chan]); + spin_unlock(&sdcp->lock[actx->chan]); wake_up_process(sdcp->thread[actx->chan]); mutex_unlock(&actx->mutex); @@ -984,7 +991,7 @@ static int mxs_dcp_probe(struct platform platform_set_drvdata(pdev, sdcp); for (i = 0; i < DCP_MAX_CHANS; i++) { - mutex_init(&sdcp->mutex[i]); + spin_lock_init(&sdcp->lock[i]); init_completion(&sdcp->completion[i]); crypto_init_queue(&sdcp->queue[i], 50); }