Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved allocated object classification #87

Open
avikivity opened this issue Nov 7, 2013 · 1 comment
Open

Improved allocated object classification #87

avikivity opened this issue Nov 7, 2013 · 1 comment

Comments

@avikivity
Copy link
Member

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)

The virtual memory map will now be

0000_0000_0000_0000 - 0000_7fff_ffff_ffff kernel code and application virtual memory
ffff_8000_0000_0000 - ffff_8fff_ffff_ffff mempool (sub-page) objects
ffff_9000_0000_0000 - ffff_9fff_ffff_ffff page objects
ffff_a000_0000_0000 - ffff_afff_ffff_ffff halfpage objects
ffff_b000_0000_0000 - ffff_bfff_ffff_ffff large objects (> 1 page)
ffff_e000_0000_0000 - ffff_efff_ffff_ffff early allocator objects
ffff_f000_0000_0000 - ffff_ffff_ffff_ffff debug allocator objects
@nyh
Copy link
Contributor

nyh commented Nov 19, 2013

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.

avikivity pushed a commit that referenced this issue Nov 19, 2013
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]>
avikivity added a commit that referenced this issue Jun 8, 2014
"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]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants