]> xenbits.xensource.com Git - unikraft/unikraft.git/commitdiff
plat/common: Preserve original size of allocated memory regions
authorSergiu Moga <sergiu@unikraft.io>
Sat, 19 Aug 2023 15:33:34 +0000 (18:33 +0300)
committerRazvan Deaconescu <razvand@unikraft.io>
Fri, 20 Oct 2023 16:35:55 +0000 (19:35 +0300)
Previously, `ukplat_memregion_alloc()` would allow one to dynamically
allocate based on available free memory regions a certain memory region
of a specific type and with specific flags and whose size will be the
page-aligned size of the desired size.

A user may want however to fetch some memory regions and know the
actual, intended size. To achieve this, make it so that the allocated
memory region has the original size on the surface, but the actual
allocation is done by splitting a page-aligned chunk to avoid
misalignments.

This leads to the same amount of memory fragmentation as before,
but with the improvement that the user of the API will have access to
the actual size of the data the memory region was allocated for.

Luckily, the paging initialization code is written in such a way that
it aligns every memory region before mapping/unmapping.

Signed-off-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Michalis Pappas <michalis@unikraft.io>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1060

plat/common/memory.c

index 3d256eb2260ea45c0e4de7aabb5a9a02559dd908..3aa1ba4d1b1a05cfadfe418dd900558d962d7c68 100644 (file)
@@ -65,16 +65,18 @@ void *ukplat_memregion_alloc(__sz size, int type, __u16 flags)
 {
        struct ukplat_memregion_desc *mrd, alloc_mrd = {0};
        __vaddr_t unmap_start, unmap_end;
+       __sz unmap_len, desired_sz;
        struct ukplat_bootinfo *bi;
        __paddr_t pstart, pend;
        __paddr_t ostart, olen;
-       __sz unmap_len;
        int rc;
 
        unmap_start = ALIGN_DOWN(bpt_unmap_mrd.vbase, __PAGE_SIZE);
        unmap_end = unmap_start + ALIGN_DOWN(bpt_unmap_mrd.len, __PAGE_SIZE);
        unmap_len = unmap_end - unmap_start;
 
+       /* Preserve desired size */
+       desired_sz = size;
        size = ALIGN_UP(size, __PAGE_SIZE);
        ukplat_memregion_foreach(&mrd, UKPLAT_MEMRT_FREE, 0, 0) {
                UK_ASSERT(mrd->pbase <= __U64_MAX - size);
@@ -106,7 +108,7 @@ void *ukplat_memregion_alloc(__sz size, int type, __u16 flags)
                if (olen - (pstart - ostart) == size) {
                        mrd->pbase = pstart;
                        mrd->vbase = pstart;
-                       mrd->len = pend - pstart;
+                       mrd->len = desired_sz;
                        mrd->type = type;
                        mrd->flags = flags;
 
@@ -122,7 +124,7 @@ void *ukplat_memregion_alloc(__sz size, int type, __u16 flags)
                /* Insert allocated region */
                alloc_mrd.vbase = pstart;
                alloc_mrd.pbase = pstart;
-               alloc_mrd.len   = size;
+               alloc_mrd.len   = desired_sz;
                alloc_mrd.type  = type;
                alloc_mrd.flags = flags | UKPLAT_MEMRF_MAP;