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 <sugar.zhang@rock-chips.com>
Change-Id: I5ad862db58262fb9ec39bbfe273dcb0215bb1c9d
This commit is contained in:
Sugar Zhang
2024-11-22 14:23:28 +08:00
parent 0f41390f2f
commit 465e356900

View File

@@ -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);