近期在调试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
;

return
addr
+
size -
<= *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中报错。

DMA32映射问题的更多相关文章

  1. kmalloc分配物理内存与高端内存映射--Linux内存管理(十八)

    1 前景回顾 1.1 内核映射区 尽管vmalloc函数族可用于从高端内存域向内核映射页帧(这些在内核空间中通常是无法直接看到的), 但这并不是这些函数的实际用途. 重要的是强调以下事实 : 内核提供 ...

  2. Hibernatel框架关联映射

    Hibernatel框架关联映射 Hibernate程序执行流程: 1.集合映射 需求:网络购物时,用户购买商品,填写地址 每个用户会有不确定的地址数目,或者只有一个或者有很多.这个时候不能把每条地址 ...

  3. hibernate多对多关联映射

    关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...

  4. Dapper逆天入门~强类型,动态类型,多映射,多返回值,增删改查+存储过程+事物案例演示

    Dapper的牛逼就不扯蛋了,答应群友做个入门Demo的,现有园友需要,那么公开分享一下: 完整Demo:http://pan.baidu.com/s/1i3TcEzj 注 意 事 项:http:// ...

  5. ElasticSearch 5学习(9)——映射和分析(string类型废弃)

    在ElasticSearch中,存入文档的内容类似于传统数据每个字段一样,都会有一个指定的属性,为了能够把日期字段处理成日期,把数字字段处理成数字,把字符串字段处理成字符串值,Elasticsearc ...

  6. .NET平台开源项目速览(14)最快的对象映射组件Tiny Mapper

    好久没有写文章,工作甚忙,但每日还是关注.NET领域的开源项目.五一休息,放松了一下之后,今天就给大家介绍一个轻量级的对象映射工具Tiny Mapper:号称是.NET平台最快的对象映射组件.那就一起 ...

  7. ASP.NET Core的路由[1]:注册URL模式与HttpHandler的映射关系

    ASP.NET Core的路由是通过一个类型为RouterMiddleware的中间件来实现的.如果我们将最终处理HTTP请求的组件称为HttpHandler,那么RouterMiddleware中间 ...

  8. mybatis_映射查询

    一.一对一映射查询: 第一种方式(手动映射):借助resultType属性,定义专门的pojo类作为输出类型,其中该po类中封装了查询结果集中所有的字段.此方法较为简单,企业中使用普遍. <!- ...

  9. 问题记录:EntityFramework 一对一关系映射

    EntityFramework 一对一关系映射有很多种,比如主键作为关联,配置比较简单,示例代码: public class Teacher { public int Id { get; set; } ...

随机推荐

  1. matlab化简符号表达式

    化简符号表达式计算机毕竟还是挺笨的, 经过一系列的符号计算后, 得到的结果可能只有它自己才能看懂, Matlab提供大量函数以用于符号表达式的化简. collect(f): 函数用途是合并多项式中相同 ...

  2. 【转】用jquery编写动态的返回顶部特效

    jquery代码: function gotoTop(min_height){ //预定义返回顶部的html代码,它的css样式默认为不显示 var gotoTop_html = '<div i ...

  3. mysql字符集乱码问题

    程序错误截图如下: 分析:我们mysql数据库没有设置默认编码, 导致创建的库字符集为 latin1,然而我们创建表的时候,指定字符集为其他的,比如utf8 我的解决思路:把数据库的编码修改为utf8 ...

  4. MRC转ARC(2)

    春节前抽空花了一天的时间将手头的工程从MRC转成了ARC,然后陆陆续续地修复一部分因为转ARC引起的内存泄漏和崩溃,到目前为止工程也算是比较稳定了,抽空记上一笔.(虽说这种事情这辈子估计都只会做这么一 ...

  5. (C/C++学习)17.bitset(位操作)

    说明:bitset 就像 vector 一样,是 C++ 的一个类模板库,用来对一个数的二进制位进行管理.判断等操作,使用时需要包含头文件 #include<bitset>. 1.声明及定 ...

  6. [Python3网络爬虫开发实战] 1.8.2-Scrapy的安装

    Scrapy是一个十分强大的爬虫框架,依赖的库比较多,至少需要依赖的库有Twisted 14.0.lxml 3.4和pyOpenSSL 0.14.在不同的平台环境下,它所依赖的库也各不相同,所以在安装 ...

  7. [Python3网络爬虫开发实战] 1.2.4-GeckoDriver的安装

    上一节中,我们了解了ChromeDriver的配置方法,配置完成之后便可以用Selenium驱动Chrome浏览器来做相应网页的抓取. 那么对于Firefox来说,也可以使用同样的方式完成Seleni ...

  8. 【转】WinAPI: CreateFontIndirect - 根据字体结构建立逻辑字体

    //声明: CreateFontIndirect( const p1: TLogFont {字体结构} ): HFONT; {返回新字体指针} //TLogFont 是 tagLOGFONTA 结构的 ...

  9. 树莓派 -- 输入设备驱动 (key) 续1

    测试 安装 input-utils pi@raspberrypi:~ $ sudo apt-get install input-utils Reading package lists... Done ...

  10. 18Spring后置通知

    Spring后置通知,和前置通知类似,直接看代码: package com.cn.spring.aop.impl; //加减乘除的接口类 public interface ArithmeticCalc ...