博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
DMA32映射问题
阅读量:6458 次
发布时间:2019-06-23

本文共 1775 字,大约阅读时间需要 5 分钟。

近期在调试PCIe的行情加速卡的驱动。当中使用DMA在CPU和FPGA间数据传输。

最開始使用的是低16M的DMA ZONE的内存,用slab分配器的kmalloc分配获取。但因为最新的需求,须要使用的内存远远超过16M,这样再使用DMA ZONE区域的内存就不够了,那就仅仅能使用DMA32区域的内存来进行DMA传输了。

在我使用的调试机器上。DMA32区域的内存情况例如以下:

由上图可知DMA32 ZONE为16M~4G,高于4G的内存为Normal ZONE。

假设使用DMA32 ZONE的内存,不可以使用slab分配器,否则会panic。

__cache_allocàcache_alloc_refillàcache_grow函数:

BUG_ON(flags & GFP_SLAB_BUG_MASK);

假设设置了GFP_SLAB_BUG_MASK标志,那么就会直接bug_on。GFP_SLAB_BUG_MASK标志的定义例如以下:

/* Do not use these with a slab allocator */  

 #define GFP_SLAB_BUG_MASK (__GFP_DMA32|__GFP_HIGHMEM|~__GFP_BITS_MASK)

由于我们须要设置__GFP_DMA32标志,因此在使用DMA32ZONE的内存时候,不能使用slab分配器来分配内存。

因此使用buddy分配器来分配DMA32ZONE的内存供DMA传输使用。这个时候须要注意一个问题:我们的设置是否可以在DMA32 ZONE分配的内存上运行DMA?

之前使用的低16M的DMA ZONE的内存,设置的设备的寻址能力为24bit,如今使用的是16M~4G的DMA32 ZONE,设备须要能在32位地址上运行DMA,调用dma_set_mask设置32bit的寻址能力。

假设不设置32bit的寻址能力,那么在流式DMA映射的时候就会报错。报错是swiotlb_full函数打印出来的。

printk(KERN_ERR "DMA: Out of SW-IOMMU space for %zu bytes at "

        "device %s\n", size, dev ?

dev_name(dev) : "?");  

以下分析下DMA映射的相关代码swiotlb_map_page函数实现:

/* 

   * If the address happens to be in the device's DMA window, 

   * we can safely return the device addr and not worry about bounce 

   * buffering it. 

   */             

 if (dma_capable(dev, dev_addr, size) && !swiotlb_force)  

       return dev_addr;  

此函数中首先调用dma_capable函数检查映射的地址范围是否在设备同意的寻址能力范围内。

static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)

{  

      if (!dev->dma_mask)  

             return 0;  

  

      return addr + size - 1 <= *dev->dma_mask;  

}  

此函数首先检查有没有设置设备的寻址掩码。调用dma_set_mask函数底层实现就是设置*dev->dma_mask = mask。假设设置DMA_BIT_MASK(32),那么mask就是0xffffffff。不论什么4G范围内的地址在此检查条件下都能通过。

假设设置的寻址能力为24bit,那么mask就是0xffffff。那么假设从DMA32分配的地址大于此掩码范围,检查就不通过,那么swiotlb_map_page函数就会接着往下运行map_singleàswiotlb_tbl_map_single,并极有可能返回SWIOTLB_MAP_ERROR,进而swiotlb_full中报错。

转载于:https://www.cnblogs.com/clnchanpin/p/7136456.html

你可能感兴趣的文章
锚点盒子随滚动条浮动
查看>>
T4 生成指定DB表实体
查看>>
ASP.NET网站运行常见错误以及解决方法(持续更新)
查看>>
在Visio里加上、下标方法
查看>>
C/C++经典面试题
查看>>
【Python】安装配置Anaconda
查看>>
rem布局下使用背景图片和sprite图
查看>>
团队作业7——第二次项目冲刺(Beta版本)-第一篇
查看>>
iOS - 常用本机URL跳转设置
查看>>
Linux C多线程编程
查看>>
Word2Vec中文语料实战
查看>>
4.5Python数据处理篇之Matplotlib系列(五)---plt.pie()饼状图
查看>>
D3.js v4版本 按住shift键框选节点demo
查看>>
Unity IOC简单认知
查看>>
DIV+CSS规范命名大全集合
查看>>
php ZeroMQ 的使用
查看>>
Codewar python训练题全记录——持续更新
查看>>
Java运行报错问题——Picked up JAVA_TOOL_OPTIONS: -agentlib:jvmhook
查看>>
(二)Struts.xml文件详解
查看>>
转:SQL注入攻击的原理
查看>>