From: Simona Vetter <simona.vetter@ffwll.ch>
To: Asahi Lina <lina@asahilina.net>
Cc: "Miguel Ojeda" <ojeda@kernel.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <benno.lossin@proton.me>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Jann Horn" <jannh@google.com>,
"Matthew Wilcox" <willy@infradead.org>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Danilo Krummrich" <dakr@kernel.org>,
"Wedson Almeida Filho" <wedsonaf@gmail.com>,
"Valentin Obst" <kernel@valentinobst.de>,
"Andrew Morton" <akpm@linux-foundation.org>,
linux-mm@kvack.org, airlied@redhat.com,
"Abdiel Janulgue" <abdiel.janulgue@gmail.com>,
rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org,
asahi@lists.linux.dev
Subject: Re: [PATCH 0/6] rust: page: Support borrowing `struct page` and physaddr conversion
Date: Mon, 3 Feb 2025 10:58:04 +0100 [thread overview]
Message-ID: <Z6CTLB2NggwYafi9@phenom.ffwll.local> (raw)
In-Reply-To: <20250202-rust-page-v1-0-e3170d7fe55e@asahilina.net>
On Sun, Feb 02, 2025 at 10:05:42PM +0900, Asahi Lina wrote:
> This series refactors the existing Page wrapper to support borrowing
> `struct page` objects without ownership on the Rust side, and converting
> page references to/from physical memory addresses.
>
> The series overlaps with the earlier submission in [1] and follows a
> different approach, based on the discussion that happened there.
>
> The primary use case for this is implementing IOMMU-style page table
> management in Rust. This allows drivers for IOMMUs and MMU-containing
> SoC devices to be written in Rust (such as embedded GPUs). The intended
> logic is similar to how ARM SMMU page tables are managed in the
> drivers/iommu tree.
>
> First, introduce a concept of Owned<T> and an Ownable trait. These are
> similar to ARef<T> and AlwaysRefCounted, but are used for types which
> are not ref counted but rather have a single intended owner.
>
> Then, refactor the existing Page support to use the new mechanism. Pages
> returned from the page allocator are not intended to be ref counted by
> consumers (see previous discussion in [1]), so this keeps Rust's view of
> page ownership as a simple "owned or not". Of course, this is still
> composable as Arc<Owned<Page>> if Rust code needs to reference count its
> own Page allocations for whatever reason.
I think there's a bit a potential mess here because the conversion to
folios isn't far enough yet that we can entirely ignore page refcounts and
just use folio refcounts. But I guess we can deal with that oddity if we
hit it (maybe folio conversion moves fast enough), since this only really
starts to become relevant for hmm/svm gpu stuff.
iow I think anticipating the future where struct page really doesn't have
a refcount is the right move. Aside from that it's really not a refcount
that works in the rust ARef sense, since struct page cannot disappear for
system memory, and for dev_pagemap memory it's an entirely different
reference you need (and then there's a few more special cases).
For dma/iommu stuff there's also a push to move towards pfn + metadata
model, so that p2pdma doesn't need struct page. But I haven't looked into
that much yet.
Cheers, Sima
> Then, make some existing private methods public, since this is needed to
> reasonably use allocated pages as IOMMU page tables.
>
> Along the way we also add a small module to represent a core kernel
> address types (PhysicalAddr, DmaAddr, ResourceSize, Pfn). In the future,
> this might grow with helpers to make address math safer and more
> Rust-like.
>
> Finally, add methods to:
> - Get a page's physical address
> - Convert an owned Page into its physical address
> - Convert a physical address back to its owned Page
> - Borrow a Page from a physical address, in both checked (with checks
> that a struct page exists and is accessible as regular RAM) and not
> checked forms (useful when the user knows the physaddr is valid,
> for example because it got it from Page::into_phys()).
>
> Of course, all but the first two have to be `unsafe` by nature, but that
> comes with the territory of writing low level memory management code.
>
> These methods allow page table code to know the physical address of
> pages (needed to build intermediate level PTEs) and to essentially
> transfer ownership of the pages into the page table structure itself,
> and back into Page objects when freeing page tables. Without that, the
> code would have to keep track of page allocations in duplicate, once in
> Rust code and once in the page table structure itself, which is less
> desirable.
>
> For Apple GPUs, the address space shared between firmware and the driver
> is actually pre-allocated by the bootloader, with the top level page
> table already pre-allocated, and the firmware owning some PTEs within it
> while the kernel populates others. This cooperation works well when the
> kernel can reference this top level page table by physical address. The
> only thing the driver needs to ensure is that it never attempts to free
> it in this case, nor the page tables corresponding to virtual address
> ranges it doesn't own. Without the ability to just borrow the
> pre-allocated top level page and access it, the driver would have to
> special-case this and manually manage the top level PTEs outside the
> main page table code, as well as introduce different page table
> configurations with different numbers of levels so the kernel's view is
> one lever shallower.
>
> The physical address borrow feature is also useful to generate virtual
> address space dumps for crash dumps, including firmware pages. The
> intent is that firmware pages are configured in the Device Tree as
> reserved System RAM (without no-map), which creates struct page objects
> for them and makes them available in the kernel's direct map. Then the
> driver's page table code can walk the page tables and make a snapshot of
> the entire address space, including firmware code and data pages,
> pre-allocated shared segments, and driver-allocated objects (which are
> GEM objects), again without special casing anything. The checks in
> `Page::borrow_phys()` should ensure that the page is safe to access as
> RAM, so this will skip MMIO pages and anything that wasn't declared to
> the kernel in the DT.
>
> Example usage:
> https://github.com/AsahiLinux/linux/blob/gpu/rust-wip/drivers/gpu/drm/asahi/pgtable.rs
>
> The last patch is a minor cleanup to the Page abstraction noticed while
> preparing this series.
>
> [1] https://lore.kernel.org/lkml/20241119112408.779243-1-abdiel.janulgue@gmail.com/T/#u
>
> Signed-off-by: Asahi Lina <lina@asahilina.net>
> ---
> Asahi Lina (6):
> rust: types: Add Ownable/Owned types
> rust: page: Convert to Ownable
> rust: page: Make with_page_mapped() and with_pointer_into_page() public
> rust: addr: Add a module to declare core address types
> rust: page: Add physical address conversion functions
> rust: page: Make Page::as_ptr() pub(crate)
>
> rust/helpers/page.c | 26 ++++++++++++
> rust/kernel/addr.rs | 15 +++++++
> rust/kernel/lib.rs | 1 +
> rust/kernel/page.rs | 101 ++++++++++++++++++++++++++++++++++++++--------
> rust/kernel/types.rs | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++
> 5 files changed, 236 insertions(+), 17 deletions(-)
> ---
> base-commit: ffd294d346d185b70e28b1a28abe367bbfe53c04
> change-id: 20250202-rust-page-80892069fc78
>
> Cheers,
> ~~ Lina
>
--
Simona Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
next prev parent reply other threads:[~2025-02-03 9:58 UTC|newest]
Thread overview: 67+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-02 13:05 [PATCH 0/6] rust: page: Support borrowing `struct page` and physaddr conversion Asahi Lina
2025-02-02 13:05 ` [PATCH 1/6] rust: types: Add Ownable/Owned types Asahi Lina
2025-02-03 9:13 ` Alice Ryhl
2025-02-03 14:17 ` Asahi Lina
2025-02-03 18:17 ` Alice Ryhl
2025-02-03 19:17 ` Asahi Lina
2025-02-19 8:34 ` Andreas Hindborg
2025-02-19 8:37 ` Andreas Hindborg
2025-02-02 13:05 ` [PATCH 2/6] rust: page: Convert to Ownable Asahi Lina
2025-02-03 9:17 ` Alice Ryhl
2025-02-03 9:39 ` Fiona Behrens
2025-02-19 8:46 ` Andreas Hindborg
2025-02-02 13:05 ` [PATCH 3/6] rust: page: Make with_page_mapped() and with_pointer_into_page() public Asahi Lina
2025-02-03 9:10 ` Alice Ryhl
2025-02-03 9:43 ` Fiona Behrens
2025-02-19 8:48 ` Andreas Hindborg
2025-02-02 13:05 ` [PATCH 4/6] rust: addr: Add a module to declare core address types Asahi Lina
2025-02-03 9:09 ` Alice Ryhl
2025-02-03 15:04 ` Boqun Feng
2025-02-04 11:50 ` Asahi Lina
2025-02-04 14:50 ` Boqun Feng
2025-02-19 8:51 ` Andreas Hindborg
2025-02-02 13:05 ` [PATCH 5/6] rust: page: Add physical address conversion functions Asahi Lina
2025-02-03 9:35 ` Alice Ryhl
2025-02-04 11:43 ` Asahi Lina
2025-02-03 9:53 ` Fiona Behrens
2025-02-03 10:01 ` Alice Ryhl
2025-02-19 9:06 ` Andreas Hindborg
2025-02-02 13:05 ` [PATCH 6/6] rust: page: Make Page::as_ptr() pub(crate) Asahi Lina
2025-02-03 9:08 ` Alice Ryhl
2025-02-19 9:08 ` Andreas Hindborg
2025-02-03 9:58 ` Simona Vetter [this message]
2025-02-03 14:32 ` [PATCH 0/6] rust: page: Support borrowing `struct page` and physaddr conversion Asahi Lina
2025-02-03 21:05 ` Zi Yan
2025-02-04 10:26 ` David Hildenbrand
2025-02-04 11:41 ` Asahi Lina
2025-02-04 11:59 ` David Hildenbrand
2025-02-04 13:05 ` Asahi Lina
2025-02-04 14:38 ` David Hildenbrand
2025-02-04 17:59 ` Asahi Lina
2025-02-04 20:10 ` David Hildenbrand
2025-02-04 21:06 ` Asahi Lina
2025-02-06 17:58 ` David Hildenbrand
2025-02-06 19:18 ` Asahi Lina
2025-02-06 19:27 ` Asahi Lina
2025-02-12 19:06 ` David Hildenbrand
2025-02-12 19:01 ` David Hildenbrand
2025-02-05 7:40 ` Simona Vetter
2025-02-12 19:07 ` David Hildenbrand
2025-02-04 10:33 ` David Hildenbrand
2025-02-04 18:39 ` Jason Gunthorpe
2025-02-04 19:01 ` Asahi Lina
2025-02-04 20:05 ` David Hildenbrand
2025-02-04 20:26 ` Jason Gunthorpe
2025-02-04 20:41 ` David Hildenbrand
2025-02-04 20:47 ` David Hildenbrand
2025-02-04 21:18 ` Asahi Lina
2025-02-06 18:02 ` David Hildenbrand
2025-02-04 20:49 ` Jason Gunthorpe
2025-02-05 23:17 ` Matthew Wilcox
2025-02-06 18:04 ` David Hildenbrand
2025-02-03 10:22 ` Danilo Krummrich
2025-02-03 14:41 ` Asahi Lina
2025-02-15 19:47 ` Asahi Lina
2025-02-17 8:50 ` Abdiel Janulgue
2025-02-19 9:24 ` Andreas Hindborg
-- strict thread matches above, loose matches on Subject: below --
2025-03-06 19:21 Oliver Mangold
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Z6CTLB2NggwYafi9@phenom.ffwll.local \
--to=simona.vetter@ffwll.ch \
--cc=a.hindborg@kernel.org \
--cc=abdiel.janulgue@gmail.com \
--cc=airlied@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=asahi@lists.linux.dev \
--cc=benno.lossin@proton.me \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=dakr@kernel.org \
--cc=gary@garyguo.net \
--cc=jannh@google.com \
--cc=kernel@valentinobst.de \
--cc=lina@asahilina.net \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ojeda@kernel.org \
--cc=pbonzini@redhat.com \
--cc=rust-for-linux@vger.kernel.org \
--cc=tmgross@umich.edu \
--cc=wedsonaf@gmail.com \
--cc=willy@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.