系统与数据库2024db.in.tum.de
用 Rust 编写 NVMe 驱动程序
Writing an NVMe Driver in Rust
进阶 · 约 60 分钟读完前置知识:Rust 基础、操作系统与驱动基础、NVMe/存储协议
导读
这篇图宾根大学的本科论文用 Rust 从零实现了一个用户态 NVMe 驱动,并与 C 语言编写的 SPDK 驱动进行对比。论文展示了 Rust 可以在系统级设备驱动开发中工作,且实现出的驱动 API 更简洁、代码量更少。
HN 关注点:Rust 在系统编程/设备驱动领域的实际可行性,以及内存安全语言在驱动开发中的真实价值;讨论焦点包括 Rust 结构体内存布局与 C ABI 的兼容性、IOMMU 对 DMA 安全的关键作用等。
HN 评论精选
这几条评论里:支持 2 质疑 2
质疑质疑 Rust 结构体的内存布局能否与 C ABI 二进制兼容
我只读了论文(和论文里的代码),没看完整源码,所以也许看了源码会更清楚……Rust 从根本上保证 struct 的字段按定义顺序在内存中排布吗?它能用来和期望 C struct(或指向它的指针)的 API(其实是 ABI)交互吗?我觉得 Go 和 Swift 在这方面让我沮丧的地方在于,它们的 struct 与 C struct 不具备这种二进制兼容性,因为它们会为了对齐/打包而重排字段。
bengl3rt查看英文原文
I only read the paper (and the code in the paper) but not the complete source code, so maybe this would become clearer if I had, but... Does Rust fundamentally guarantee that if you make a struct, its fields will lay out in memory in the order that you defined them? Can it be used to interact with APIs (really ABIs) who expect a C struct (or pointer to one)? I think my main frustration with stuff like Go and Swift in this case is that their structs are not binary-compatible with C structs in this way because they rearrange things to be better aligned/packed/whatever.
质疑指出论文未兑现内存安全论证,且未启用 IOMMU 时 DMA 可绕过 Rust 的安全保证
很高兴看到更多用 Rust 写的系统代码!我以前也参与过 SPDK,所以看到它被选作对比对象觉得很有意思。不过我一直在等论文里宣传的内存安全在引言之外再次出现,但它再也没被提起。我希望论文能更有力地论证 Rust 这类内存安全语言,比如“我们的驱动没有其他驱动中出现过的 X、Y、Z bug,因为编译器捕获了它们”。另外,对于一个控制可 DMA 硬件(如 NVMe 控制器)的用户态驱动,最关键的内存安全特性是 IOMMU,而论文中的驱动并未启用它;当硬件可以被编程去读写物理地址空间的任意位置(包括其他进程甚至内核的内存)时,驱动代码本身的内存安全毫无意义——即使这些代码在 Rust 语义下完全“安全”。论文的驱动或许确实“API 更简化、代码更少”,但我不认为这和实现语言有多大关系:这是在拿一个全新的极简设计对比一个存在多年、不断增量添加功能的老项目,后者必然更大更复杂。这并不是一个特别令人惊讶的结果,也算不上对某种语言的背书。
drv查看英文原文
It's cool to see more systems code written in Rust! I also previously worked on SPDK, so it was neat to see it being chosen as a point of comparison. However, I was waiting for the touted memory safety to be mentioned beyond the introduction, but it never really came up again. I was hoping for the paper to make a stronger argument for memory-safe languages like Rust, something like "our driver did not have bugs X, Y, and Z, which were found in other drivers, because the compiler caught them". Additionally, in a userspace device driver that is given control of a piece of hardware that can do DMA, like an NVMe controller, the most critical memory safety feature is an IOMMU, which the driver covered by the paper does not enable; no amount of memory safety in the driver code itself matters when the hardware can be programmed to read or write anywhere in the physical address space, including memory belonging to other processes or even the kernel, from totally "safe" (in Rust semantics) code. While the driver from the paper may certainly have a "simplified API and less code", I don't expect much of this to be related to the implementation language; it's comparing a clean-sheet minimal design to a project that has been around for a while and has had additional features incrementally added to it over time, making the older codebase inevitably larger and more complex. This doesn't seem like a particularly surprising result or an endorsement of a particular language, though it perhaps does indicate that it would be useful to start from scratch now and again just to see what the minimum viable system can look like. I certainly would have liked to rewrite it in Rust, but that wasn't really feasible. :) In any case, it's great to see proof that a Rust driver can have comparable performance to one written in C, since it will hopefully encourage new code to be written in a nicer language than C. I definitely don't miss having to deal with manual memory management and chasing down use-after-frees now that I write Rust instead of C. (As a side note, I'd encourage anyone thinking of using a userspace storage driver on Linux to check out io_uring first before going all in; if io_uring had existed before SPDK, I don't know that SPDK would have been written, given that io_uring gets you most of the way there performance-wise and integrates nicely with the rest of the kernel. A userspace driver has its uses, but I would consider it to be a last resort after exhausting all other options, since you have to reinvent all of the other functionality normally provided by the kernel like I/O scheduling, filesystems, encryption, etc., not just the NVMe driver itself. That is, assuming the io_uring security issues get resolved over time, and I expect they will.)
支持求推荐类似的驱动实现学习资源
非常酷、令人印象深刻的工作!我偏软件(高层)方向而非硬件,但我一直好奇 USB 等接口到底是怎么工作的,这是我惭愧欠缺的知识领域……有人能分享一些像这篇这样聚焦某个具体接口并实现驱动/读取器/解析器的优质资源吗?我很想深入学习。
Kydlaw查看英文原文
Really cool and impressive work! I'm more on the software (high level) side than on the hardware, but I always wondered how USBs and other ports were truly working. It is an area of knowledge that I'm shamefully lacking... Does anyone have nice resources to share like this one that focuses on a specific port/connection and implement a driver/reader/parser? I'd very like to learn more of this.
支持称赞论文质量,建议录用该学生
这是一篇本科毕业论文——应该有人把这位学生招走。写作清晰、思路出色。
gdiamos查看英文原文
That is a bachelor’s thesis - someone should hire that student Clear writing and ideas
相关资源
从这篇论文所有 HN 讨论帖的全部评论里整理出来的链接。
历次讨论
- 2024Hacker News 讨论帖242 分 · 44 评
同领域还值得读
I/O 比 CPU 更快——让我们划分资源并消除操作系统抽象
I/O Is Faster Than CPU – Let’s Partition Resources and Eliminate OS Abstractions
指出在现代服务器硬件上 I/O 速度已接近甚至超过 CPU,传统操作系统抽象反而成为瓶颈。
系统与数据库2019 · 817 分 · 277 评进阶 · 约 30 分钟编辑精选使用 io_uring 的高效 I/O
Efficient IO with io_uring
由 Linux 内核开发者 Jens Axboe 撰写,介绍 Linux 新的异步 I/O 接口 io_uring。
系统与数据库2019 · 426 分 · 96 评进阶 · 约 45 分钟编辑精选线程对大多数用途而言是个坏主意(1995)
Threads Are a Bad Idea for Most Purposes (1995)
这篇 1995 年的文章由 John Ousterhout 撰写,讨论为什么线程对大多数用途而言是坏主意,并主张事件驱动编程通常更简单、更高效。
系统与数据库2017 · 423 分 · 382 评进阶 · 约 25 分钟编辑精选学习型索引结构之论证
The Case for Learned Index Structures
提出把索引看作一种"模型":既然 B-tree 等结构本质上是在学习数据的分布,就可以用机器学习模型(如回归模型、神经网络)来近似键到位置的映射,从而替代 B-tree、哈希索引…
系统与数据库2017 · 398 分 · 66 评 · 引用 25进阶 · 约 60 分钟编辑精选FoundationDB:一个分布式、解耦的事务型键值存储
FoundationDB: A distributed, unbundled, transactional key value store
介绍 FoundationDB:一个分布式、解耦设计的事务性键值存储。
系统与数据库2021 · 283 分 · 99 评进阶 · 约 90 分钟编辑精选