返回资讯中心
外部精选
软件工程
#开发者实时流

Owning C types from Rust code

Subscriptions are the lifeblood of LWN.net. If you appreciate this

Hacker News 最新signa112026/10/23 · 22 天前21 分钟阅读

以下正文同步自 Hacker News 最新,版权归原站所有,已转换为易读排版。

Subscriptions are the lifeblood of LWN.net. If you appreciate this content and would like to see more of it, your subscription will help to ensure that LWN continues to thrive. Please visit this page to join up and keep LWN on the net.

By Daroc Alden October 13, 2026

Kangrejos

Rust's system of ownership and borrowed references is convenient when it can correctly model a program's needs. The

Rust for Linux project has worked to provide adapters between Rust's semantics and the existing C code in the kernel. At Kangrejos 2026, Andreas Hindborg spoke about a

patch series implementing the next such adaptor: an Ownable trait for representing objects that are allocated in C code, but which Rust code is responsible for cleaning up (if not necessarily deallocating) when it is done with them. He hoped to finally reach a consensus on the patch series, after months of discussion on the mailing list.

In the block subsystem, where Hindborg does most of his work, there is a memory pool set aside for handling concurrent requests. Each I/O request is represented by a

bio structure. To make a new request, the block layer identifies an unused structure in the pool, fills it with the details of the request, and passes it to the appropriate driver. The driver handles the request, clears the request structure, and passes it back to the block layer to be reused. That design avoids the overhead of constantly allocating and deallocating for each request, but it also doesn't quite fit with the existing abstractions in the kernel's Rust code.

The two closest abstractions are the

KBox and

ARef types. The former isn't suitable for this case, because it assumes that allocations are made from within Rust code. The latter doesn't fit either, because it assumes that objects are always reference-counted, which is not always the case for I/O requests. So, Hindborg wants to add a new smart pointer called Owned that behaves conceptually like a KBox, in that it provides unique access to the pointed-to value, but that doesn't attempt to free the memory when it reaches the end of its life. Instead, an Owned pointer would call a special release() function, which could do something like release the underlying memory back to a subsystem-specific pool. Owned pointers would only be able to point at C types that implement the Ownable trait, to ensure that they are only used with types that have a meaningful release() function.

The complexity comes from making Owned integrate with the existing Rust abstractions in the kernel. For example, if a reference-counted type has a reference count of one, then in theory the Rust code holding an ARef can know that no other references exist, and that therefore it should be safe to convert to an Owned pointer. When a type can be either uniquely owned or reference counted, it also makes sense to go the other way and convert an Owned pointer into an ARef. If that operation consumed the Owned pointer, that would be sound.

The problem is that it is already permitted to use an Owned pointer to produce a built-in reference. In addition, turning a built-in reference into an ARef pointer is also allowed, since if Rust code manages to acquire a reference to a reference-counted type, the reference count must be at least one. Taken together, these features would allow for unsoundness. If an Owned pointer were used to produce to a built-in reference, that reference were used to create an ARef, and then the Owned pointer continued being used to modify the underlying item, it could result in a concurrent modification.

Some users in the kernel feel strongly about keeping the existing behavior that allows upgrading a built-in reference to an ARef pointer, Hindborg said. He thinks that they could change their APIs to take an ARef directly, and that this would be simpler, but they have been unwilling to take that approach. As a compromise, he has suggested splitting the existing

AlwaysRefCounted trait (which tells the compiler that C types can be put behind an ARef) into two smaller traits. One would enable a type to be used with ARef, and the other would allow for converting built-in references to ARef pointers. Implementing the latter for a type that also implements Ownable would be forbidden.

In Hindborg's proposed Rust bindings for the block layer, there are four possible states that an I/O request can be in: owned by the block layer, owned by the driver, shared between multiple parts of the driver, and parked by the driver. When the block layer sends a request to a driver written in Rust, the bindings pass an Owned pointer to the request; marking a request as ended requires passing one back. That way, the block-layer Rust code can be sure that the driver did not retain any references internally.

He showed a diagram of the full state machine, which was made more complex by the possibility of having multiple shared pointers or relying on hardware tags inside the driver itself. Ultimately, his goal was to produce an interface that drivers could only use correctly.

Other subsystems could also make use of the Owned abstraction, he thought. IOMMU page tables and the Rust binder driver could both use it. He had discussed using it for

GPUVM, before determining that it was not an appropriate fit. Alice Ryhl and Hindborg then got into a back-and-forth discussion about whether it could be made suitable for GPUVM, eventually concluding that the necessary changes could be added on after Hindborg's patch series was merged. Boqun Feng disagreed that extending it to support GPUVM was desirable. Greg Kroah-Hartman thought that the USB drivers could potentially make use of Owned as well.

One question that Hindborg had was whether it was reasonable to make the Rust wrapper type around page structures implement Ownable. It couldn't be done simply, because the Rust binder code relies on being able to upgrade a built-in reference to a page into an ARef pointer. That is necessary because the Rust binder code passes the reference to

vm_insert_page(), which increments the reference count on the page. Hindborg asked Ryhl whether it would be possible to change the Rust bindings to vm_insert_page() to eliminate the need to pass a built-in reference. Ryhl didn't think so, pointing out that it is, in general, acceptable for code to increment the reference count of a page, so addressing this one case would not make it safe to have pages implement Ownable.

Kent Overstreet added that the reference counting of pages is a delicate subject, because of the interactions with the splice() system call. When prompted to elaborate, he explained that it can vary from page to page whether it is acceptable to change the reference count. Additionally, the transition to folios has complicated that code, because it is now necessary to differentiate between head and tail pages.

Gary Guo wondered why Hindborg wanted to use owned page structures at all; he thought that there was a difference between being able to edit the page structure and being able to edit the memory in the page directly, and that, unfortunately, different parts of the code had their own assumptions about what was permitted. Hindborg indicated that he was interested in modifying the data content of the page, but that he thought it was a sub-problem of being able to modify the page structure itself. Feng pointed out that the memory-management maintainers want to push developers toward using folios, and avoid exposing pages to any new users. So, the question of whether to expose pages to Rust code in this way was more of an API discussion that should include the memory-management maintainers than a standalone correctness problem that could be solved on the Rust side of things.

The patch series has been in progress since early 2025, Hindborg said, and was on its twenty-second version. The implementation has gone around in circles, with people requesting different changes. At this point, Hindborg just wants to see some consensus reached. "So please. Let's work together. We can do this."

Miguel Ojeda mentioned that in the kernel, it is often possible to do review swaps, where two people trade reviews of their work. Hindborg immediately agreed, saying: "I am absolutely for sale." Hopefully, that means that Hindborg's patch set will soon be reviewed and, potentially, merged.

[ Thanks to the Linux Foundation, LWN's travel sponsor, for assistance with traveling to Kangrejos. ]

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →