From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MaVJN-0004OS-UV for qemu-devel@nongnu.org; Mon, 10 Aug 2009 09:53:18 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MaVJH-0004Nd-Ex for qemu-devel@nongnu.org; Mon, 10 Aug 2009 09:53:16 -0400 Received: from [199.232.76.173] (port=54895 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MaVJH-0004NX-6X for qemu-devel@nongnu.org; Mon, 10 Aug 2009 09:53:11 -0400 Received: from mail.gmx.net ([213.165.64.20]:33041) by monty-python.gnu.org with smtp (Exim 4.60) (envelope-from ) id 1MaVJG-0004Xu-Ck for qemu-devel@nongnu.org; Mon, 10 Aug 2009 09:53:10 -0400 From: "Jan-Simon =?utf-8?q?M=C3=B6ller?=" Subject: Re: [Qemu-devel] qemu-arm fails on test-mmap - take #2 Date: Mon, 10 Aug 2009 15:52:55 +0200 References: <200908100145.52476.dl9pf@gmx.de> In-Reply-To: MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_3YCgKtYX0U8EVW7" Message-Id: <200908101552.55755.dl9pf@gmx.de> List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "Kirill A. Shutemov" Cc: riku.voipio@iki.fi, qemu-devel@nongnu.org --Boundary-00=_3YCgKtYX0U8EVW7 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline 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-deve= l% >5D_%5BPATCH,_v2%5D_Rewrite_mmap_find_vma%28%29_to_work_fine_on_64-bit_host= s_ >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=C3=B6ller Original post:=20 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-b= it_targets Attachement: Patch rebased to trunk. Best, Jan-Simon --Boundary-00=_3YCgKtYX0U8EVW7 Content-Type: text/x-diff; charset="iso 8859-15"; name="qemu-0.11-git-user-linux-mmap_find_vma.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="qemu-0.11-git-user-linux-mmap_find_vma.patch" 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 */ --Boundary-00=_3YCgKtYX0U8EVW7--