You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, free(v) uses the offset of an objectwithin a page (o = v & 0xfff) to determine which allocator is responsible for the page:
if o == 0, it is a large object (> page size)
if o == 8, it is a an early allocator object
otherwise, it is a mempool object, with the pool page header residing at the beginning of the page (v - o)
this scheme has a number of issues:
allocating objects that are exactly page sized waste two pages
it is hard to align objects that are between half a page and a page
the header for a large object is sized an entire page (the expected waste is half a page on average)
We can improve this by using information other than the offset within the page to determine the allocator. If we map physical memory multiple times (all aliases of each other), we can use virtual address bits 44:46 to determine the allocator.
The value of v[44:46] can be used as follows:
0 - mempool allocator
1 - page allocator (for objects between half a page and a page)
2 - half-page allocator (for objects exactly half a page, useful for network buffers)
3 - large objects
4-5 reserved
6 - early allocator objects
7 - debug allocator (using a non identity virtual:physical mapping)
In the mailing list Avi pointed out that as part of this fix, we should also get a more complete implementation of posix_memalign() than what we have now:
On Tue, Nov 19, 2013 at 11:38 AM, Avi Kivity [email protected] wrote:
I should implement posix_memalign (POSIX) and/or aligned_alloc() (new to C11), and use that.
Shoud be done as part of #87.
Note it's pretty easy if you change the header to include a pointer to the start of the block.
This patch provides a trivial implementation of two similar functions for
allocating aligned memory blocks: aligned_alloc() (from the C11 standard)
and posix_memaligned() (from POSIX). Memory returned by either function
can be freed with the ordinary free().
This trivial implementation just calls malloc(), and assert()s that it got
the desired alignment, aborting if not. In many cases this is good enough
because malloc() already returns 4096-byte-aligned blocks for large
allocations. In particular we'll use these functions in the next patch for
allocating the large page-aligned per-cpu areas.
If we ever fail on this assertion, we can replace these functions by a
full implementation (see issue #87).
Signed-off-by: Nadav Har'El <[email protected]>
Reviewed-by: Pekka Enberg <[email protected]>
Signed-off-by: Avi Kivity <[email protected]>
"This series is the first step in implementing memory allocator enhancements
described by Avi in #87. Virtual memory starting from address 0xffff800000000000
is divided into memory areas. Each of the object allocators (currently: mempool,
large and early) return addresses to memory block only in its own memory area.
When memory block is freed bits [44:46] of its virtual address are used to
identify the responsible allocator.
phys_to_virt() makes things a bit tricky, since it is not possible to determine
to which memory area should the returned virtual address belong to. Current
solution is to return addresses in memory_area::main (used also by large memory
allocator) and make alloc_phys_contiguous_aligned() use memory::malloc_large()
only."
Signed-off-by: Avi Kivity <[email protected]>
Currently, free(v) uses the offset of an objectwithin a page (o = v & 0xfff) to determine which allocator is responsible for the page:
this scheme has a number of issues:
We can improve this by using information other than the offset within the page to determine the allocator. If we map physical memory multiple times (all aliases of each other), we can use virtual address bits 44:46 to determine the allocator.
The value of v[44:46] can be used as follows:
0 - mempool allocator
1 - page allocator (for objects between half a page and a page)
2 - half-page allocator (for objects exactly half a page, useful for network buffers)
3 - large objects
4-5 reserved
6 - early allocator objects
7 - debug allocator (using a non identity virtual:physical mapping)
The virtual memory map will now be
The text was updated successfully, but these errors were encountered: