IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

DMA设备驱动的常见问题

delphij's Chaos 2009-11-09 09:28:15 累计浏览 2,156 次
本机暂存

    DMA (Direct Memory Access) 是一种提高计算机系统并发能力的技术。简单地说,它允许外围设备以异步方式操作内存,从而减少了CPU在I/O操作中的参与。

    目前的微机和PC服务器都广泛采用了 DMA 技术。由于 DMA 是一种异步操作,因此在撰写驱动时,有很多需要注意的问题。

    第一类比较常见的问题是,并不是所有的 DMA 控制器或设备都有能力访问全部物理内存,或对访问有限制。例如,许多低端存储设备和网卡往往只能访问物理内存的前4GB,甚至更小的范围。而另一些设备可能只能同时访问同一段整4GB内存,例如,它可能只能访问物理地址为 0~4G-1,或4G~8G-1的内存,而不能同时访问两部分内存。还有一种比较常见的限制是设备只能按照整数次方幂边界来访问内存,例如它可能要求映射长度为4K的DMA起始地址为4K的整数倍,等等。

    这一类问题比较隐蔽。如果驱动程序没有考虑这些问题,导致的结果往往是在运行一段时间之后突然发现数据损坏等问题。如果硬件手册中没有特别指出硬件的限制,我们往往可以通过设计一些特别的用例来强制系统映射位于某些可能导致问题的边缘内存来发现这类问题。

    针对这些限制,操作系统往往提供了一些绕过限制的方法,例如比较常见的bouncing page,即在较低的物理内存地址进行DMA映射,然后由OS在DMA完成之后将这些数据复制到其他地方。这些方法都会导致性能下降,因此,对于希望承担高性能任务的系统而言,应尽量避免使用这样的硬件。

    第二类比较常见的问题是,驱动程序?PU)在不适当的时候读写内存。许多设备都支持主动发起DMA(Bus Mastering),这种时候,CPU可能没有办法知道设备是不是正在写内存。解决这种问题的方法是引入内存栅(Memory Barrier),即驱动程序在读写内存前后通知硬件自己将要执行的操作,并由硬件来确保相应的结果。例如,网卡驱动在读写映射环或映射链的时候,应在读前以及写前后分别进行内存栅操作,确保自己没有读到过期数据,并确保设备没有读到过期数据。

    这一类问题也非常隐蔽。对于负载不高的情形,很可能驱动程序的开发者不会注意到任何问题。甚至,对于负载较高的情形,这类问题会表现为响应慢而不是不稳定或数据损坏。

同分类推荐文章

  1. 等了十年的 Go 链式管道,终于来了:seq 让你像写 Scala 一样写 Go (2026-06-25 18:38:18)
  2. Go 实验特性详解 (2026-06-21 10:05:27)
  3. amd64 微架构级别对 Go 程序性能提升多少? (2026-06-21 09:38:49)

查看更多 后端 文章 →

建议继续学习

  1. Java开发岗位面试题归类汇总 (累计阅读 22,157)
  2. Linux内存点滴 用户进程内存空间 (累计阅读 13,232)
  3. Linux Used内存到底哪里去了? (累计阅读 11,868)
  4. Linux操作系统的内存使用方法详细解析 (累计阅读 10,151)
  5. 几个内存相关面试题(c/c++) (累计阅读 9,447)
  6. top 命令补充 ( VIRT RES SHR) (累计阅读 9,117)
  7. 高性能web服务器-读书笔记 (累计阅读 7,777)
  8. Innodb分表太多或者表分区太多,会导致内存耗尽而宕机 (累计阅读 7,720)
  9. redis 运维实际经验纪录之一 (累计阅读 7,712)
  10. 必看!linux系统如何查看内存使用情况 (累计阅读 7,170)