From 465e3569003eaab009605ffc93262a6607fc73f0 Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Fri, 22 Nov 2024 14:23:28 +0800 Subject: [PATCH] dmaengine: pl330: Fix desc_pool list-add corruption list_add corruption. prev->next should be next (ffffff8102792618), but was ffffff8102af00a8. (prev=ffffff8101640460). kernel BUG at lib/list_debug.c:28! Internal error: Oops - BUG: 0 [#1] PREEMPT SMP Modules linked in: bcmdhd dhd_static_buf tiot_driver r8168 CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.10.66-abeng..20241011.190040 #1 Hardware name: Rockchip RK3588S TABLET SU30PRO SSD V12 Board (DT) pstate: 60400089 (nZCv daIf +PAN -UAO -TCO BTYPE=--) pc : __list_add_valid+0x94/0x98 lr : __list_add_valid+0x94/0x98 sp : ffffffc01261bdf0 x29: ffffffc01261bdf0 x28: ffffffc0109f01c0 x27: ffffff8102af14e0 x26: 0000000000000000 x25: ffffff8102792618 x24: ffffff8101640460 x23: ffffff8102f66800 x22: ffffff8101640a80 x21: 0000000000000000 x20: ffffff8102af1428 x19: ffffff8102792480 x18: ffffffc012611048 x17: 0000000000000000 x16: 00000000000000d8 x15: 0000000000000004 x14: 0000000000002d18 x13: ffffffc012060018 x12: 0000000000000003 x11: 0000000100042d18 x10: 0000000000000000 x9 : 9df2689215223100 x8 : 9df2689215223100 x7 : 5f78783338387761 x6 : ffffffc01226f350 x5 : ffffffffffffffff x4 : 0000000000000000 x3 : ffffffc011d08caf x2 : ffffff84f1d098c8 x1 : 0000000000000000 x0 : 0000000000000075 Call trace: __list_add_valid+0x94/0x98 pl330_tasklet+0x204/0x2c4 tasklet_action_common+0x11c/0x414 tasklet_action+0x28/0x38 _stext+0x108/0x408 __irq_exit_rcu+0xc0/0xc4 irq_exit+0x14/0x28 __handle_domain_irq+0x84/0xd0 gic_handle_irq+0x78/0x154 el1_irq+0xe4/0x1c0 cpuidle_enter_state+0x180/0x3b8 cpuidle_enter+0x3c/0x58 cpuidle_idle_call+0x158/0x238 do_idle+0xac/0xfc cpu_startup_entry+0x28/0x2c rest_init+0xd8/0xec arch_call_rest_init+0x14/0x24 start_kernel+0x3d8/0x500 Signed-off-by: Sugar Zhang Change-Id: I5ad862db58262fb9ec39bbfe273dcb0215bb1c9d --- drivers/dma/pl330.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index a796ffcafb42..31b8ed6c31ca 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -1739,7 +1739,9 @@ static int pl330_submit_req(struct pl330_thread *thrd, if (!desc->last) { desc->status = FREE; + spin_lock(&pl330->pool_lock); list_move_tail(&desc->node, &pl330->desc_pool); + spin_unlock(&pl330->pool_lock); dev_dbg(pl330->ddma.dev, "desc-%px has been merged, drop it\n", desc); } @@ -2324,7 +2326,10 @@ static void pl330_tasklet(struct tasklet_struct *t) dmaengine_desc_get_callback(&desc->txd, &cb); desc->status = FREE; + + spin_lock(&pch->dmac->pool_lock); list_move_tail(&desc->node, &pch->dmac->desc_pool); + spin_unlock(&pch->dmac->pool_lock); dma_descriptor_unmap(&desc->txd); @@ -2542,9 +2547,12 @@ static int pl330_terminate_all(struct dma_chan *chan) dma_cookie_complete(&desc->txd); } + spin_lock(&pl330->pool_lock); list_splice_tail_init(&pch->submitted_list, &pl330->desc_pool); list_splice_tail_init(&pch->work_list, &pl330->desc_pool); list_splice_tail_init(&pch->completed_list, &pl330->desc_pool); + spin_unlock(&pl330->pool_lock); + spin_unlock_irqrestore(&pch->lock, flags); pm_runtime_mark_last_busy(pl330->ddma.dev); if (power_down) @@ -2600,7 +2608,9 @@ static void pl330_free_chan_resources(struct dma_chan *chan) pl330_release_channel(pch->thread); pch->thread = NULL; + spin_lock(&pl330->pool_lock); list_splice_tail_init(&pch->work_list, &pch->dmac->desc_pool); + spin_unlock(&pl330->pool_lock); spin_unlock_irqrestore(&pl330->lock, flags); pm_runtime_mark_last_busy(pch->dmac->ddma.dev);