The new functions vm_phys_early_alloc_ex() and
vm_phys_early_alloc_ex_err() are extensions to vm_phys_early_alloc()
that allow to allocate early memory (from phys_avail[]) with more
fine-grained control. In particular, through them, one now can:
- Indicate that allocation must be performed at boundaries of the available physical addresses.
- Specify the alignment to use (with a minimum of PAGE_SIZE), independently of the allocation size.
- Let the caller decide if allocation failure should be fatal.
- Say that alignment waste should be simply dropped instead of keeping it (by creating a new chunk in phys_avail[]).
- Force allocation at start or end of a chunk (by default, the existing anti-fragmentation policy has been preserved).
- Force allocation from a particular chunk in phys_avail[].
Both these functions are in fact thin wrappers around a single internal
function vm_phys_early_alloc_int(). They exist just to differentiate
signatures depending on whether the latter returns on error or panics
instead, allowing annotating vm_phys_early_alloc_ex_err() with
'__result_use_check', which forces callers to test its return code.
The algorithm to allocate from a specific memory domain has been
improved in that it will always select the biggest chunk of phys_avail[]
in that domain, even if that chunk is not in the largest range described
in mem_affinity[] for that domain. Absent some proper abstraction
around phys_avail[], the drawback of this change is increased complexity
when selecting that chunk (now proportional to the number of chunks in
phys_avail[] multiplied by that in mem_affinity[]), but given both
arrays never describe more than tens of ranges, there should be no
impact in practice.
vm_phys_early_alloc() has been re-implemented as a thin wrapper around
vm_phys_early_alloc_ex(). We are preserving this simpler function for
the most common case, which is PAGE_SIZE alignment regardless of the
requested size. However, in order not to have to do the impacts of such
a change in this same commit, its current behavior ("natural alignment")
has been preserved, and changing it is deferred to a subsequent commit.