diff mbox series

[1/5] crypto: atmel-{aes,sha} - Fix incorrect use of dmaengine_terminate_all()

Message ID 20191213095423.6687-1-tudor.ambarus@microchip.com (mailing list archive)
State Accepted
Delegated to: Herbert Xu
Headers show
Series [1/5] crypto: atmel-{aes,sha} - Fix incorrect use of dmaengine_terminate_all() | expand

Commit Message

Tudor Ambarus Dec. 13, 2019, 9:54 a.m. UTC
From: Tudor Ambarus <tudor.ambarus@microchip.com>

device_terminate_all() is used to abort all the pending and
ongoing transfers on the channel, it should be used just in the
error path.

Also, dmaengine_terminate_all() is deprecated and one should use
dmaengine_terminate_async() or dmaengine_terminate_sync(). The method
is not used in atomic context, use dmaengine_terminate_sync().

A secondary aspect of this patch is that it luckily avoids a deadlock
between atmel_aes and at_hdmac.c. While in tasklet with the lock held,
the dma controller invokes the client callback (dmaengine_terminate_all),
which tries to get the same lock. The at_hdmac fix would be to drop the
lock before invoking the client callback, a fix on at_hdmac will follow.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/crypto/atmel-aes.c | 32 ++------------------------------
 drivers/crypto/atmel-sha.c |  1 -
 2 files changed, 2 insertions(+), 31 deletions(-)

Comments

Herbert Xu Dec. 20, 2019, 7:07 a.m. UTC | #1
On Fri, Dec 13, 2019 at 09:54:42AM +0000, Tudor.Ambarus@microchip.com wrote:
> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> device_terminate_all() is used to abort all the pending and
> ongoing transfers on the channel, it should be used just in the
> error path.
> 
> Also, dmaengine_terminate_all() is deprecated and one should use
> dmaengine_terminate_async() or dmaengine_terminate_sync(). The method
> is not used in atomic context, use dmaengine_terminate_sync().
> 
> A secondary aspect of this patch is that it luckily avoids a deadlock
> between atmel_aes and at_hdmac.c. While in tasklet with the lock held,
> the dma controller invokes the client callback (dmaengine_terminate_all),
> which tries to get the same lock. The at_hdmac fix would be to drop the
> lock before invoking the client callback, a fix on at_hdmac will follow.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> ---
>  drivers/crypto/atmel-aes.c | 32 ++------------------------------
>  drivers/crypto/atmel-sha.c |  1 -
>  2 files changed, 2 insertions(+), 31 deletions(-)

All applied.  Thanks.
diff mbox series

Patch

diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c
index 47b20df3adfc..c3f0e99d24b0 100644
--- a/drivers/crypto/atmel-aes.c
+++ b/drivers/crypto/atmel-aes.c
@@ -857,27 +857,6 @@  static int atmel_aes_dma_transfer_start(struct atmel_aes_dev *dd,
 	return 0;
 }
 
-static void atmel_aes_dma_transfer_stop(struct atmel_aes_dev *dd,
-					enum dma_transfer_direction dir)
-{
-	struct atmel_aes_dma *dma;
-
-	switch (dir) {
-	case DMA_MEM_TO_DEV:
-		dma = &dd->src;
-		break;
-
-	case DMA_DEV_TO_MEM:
-		dma = &dd->dst;
-		break;
-
-	default:
-		return;
-	}
-
-	dmaengine_terminate_all(dma->chan);
-}
-
 static int atmel_aes_dma_start(struct atmel_aes_dev *dd,
 			       struct scatterlist *src,
 			       struct scatterlist *dst,
@@ -936,25 +915,18 @@  static int atmel_aes_dma_start(struct atmel_aes_dev *dd,
 	return -EINPROGRESS;
 
 output_transfer_stop:
-	atmel_aes_dma_transfer_stop(dd, DMA_DEV_TO_MEM);
+	dmaengine_terminate_sync(dd->dst.chan);
 unmap:
 	atmel_aes_unmap(dd);
 exit:
 	return atmel_aes_complete(dd, err);
 }
 
-static void atmel_aes_dma_stop(struct atmel_aes_dev *dd)
-{
-	atmel_aes_dma_transfer_stop(dd, DMA_MEM_TO_DEV);
-	atmel_aes_dma_transfer_stop(dd, DMA_DEV_TO_MEM);
-	atmel_aes_unmap(dd);
-}
-
 static void atmel_aes_dma_callback(void *data)
 {
 	struct atmel_aes_dev *dd = data;
 
-	atmel_aes_dma_stop(dd);
+	atmel_aes_unmap(dd);
 	dd->is_async = true;
 	(void)dd->resume(dd);
 }
diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c
index ebf500153700..7cf4ec9ed93a 100644
--- a/drivers/crypto/atmel-sha.c
+++ b/drivers/crypto/atmel-sha.c
@@ -1429,7 +1429,6 @@  static void atmel_sha_dma_callback2(void *data)
 	struct scatterlist *sg;
 	int nents;
 
-	dmaengine_terminate_all(dma->chan);
 	dma_unmap_sg(dd->dev, dma->sg, dma->nents, DMA_TO_DEVICE);
 
 	sg = dma->sg;