Skip to content

Conversation

RossComputerGuy
Copy link
Contributor

Split off from #22226 as suggested by @linusg. This reworks the allocators to be more friendly.

Copy link
Collaborator

@linusg linusg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, this is the right size for a PR like this :)

Two high level concerns:

  • All allocators, including platform-specific ones like WasmAllocator currently live in std.heap. If we're moving these around that should be where.
  • Why are we adding additional abstractions on top of the UEFI-provided allocator functions? In general that's a good thing if it improves ergonomics of those APIs from a Zig perspective, but in this case no one but the allocator implementation should touch those, and I feel in that case the extra layer is not justified.

@RossComputerGuy
Copy link
Contributor Author

  • All allocators, including platform-specific ones like WasmAllocator currently live in std.heap. If we're moving these around that should be where.

Will do

  • Why are we adding additional abstractions on top of the UEFI-provided allocator functions? In general that's a good thing if it improves ergonomics of those APIs from a Zig perspective, but in this case no one but the allocator implementation should touch those, and I feel in that case the extra layer is not justified.

I'm not 100% sure, this originally came from @truemedian.

@truemedian
Copy link
Contributor

Why are we adding additional abstractions

Which additional abstractions are you referring to?

PageAllocator.resize requesting new pages at the end of the current allocation happens because it's essentially free and part of the UEFI page allocation interface

PoolAllocator exists because RawPoolAllocator cannot handle the full range of possible alignment values the Allocator interface requires

@RossComputerGuy RossComputerGuy force-pushed the feat/uefi-alloc-rework branch 2 times, most recently from 7efc07c to a9862db Compare February 10, 2025 03:35
@linusg
Copy link
Collaborator

linusg commented Feb 10, 2025

Which additional abstractions are you referring to?

The ones in boot_services.zig.

@truemedian
Copy link
Contributor

Ah, thats because this came out of a branch where the goal was to make std.os.uefi a more idiomatic interface instead of just a loose C library binding.

Copy link
Collaborator

@linusg linusg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rebase this after #22820 and provide a compelling use case for the custom layer in boot_services.zig or remove it.

/// Allocates memory in pages.
///
/// This allocator is backed by `allocatePages` and is therefore only suitable for usage when Boot Services are available.
pub const PageAllocator = struct {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The namespacing here is awkward, this ought to be a file-as-struct (UefiPageAllocator.zig).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why file as a struct when there's multiple allocators?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because std.heap.UefiPageAllocator is much nicer than std.heap.uefi_allocators.PageAllocator (which violates https://ziglang.org/documentation/master/#Avoid-Redundant-Names-in-Fully-Qualified-Namespaces). Why do you want both allocators in the same file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because std.heap.UefiPageAllocator is much nicer than std.heap.uefi_allocators.PageAllocator

Wouldn't std.heap.uefi.Page/Pool be nicer?

Why do you want both allocators in the same file?

Just so there isn't 3 more files that could fit into 1.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't std.heap.uefi.Page/Pool be nicer?

Not really, a "page" and a "page allocator" are different things. Avoiding redundancy does not mean to leave out important bits of information until the name has a different meaning.

Just so there isn't 3 more files that could fit into 1.

That's not a good reason.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I've managed to find the time and split the allocators into their own files.

@RossComputerGuy
Copy link
Contributor Author

Please rebase this after #22820

Already been rebased.

provide a compelling use case for the custom layer in boot_services.zig or remove it.

I don't have one unless @truemedian does. I think it just makes the API easier to use and it's already there. Shouldn't need additional maintenance since UEFI's API doesn't really change in that section. I probably will just remove it.

@linusg
Copy link
Collaborator

linusg commented Feb 20, 2025

Already been rebased.

I see at least one reference to .LoaderData which has been renamed.

@RossComputerGuy
Copy link
Contributor Author

I see at least one reference to .LoaderData which has been renamed.

Fixed, strange that one didn't get caught when I tried compiling lib/init.

@linusg
Copy link
Collaborator

linusg commented Feb 20, 2025

I think it just makes the API easier to use and it's already there. Shouldn't need additional maintenance

For the most part Zig follows YAGNI principles.

Copy link
Collaborator

@linusg linusg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parts of this will be superseded by #23441.

@RossComputerGuy
Copy link
Contributor Author

Great, I'll rebase once that lands. Though I'm still wondering about #22818 (comment).

@RossComputerGuy RossComputerGuy force-pushed the feat/uefi-alloc-rework branch from 33af113 to 9611057 Compare April 10, 2025 07:24
Copy link
Contributor

@dotcarmen dotcarmen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this pr should now be unblocked as well since #23441 landed :)

@@ -24,6 +24,8 @@ pub const GeneralPurposeAllocatorConfig = DebugAllocatorConfig;
/// Deprecated; to be removed after 0.14.0 is tagged.
pub const GeneralPurposeAllocator = DebugAllocator;

pub const uefi = @import("heap/uefi_allocators.zig");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i prefer to keep these in std.os.uefi, any reason to move them?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forget who mentioned it but someone here mentioned that this is what should be done.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was me, but I've changed my mind - the split into file-as-struct is nice but let's keep them in std.os.uefi for now.

@@ -38,19 +40,19 @@ pub const BootServices = extern struct {
restoreTpl: *const fn (old_tpl: usize) callconv(cc) void,

/// Allocates memory pages from the system.
allocatePages: *const fn (alloc_type: AllocateType, mem_type: MemoryType, pages: usize, memory: *[*]align(4096) u8) callconv(cc) Status,
_allocatePages: *const fn (alloc_type: AllocateType.Enum, mem_type: MemoryType, pages: usize, memory: PhysicalAddress) callconv(cc) Status,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh that's a good point that i didn't address in my pr: the memory returned is a physical address, which shouldn't be used directly as a pointer

once you rebase i think it might make sense to keep that change (as opposed to *[*]uefi.Page), with the caveat that it should be memory: *PhysicalAddress and to return that PhysicalAddress from allocatePages. idk though, that would imply changing eg convertPointer which could get hairy

alternatively it would be nice if there was std.builtin.AddressSpace.physical but that could come with a cascade of changes that aren't necessarily relevant here.

@RossComputerGuy RossComputerGuy force-pushed the feat/uefi-alloc-rework branch from 9611057 to d5966c8 Compare July 18, 2025 21:27
@RossComputerGuy
Copy link
Contributor Author

Rebased, I haven't adjusted much but hopefully I resolved the conflicts well.

@@ -377,7 +379,7 @@ pub const BootServices = extern struct {
mem_type: MemoryType,
pages: usize,
) AllocatePagesError![]align(4096) Page {
var ptr: [*]align(4096) Page = switch (location) {
var ptr: PhysicalAddress = switch (location) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you also have to fix the return type of the function and the .success arm of the switch below

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants