From owner-svn-src-all@freebsd.org Wed Jun 28 04:02:38 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 25380D97568; Wed, 28 Jun 2017 04:02:38 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 00DEC646BE; Wed, 28 Jun 2017 04:02:37 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v5S42bVK089190; Wed, 28 Jun 2017 04:02:37 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v5S42bQx089187; Wed, 28 Jun 2017 04:02:37 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201706280402.v5S42bQx089187@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Wed, 28 Jun 2017 04:02:37 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r320430 - head/sys/vm X-SVN-Group: head X-SVN-Commit-Author: kib X-SVN-Commit-Paths: head/sys/vm X-SVN-Commit-Revision: 320430 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Jun 2017 04:02:38 -0000 Author: kib Date: Wed Jun 28 04:02:36 2017 New Revision: 320430 URL: https://svnweb.freebsd.org/changeset/base/320430 Log: Treat the addr argument for mmap(2) request without MAP_FIXED flag as a hint. Right now, for non-fixed mmap(2) calls, addr is de-facto interpreted as the absolute minimal address of the range where the mapping is created. The VA allocator only allocates in the range [addr, VM_MAXUSER_ADDRESS]. This is too restrictive, the mmap(2) call might unduly fail if there is no free addresses above addr but a lot of usable space below it. Lift this implementation limitation by allocating VA in two passes. First, try to allocate above addr, as before. If that fails, do the second pass with less restrictive constraints for the start of allocation by specifying minimal allocation address at the max bss end, if this limit is less than addr. One important case where this change makes a difference is the allocation of the stacks for new threads in libthr. Under some configuration conditions, libthr tries to hint kernel to reuse the main thread stack grow area for the new stacks. This cannot work by design now after grow area is converted to stack, and there is no unallocated VA above the main stack. Interpreting requested stack base address as the hint provides compatibility with old libthr and with (mis-)configured current libthr. Reviewed by: alc Tested by: dim (previous version) Sponsored by: The FreeBSD Foundation MFC after: 1 week Modified: head/sys/vm/vm_map.c head/sys/vm/vm_map.h head/sys/vm/vm_mmap.c Modified: head/sys/vm/vm_map.c ============================================================================== --- head/sys/vm/vm_map.c Wed Jun 28 04:01:29 2017 (r320429) +++ head/sys/vm/vm_map.c Wed Jun 28 04:02:36 2017 (r320430) @@ -1556,6 +1556,25 @@ again: return (result); } +int +vm_map_find_min(vm_map_t map, vm_object_t object, vm_ooffset_t offset, + vm_offset_t *addr, vm_size_t length, vm_offset_t min_addr, + vm_offset_t max_addr, int find_space, vm_prot_t prot, vm_prot_t max, + int cow) +{ + vm_offset_t hint; + int rv; + + hint = *addr; + for (;;) { + rv = vm_map_find(map, object, offset, addr, length, max_addr, + find_space, prot, max, cow); + if (rv == KERN_SUCCESS || min_addr >= hint) + return (rv); + *addr = min_addr; + } +} + /* * vm_map_simplify_entry: * Modified: head/sys/vm/vm_map.h ============================================================================== --- head/sys/vm/vm_map.h Wed Jun 28 04:01:29 2017 (r320429) +++ head/sys/vm/vm_map.h Wed Jun 28 04:02:36 2017 (r320430) @@ -372,6 +372,8 @@ vm_map_t vm_map_create(pmap_t, vm_offset_t, vm_offset_ int vm_map_delete(vm_map_t, vm_offset_t, vm_offset_t); int vm_map_find(vm_map_t, vm_object_t, vm_ooffset_t, vm_offset_t *, vm_size_t, vm_offset_t, int, vm_prot_t, vm_prot_t, int); +int vm_map_find_min(vm_map_t, vm_object_t, vm_ooffset_t, vm_offset_t *, + vm_size_t, vm_offset_t, vm_offset_t, int, vm_prot_t, vm_prot_t, int); int vm_map_fixed(vm_map_t, vm_object_t, vm_ooffset_t, vm_offset_t, vm_size_t, vm_prot_t, vm_prot_t, int); int vm_map_findspace (vm_map_t, vm_offset_t, vm_size_t, vm_offset_t *); Modified: head/sys/vm/vm_mmap.c ============================================================================== --- head/sys/vm/vm_mmap.c Wed Jun 28 04:01:29 2017 (r320429) +++ head/sys/vm/vm_mmap.c Wed Jun 28 04:02:36 2017 (r320430) @@ -1438,10 +1438,12 @@ vm_mmap_object(vm_map_t map, vm_offset_t *addr, vm_siz vm_prot_t maxprot, int flags, vm_object_t object, vm_ooffset_t foff, boolean_t writecounted, struct thread *td) { - boolean_t fitit; + boolean_t curmap, fitit; + vm_offset_t max_addr; int docow, error, findspace, rv; - if (map == &td->td_proc->p_vmspace->vm_map) { + curmap = map == &td->td_proc->p_vmspace->vm_map; + if (curmap) { PROC_LOCK(td->td_proc); if (map->size + size > lim_cur_proc(td->td_proc, RLIMIT_VMEM)) { PROC_UNLOCK(td->td_proc); @@ -1529,11 +1531,20 @@ vm_mmap_object(vm_map_t map, vm_offset_t *addr, vm_siz MAP_ALIGNMENT_SHIFT); else findspace = VMFS_OPTIMAL_SPACE; - rv = vm_map_find(map, object, foff, addr, size, + max_addr = 0; #ifdef MAP_32BIT - flags & MAP_32BIT ? MAP_32BIT_MAX_ADDR : + if ((flags & MAP_32BIT) != 0) + max_addr = MAP_32BIT_MAX_ADDR; #endif - 0, findspace, prot, maxprot, docow); + if (curmap) { + rv = vm_map_find_min(map, object, foff, addr, size, + round_page((vm_offset_t)td->td_proc->p_vmspace-> + vm_daddr + lim_max(td, RLIMIT_DATA)), max_addr, + findspace, prot, maxprot, docow); + } else { + rv = vm_map_find(map, object, foff, addr, size, + max_addr, findspace, prot, maxprot, docow); + } } else { rv = vm_map_fixed(map, object, foff, *addr, size, prot, maxprot, docow);