【问题标题】:dma_alloc_coherent failed on x86_64 but works on i686dma_alloc_coherent 在 x86_64 上失败,但在 i686 上有效
【发布时间】:2016-02-15 15:16:38
【问题描述】:

我有一个 pci 设备驱动程序,它使用 CMA 分配机制进行 DMA 分配。它在 32 位模式下的内核 3.18 上运行良好,但是当我尝试在 64 位内核中使用它时(与 32 位相同的配置,但打开了 64 位模式)dma 分配失败。

我在 dmesg 中看到的唯一内容是:

 fallback device: swiotlb buffer is full (sz: 8388608 bytes)

我使用内核命令行:

swiotlb=16384 iommu=soft cma=256M

并分配 8Mb。

函数调用是:

new_region->kaddr = dma_alloc_coherent( NULL, size, &new_region->paddr, GFP_KERNEL | GFP_DMA32 );

有人可以在 64 位模式下解释这种行为吗?

【问题讨论】:

  • 查看this提交的提交信息。也许您的问题是那里描述的案例之一?
  • 感谢您的回答。我已经找到了这种代码的平静并在它周围玩耍。似乎分配的最大块大小有一些限制,但我仍然无法弄清楚差异在哪里。

标签: linux-kernel driver x86-64 dma


【解决方案1】:

经过更多的调查,我想你可能和我有同样的原因,把它列出来供你参考。 CMA 分配将从最高的内存块开始,所以如果你有超过 3G 的内存,最后的物理内存将在 0xFFFFFFFF 以上,这意味着 CMA 的基地址在 4GB 以上,但是 dma_allocat_coherent() 要求地址低于掩码[(0x1

为了解决这个问题,我们可以指定cma起始地址、大小和限制大小来手动控制CMA保留位置。

e820: BIOS-provided physical RAM map:
BIOS-e820: [mem 0x0000000000000000-0x000000000009ffff] usable
BIOS-e820: [mem 0x00000000000a0000-0x00000000000fffff] reserved
BIOS-e820: [mem 0x0000000000100000-0x00000000779c4fff] usable
BIOS-e820: [mem 0x00000000779c5000-0x0000000077a45fff] reserved
BIOS-e820: [mem 0x0000000077a46000-0x0000000079426fff] usable
BIOS-e820: [mem 0x0000000079427000-0x000000007b32efff] reserved
BIOS-e820: [mem 0x000000007b32f000-0x000000007b985fff] ACPI NVS
BIOS-e820: [mem 0x000000007b986000-0x000000007bad3fff] ACPI data
BIOS-e820: [mem 0x000000007bad4000-0x000000007bafffff] usable
BIOS-e820: [mem 0x000000007bb00000-0x000000008fffffff] reserved
BIOS-e820: [mem 0x00000000fed1c000-0x00000000fed1ffff] reserved
BIOS-e820: [mem 0x0000000100000000-0x000000017fffffff] usable

cma=nn[MG]@[start[MG][-end[MG]]]
            [ARM,X86,KNL]
            Sets the size of kernel global memory area for
            contiguous memory allocations and optionally the
            placement constraint by the physical address range of
            memory allocations. A value of 0 disables CMA
            altogether. For more information, see
            include/linux/dma-contiguous.h

首先为您提供解决方法,请在您的内核中添加“mem=3072M” 命令行。然后它将适用于您的情况。你看到的原因 这可能与传递给函数的 NULL 有关 dma_alloc_coherent()。默认情况下,它将使用 x86_dma_fallback_dev。 一旦我获得更多信息,将更新更多信息。

【讨论】:

  • 丰博给出了正确的理由,但适当的解决方案是指定CMA区域的范围或结束地址在4GB以下。例如,您可能需要cma=8M@0-4G 引导参数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-01
  • 2016-01-26
  • 1970-01-01
  • 1970-01-01
  • 2020-01-20
  • 2017-09-22
  • 1970-01-01
相关资源
最近更新 更多