Skip to content

Commit abb863e

Browse files
claudiubezneavinodkoul
authored andcommitted
dmaengine: sh: rz-dmac: Protect the driver specific lists
The driver lists (ld_free, ld_queue) are used in rz_dmac_free_chan_resources(), rz_dmac_terminate_all(), rz_dmac_issue_pending(), and rz_dmac_irq_handler_thread(), all under the virtual channel lock. Take the same lock in rz_dmac_prep_slave_sg() and rz_dmac_prep_dma_memcpy() as well to avoid concurrency issues, since these functions also check whether the lists are empty and update or remove list entries. Fixes: 5000d37 ("dmaengine: sh: Add DMAC driver for RZ/G2L SoC") Cc: [email protected] Reviewed-by: Frank Li <[email protected]> Signed-off-by: Claudiu Beznea <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent e1c9866 commit abb863e

1 file changed

Lines changed: 32 additions & 25 deletions

File tree

drivers/dma/sh/rz-dmac.c

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
*/
1111

1212
#include <linux/bitfield.h>
13+
#include <linux/cleanup.h>
1314
#include <linux/dma-mapping.h>
1415
#include <linux/dmaengine.h>
1516
#include <linux/interrupt.h>
@@ -447,6 +448,7 @@ static int rz_dmac_alloc_chan_resources(struct dma_chan *chan)
447448
if (!desc)
448449
break;
449450

451+
/* No need to lock. This is called only for the 1st client. */
450452
list_add_tail(&desc->node, &channel->ld_free);
451453
channel->descs_allocated++;
452454
}
@@ -502,18 +504,21 @@ rz_dmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
502504
dev_dbg(dmac->dev, "%s channel: %d src=0x%pad dst=0x%pad len=%zu\n",
503505
__func__, channel->index, &src, &dest, len);
504506

505-
if (list_empty(&channel->ld_free))
506-
return NULL;
507+
scoped_guard(spinlock_irqsave, &channel->vc.lock) {
508+
if (list_empty(&channel->ld_free))
509+
return NULL;
510+
511+
desc = list_first_entry(&channel->ld_free, struct rz_dmac_desc, node);
507512

508-
desc = list_first_entry(&channel->ld_free, struct rz_dmac_desc, node);
513+
desc->type = RZ_DMAC_DESC_MEMCPY;
514+
desc->src = src;
515+
desc->dest = dest;
516+
desc->len = len;
517+
desc->direction = DMA_MEM_TO_MEM;
509518

510-
desc->type = RZ_DMAC_DESC_MEMCPY;
511-
desc->src = src;
512-
desc->dest = dest;
513-
desc->len = len;
514-
desc->direction = DMA_MEM_TO_MEM;
519+
list_move_tail(channel->ld_free.next, &channel->ld_queue);
520+
}
515521

516-
list_move_tail(channel->ld_free.next, &channel->ld_queue);
517522
return vchan_tx_prep(&channel->vc, &desc->vd, flags);
518523
}
519524

@@ -529,27 +534,29 @@ rz_dmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
529534
int dma_length = 0;
530535
int i = 0;
531536

532-
if (list_empty(&channel->ld_free))
533-
return NULL;
537+
scoped_guard(spinlock_irqsave, &channel->vc.lock) {
538+
if (list_empty(&channel->ld_free))
539+
return NULL;
534540

535-
desc = list_first_entry(&channel->ld_free, struct rz_dmac_desc, node);
541+
desc = list_first_entry(&channel->ld_free, struct rz_dmac_desc, node);
536542

537-
for_each_sg(sgl, sg, sg_len, i) {
538-
dma_length += sg_dma_len(sg);
539-
}
543+
for_each_sg(sgl, sg, sg_len, i)
544+
dma_length += sg_dma_len(sg);
540545

541-
desc->type = RZ_DMAC_DESC_SLAVE_SG;
542-
desc->sg = sgl;
543-
desc->sgcount = sg_len;
544-
desc->len = dma_length;
545-
desc->direction = direction;
546+
desc->type = RZ_DMAC_DESC_SLAVE_SG;
547+
desc->sg = sgl;
548+
desc->sgcount = sg_len;
549+
desc->len = dma_length;
550+
desc->direction = direction;
546551

547-
if (direction == DMA_DEV_TO_MEM)
548-
desc->src = channel->src_per_address;
549-
else
550-
desc->dest = channel->dst_per_address;
552+
if (direction == DMA_DEV_TO_MEM)
553+
desc->src = channel->src_per_address;
554+
else
555+
desc->dest = channel->dst_per_address;
556+
557+
list_move_tail(channel->ld_free.next, &channel->ld_queue);
558+
}
551559

552-
list_move_tail(channel->ld_free.next, &channel->ld_queue);
553560
return vchan_tx_prep(&channel->vc, &desc->vd, flags);
554561
}
555562

0 commit comments

Comments
 (0)