diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2023-07-07 21:40:46 +0100 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2023-07-15 08:02:32 +0100 |
commit | 4c13048e02d93985320e4a9651dc29577ba53f0e (patch) | |
tree | 330f119ba2721161ef032f327d2100307fbbb5a2 /linux-user | |
parent | f12294b5bd214232eb0b4be87fed35519f006182 (diff) | |
download | qemu-4c13048e02d93985320e4a9651dc29577ba53f0e.zip qemu-4c13048e02d93985320e4a9651dc29577ba53f0e.tar.gz qemu-4c13048e02d93985320e4a9651dc29577ba53f0e.tar.bz2 |
linux-user: Use page_find_range_empty for mmap_find_vma_reserved
Use the interval tree to find empty space, rather than
probing each page in turn.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20230707204054.8792-19-richard.henderson@linaro.org>
Diffstat (limited to 'linux-user')
-rw-r--r-- | linux-user/mmap.c | 52 |
1 files changed, 6 insertions, 46 deletions
diff --git a/linux-user/mmap.c b/linux-user/mmap.c index c4b2515..738b9b7 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -318,55 +318,15 @@ unsigned long last_brk; static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size, abi_ulong align) { - abi_ulong addr, end_addr, incr = qemu_host_page_size; - int prot; - bool looped = false; - - if (size > reserved_va) { - return (abi_ulong)-1; - } - - /* Note that start and size have already been aligned by mmap_find_vma. */ + target_ulong ret; - end_addr = start + size; - /* - * Start at the top of the address space, ignoring the last page. - * If reserved_va == UINT32_MAX, then end_addr wraps to 0, - * throwing the rest of the calculations off. - * TODO: rewrite using last_addr instead. - * TODO: use the interval tree instead of probing every page. - */ - if (start > reserved_va - size) { - end_addr = ((reserved_va - size) & -align) + size; - looped = true; + ret = page_find_range_empty(start, reserved_va, size, align); + if (ret == -1 && start > mmap_min_addr) { + /* Restart at the beginning of the address space. */ + ret = page_find_range_empty(mmap_min_addr, start - 1, size, align); } - /* Search downward from END_ADDR, checking to see if a page is in use. */ - addr = end_addr; - while (1) { - addr -= incr; - if (addr > end_addr) { - if (looped) { - /* Failure. The entire address space has been searched. */ - return (abi_ulong)-1; - } - /* Re-start at the top of the address space (see above). */ - addr = end_addr = ((reserved_va - size) & -align) + size; - looped = true; - } else { - prot = page_get_flags(addr); - if (prot) { - /* Page in use. Restart below this page. */ - addr = end_addr = ((addr - size) & -align) + size; - } else if (addr && addr + size == end_addr) { - /* Success! All pages between ADDR and END_ADDR are free. */ - if (start == mmap_next_start) { - mmap_next_start = addr; - } - return addr; - } - } - } + return ret; } /* |