All of lore.kernel.org
 help / color / mirror / Atom feed
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 */

      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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.