计算机体系结构 29:CPU 怎样与设备交换数据
计算机体系结构 29:CPU 怎样与设备交换数据
核心问题
设备完成一次 DMA 后,CPU 为什么还不能立刻把缓冲区当成普通内存读取?数据移动只是传输链路的一部分。驱动还要处理 DMA 地址映射、缓冲区所有权、完成通知和同步;IOMMU 则可能在设备地址与物理内存之间再加一层翻译和权限检查。
本篇只验证一条六状态协议,不连接真实设备,不产生总线事务,也不测中断延迟。附件:29-dma.json。
范围与证据等级
证据等级为功能执行。模型依次进入 cpu_owned、mapped_for_device、device_owned、completion_visible、synced_for_cpu、cpu_consumed。这些状态用于检查“谁此时可以访问缓冲区”,不能证明某个平台的 DMA 一致性实现,更不能称作真实设备传输。
Linux Dynamic DMA Mapping Guide 区分 CPU 虚拟地址、CPU 物理地址和设备使用的 DMA 地址。驱动应使用 DMA API 建立映射,不能把 CPU 指针直接交给设备。streaming mapping 的同步要求还取决于数据方向和平台一致性规则。
核心案例:完成通知早于 CPU 消费
描述符由 CPU 填好并映射,所有权随后交给设备。设备写完数据并报告 completion,只说明设备侧工作到达约定完成点;模型仍要求 synced_for_cpu,然后才允许 cpu_consumed。如果跳过同步状态,模型拒绝 CPU 消费。
MMIO doorbell、中断或轮询负责推进控制状态,DMA 负责搬运数据。两条路径可能由不同的互联和排序规则承载。驱动必须按设备与平台文档放置 barrier 和 DMA sync,不能用“中断已经到了”替代缓冲区可见性的证明。
模式:数据通路与所有权通路分开记账
1 | |
网络收包、存储队列和加速器命令缓冲区都能复用这一模式。变动的是设备协议、DMA 一致性属性和通知机制,三个条件本身不能省略。
验收结果
python3 examples/computer-architecture/run_batch.py 29-33 退出 0,并生成六个有序状态。输出显式保留 real_device_transfer=false。验收只确认协议状态完整、边界可追踪;当前没有 PCIe 设备、IOMMU 映射日志、真实中断或 DMA 带宽数据。
练习
若设备只读缓冲区,CPU 在交出所有权后又修改描述符,可能破坏哪个协议条件?
画出轮询替代中断后的状态图。哪些状态不变,哪一条控制边改变?
模式速查
| 现象 | 应检查的状态 | 不能直接下的结论 |
|---|---|---|
| completion 已到 | 设备完成点、所有权、同步 | CPU 必然可安全消费 |
| 地址可由 CPU 访问 | DMA 映射与设备地址 | 设备能使用同一地址 |
| 模型状态通过 | 协议顺序 | 真实 DMA 已发生 |






