From: "Jan-Simon Möller" <dl9pf@gmx.de>
To: "Kirill A. Shutemov" <kirill@shutemov.name>
Cc: riku.voipio@iki.fi, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] qemu-arm fails on test-mmap - take #2
Date: Mon, 10 Aug 2009 15:52:55 +0200 [thread overview]
Message-ID: <200908101552.55755.dl9pf@gmx.de> (raw)
In-Reply-To: <cc557aab0908092333n1e2b3aa3l2d703352297e83a6@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 988 bytes --]
Am Montag 10 August 2009 08:33:38 schrieb Kirill A. Shutemov:
> > Now my question is: how is the data of the already blocked pages
> > processed/aquired ? It seems to me that the pages get "lost" somewhere.
>
> Current mmap() implementation requires /proc to obtain all mappings.
>
> I have alternative implementation of mmap_find_vma() which doesn't
> require /proc:
>
> http://www.archivum.info/qemu-devel@nongnu.org/2008-10/01118/%5BQemu-devel%
>5D_%5BPATCH,_v2%5D_Rewrite_mmap_find_vma%28%29_to_work_fine_on_64-bit_hosts_
>with_32-bit_targets
>
> It is probably out of date.
This does the trick ! I've attached a version against trunk.
@Riku: can we apply this to git ?
Acked-by: Jan-Simon Möller <dl9pf@gmx.de>
Original post:
http://www.archivum.info/qemu-devel%40nongnu.org/2008-10/01118/[Qemu-devel]_[PATCH,_v2]_Rewrite_mmap_find_vma()_to_work_fine_on_64-bit_hosts_with_32-bit_targets
Attachement:
Patch rebased to trunk.
Best,
Jan-Simon
[-- Attachment #2: qemu-0.11-git-user-linux-mmap_find_vma.patch --]
[-- Type: text/x-diff, Size: 3284 bytes --]
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 6f300a0..8cec230 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -275,52 +275,59 @@ abi_ulong mmap_next_start = 0x40000000;
unsigned long last_brk;
-/* find a free memory area of size 'size'. The search starts at
- 'start'. If 'start' == 0, then a default start address is used.
- Return -1 if error.
-*/
-/* page_init() marks pages used by the host as reserved to be sure not
- to use them. */
-abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
+/*
+ * Find and reserve a free memory area of size 'size'. The search
+ * starts at 'start'.
+ * It must be called with mmap_lock() held.
+ * Return -1 if error.
+ */
+abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
{
- abi_ulong addr, addr1, addr_start;
- int prot;
- unsigned long new_brk;
-
- new_brk = (unsigned long)sbrk(0);
- if (last_brk && last_brk < new_brk && last_brk == (target_ulong)last_brk) {
- /* This is a hack to catch the host allocating memory with brk().
- If it uses mmap then we loose.
- FIXME: We really want to avoid the host allocating memory in
- the first place, and maybe leave some slack to avoid switching
- to mmap. */
- page_set_flags(last_brk & TARGET_PAGE_MASK,
- TARGET_PAGE_ALIGN(new_brk),
- PAGE_RESERVED);
- }
- last_brk = new_brk;
+ void *ptr;
+ abi_ulong addr;
size = HOST_PAGE_ALIGN(size);
- start = start & qemu_host_page_mask;
+ start &= qemu_host_page_mask;
+
+ /* If 'start' == 0, then a default start address is used. */
+ if (start == 0)
+ start = mmap_next_start;
+
addr = start;
- if (addr == 0)
- addr = mmap_next_start;
- addr_start = addr;
+
for(;;) {
- prot = 0;
- for(addr1 = addr; addr1 < (addr + size); addr1 += TARGET_PAGE_SIZE) {
- prot |= page_get_flags(addr1);
- }
- if (prot == 0)
+ /*
+ * Reserve needed memory area to avoid a race.
+ * It should be discarded using:
+ * - mmap() with MAP_FIXED flag
+ * - mremap() with MREMAP_FIXED flag
+ * - shmat() with SHM_REMAP flag
+ */
+ ptr = mmap((void *)(unsigned long)addr, size, PROT_NONE,
+ MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0);
+
+ /* ENOMEM, if host address space has no memory */
+ if (ptr == MAP_FAILED)
+ return (abi_ulong)-1;
+
+ /* If address fits target address space we've found what we need */
+ if ((unsigned long)ptr + size - 1 <= (abi_ulong)-1)
break;
+
+ /* Unmap and try again with new page */
+ munmap(ptr, size);
addr += qemu_host_page_size;
- /* we found nothing */
- if (addr == addr_start)
+
+ /* ENOMEM if we check whole of target address space */
+ if (addr == start)
return (abi_ulong)-1;
}
- if (start == 0)
- mmap_next_start = addr + size;
- return addr;
+
+ /* Update default start address */
+ if (start == mmap_next_start)
+ mmap_next_start = (unsigned long)ptr + size;
+
+ return h2g(ptr);
}
/* NOTE: all the constants are the HOST ones */
prev parent reply other threads:[~2009-08-10 13:53 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-09 23:45 [Qemu-devel] qemu-arm fails on test-mmap - take #2 Jan-Simon Möller
2009-08-10 2:09 ` Jan-Simon Möller
2009-08-10 8:33 ` [Qemu-devel] qemu-arm fails on test-mmap Martin Mohring
[not found] ` <cc557aab0908092333n1e2b3aa3l2d703352297e83a6@mail.gmail.com>
2009-08-10 13:52 ` Jan-Simon Möller [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200908101552.55755.dl9pf@gmx.de \
--to=dl9pf@gmx.de \
--cc=kirill@shutemov.name \
--cc=qemu-devel@nongnu.org \
--cc=riku.voipio@iki.fi \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).