【问题标题】:ensure the DMA -capable memory确保具有 DMA 功能的内存
【发布时间】:2015-08-11 18:58:42
【问题描述】:

我正在阅读以下document 的“部分 ID”部分,例如,我不确定该文档与内核 2.6.35 的相关性如何;特别是它说:

..the DMA address of the memory must be within the dma_mask of the device..

他们建议将某些标志(例如 GFP_DMA)传递给 kmalloc,以确保内存将落在提供的 DMA 掩码内。

但是,如果内存是从kmem_cache_create 创建的缓存池中分配的,并且使用kmem_cache_alloc(.. GFP_ATOMIC),这不符合 DMA-API.txt 中列出的要求?

另一方面,LDD 谈到 __GFP_DMA 标志与旧 ISA 设备有关,因此我不确定这是否适用于 PCI/PCIe 设备。

如果重要的话,这是 x86 64 位平台:

pci_set_dma_mask(dev, 0xffffffffffffffffULL);
pci_set_consistent_dma_mask(dev, 0xffffffffffffffffULL);

我希望能听到一些关于它的解释。

【问题讨论】:

    标签: linux-kernel x86 linux-device-driver dma


    【解决方案1】:
    1. 对于 GFP_* 对于 DMA

      在 x86 上:

      • ISA - 使用kmalloc() 时需要按位或GFP_DMAGFP_KERNEL(或_ATOMIC),原因如下:

        GFP_DMA 保证:

        (1)get_free_page返回多页且物理地址连续

        (2) 仅返回低于MAX_DMA_ADDRESS 的地址。由于 ISA 限制,MAX_DMA_ADDRESS 在 PC 上为 16MB

      • PCI - 不需要使用GFP_DMA,因为没有MAX_DMA_ADDRESS 限制

    2. 在调用dma_map_*dma_alloc_coherent 时,设备会检查dma_mask

      dma_alloc_coherent 确保分配的内存能够被dma_map_* 使用,这也带来了其他好处。 (实现可以选择忽略影响返回内存位置的标志,例如 GFP_DMA)

    可以参考http://coweb.cc.gatech.edu/sysHackfest/uploads/58/DMA_howto.1.txt

    【讨论】:

    • 谢谢。我在kernel.org/doc/Documentation/DMA-API.txt 中读到的另一个要求是“建议驱动程序编写者映射在页面边界上开始和结束的虚拟区域”。什么内核 API 保证以页面为单位进行分配?这 kmem_alloc_cache 好吗?
    • __get_free_page()__get_free_pages() 是你想要的。 kmem_alloc_cache 不保证给你一整页。
    • 分配页面的更多内核API可以参考/mm/page_alloc.c
    • 您可以将SLAB_HWCACHE_ALIGN 标志传递给kmem_cache_create 以确保您从kmem_cache_alloc 获得的所有内存都是缓存行对齐的。 kmalloc 也做类似的事情。所以kmalloc也可以保证内存是cache line对齐的。
    • 它在内部分配 1+ 个连续的 ,称为 slabs。但是您不能通过调用kmem_cache_* 直接获得平板。相反,kmem_cache_alloc 返回给你的内存大小是你在它之前给kmem_cache_createsize
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多