mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 02:50:49 +09:00
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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user