On Sun, Aug 08, 2021 at 03:31:41PM +0200, Patrick Steinhardt wrote: > Currently, all platforms will set up their heap on initialization of the > platform code. While this works mostly fine, it poses some limitations > on memory management on us. Most notably, allocating big chunks of > memory in the gigabyte range would require us to pre-request this many > bytes from the firmware and add it to the heap from the beginning on > some platforms like EFI. As this isn't needed for most configurations, > it is inefficient and may even negatively impact some usecases when
s/when/when, e.g.,/ > chainloading. Nonetheless, allocating big chunks of memory is required > sometimes, where one example is the upcoming support for the Argon2 key > derival function in LUKS2. > > In order to avoid pre-allocating big chunks of memory, this commit > implements a runtime mechanism to add more pages to the system. When > a given allocation cannot be currently be satisfied, we'll call a given s/currently be/currently/ > callback set up by the platform's own memory management subsystem, > asking it to add a memory area with at least `n` bytes. If this > succeeds, we retry searching for a valid memory region, which should now > succeed. > > Signed-off-by: Patrick Steinhardt <p...@pks.im> > --- > grub-core/kern/mm.c | 11 ++++++++++- > include/grub/mm.h | 13 +++++++++++++ > 2 files changed, 23 insertions(+), 1 deletion(-) > > diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c > index c070afc62..3c003a2f9 100644 > --- a/grub-core/kern/mm.c > +++ b/grub-core/kern/mm.c > @@ -81,6 +81,7 @@ > > > grub_mm_region_t grub_mm_base; > +grub_mm_region_func_t grub_mm_region_fn; > > /* Get a header from the pointer PTR, and set *P and *R to a pointer > to the header and a pointer to its region, respectively. PTR must > @@ -360,8 +361,16 @@ grub_memalign (grub_size_t align, grub_size_t size) > count++; > goto again; > > -#if 0 > case 1: > + /* Request additional pages. */ > + count++; > + > + if (grub_mm_region_fn && grub_mm_region_fn (size, > GRUB_MM_REGION_CONSECUTIVE) == GRUB_ERR_NONE) > + goto again; > + > + /* fallthrough */ > +#if 0 > + case 2: > /* Unload unneeded modules. */ > grub_dl_unload_unneeded (); Please drop this dead code together with grub_dl_unload_unneeded() function in a preparatory patch. > count++; > diff --git a/include/grub/mm.h b/include/grub/mm.h > index 9c38dd3ca..deff15f17 100644 > --- a/include/grub/mm.h > +++ b/include/grub/mm.h > @@ -20,6 +20,7 @@ > #ifndef GRUB_MM_H > #define GRUB_MM_H 1 > > +#include <grub/err.h> > #include <grub/types.h> > #include <grub/symbol.h> > #include <config.h> > @@ -28,6 +29,18 @@ > # define NULL ((void *) 0) > #endif > > +enum { > + GRUB_MM_REGION_CONSECUTIVE = 1 << 0, > +}; I prefer define instead of enum here. > +/* Function used to request memory regions of `grub_size_t` bytes. The second > + * parameter is a bitfield of `GRUB_MM_REGION` flags. */ Please format comments according to [1]. > +typedef grub_err_t (*grub_mm_region_func_t) (grub_size_t, unsigned); s/unsigned/unsigned int/ > +/* Set this function pointer to enable adding memory-regions at runtime in > case > + * a memory allocation cannot be satisfied with existing regions. */ > +extern grub_mm_region_func_t EXPORT_VAR(grub_mm_region_fn); > + > void grub_mm_init_region (void *addr, grub_size_t size); > void *EXPORT_FUNC(grub_calloc) (grub_size_t nmemb, grub_size_t size); > void *EXPORT_FUNC(grub_malloc) (grub_size_t size); Daniel [1] https://www.gnu.org/software/grub/manual/grub-dev/grub-dev.html#Comments _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel