DMA超时的原因是什么?

时间:2018-04-10 10:05:14

标签: linux-kernel dma

我在尝试分配DMA内存区域时发现超时。虽然我可以通过使用GFP_ATOMIC而不是GFP_KERNEL als gfp标志来删除此错误,以便DMA分配变得不可中断,我想知道发生这种超时的原因是什么?系统总线不知道请求的内存区域?公共汽车已经饱和了吗?

[   87.400000] [<c0138eec>] (schedule_bug) from [<c05a0774>] (schedule+0x3c/0x528)
[   87.410000] [<c05a0774>] (__schedule) from [<c05a0d0c>] (schedule+0xac/0xcc)
[   87.410000] [<c05a0d0c>] (schedule) from [<c05a3e20>] (schedule_timeout+0x20/0x2b8)
[   87.420000] [<c05a3e20>] (schedule_timeout) from [<c05a1804>] (wait_for_common+0xf8/0x1a8)
[   87.430000] [<c05a1804>] (wait_for_common) from [<c012c540>] (flush_work+0x174/0x1ac)
[   87.450000] [<c012c540>] (flush_work) from [<c01a0648>] (drain_all_pages+0x108/0x130)
[   87.460000] [<c01a0648>] (drain_all_pages) from [<c01d6d34>] (start_isolate_page_range+0xbc/0x284)
[   87.470000] [<c01d6d34>] (start_isolate_page_range) from [<c01a3310>] (alloc_contig_range+0xdc/0x330)
[   87.480000] [<c01a3310>] (alloc_contig_range) from [<c01d7658>] (cma_alloc+0x170/0x308)
[   87.490000] [<c01d7658>] (cma_alloc) from [<c011142c>] (__alloc_from_contiguous+0x40/0xd8)
[   87.500000] [<c011142c>] (__alloc_from_contiguous) from    [<c0111500>] (cma_allocator_alloc+0x3c/0x44)
[   87.510000] [<c0111500>] (cma_allocator_alloc) from [<c010f86c>] (__dma_alloc+0x1d4/0x2fc)
[   87.520000] [<c010f86c>] (__dma_alloc) from [<c010fa0c>] (arm_dma_alloc+0x3c/0x48)
[   87.530000] [<c010fa0c>] (arm_dma_alloc) from [<c03ae018>] (tsg_ioctl+0x3e4/0x954)

1 个答案:

答案 0 :(得分:1)

最有可能的原因是你从原子上下文中调用了具有睡眠能力的函数(arm_dma_alloc),禁止睡眠。您可能在spin_lock下进行此分配。 spin_lock调用preempt_disable,这意味着无法重新安排。这就是spin_lock的工作原理。无论如何,如果你将在spin_lock / spin_unlock内调用sleep原语并重新安排,内核调度程序子系统将警告你,你已经在原子上下文中重新安排了(这是你在这条消息中看到的)。