From owner-svn-src-all@FreeBSD.ORG Mon Jun 23 08:08:22 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id CE4C3CD5; Mon, 23 Jun 2014 08:08:22 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::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 BAC1F2A5C; Mon, 23 Jun 2014 08:08:22 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s5N88Mhj081704; Mon, 23 Jun 2014 08:08:22 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s5N88Mks081702; Mon, 23 Jun 2014 08:08:22 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201406230808.s5N88Mks081702@svn.freebsd.org> From: Konstantin Belousov Date: Mon, 23 Jun 2014 08:08:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r267772 - stable/10/sys/vm X-SVN-Group: stable-10 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.18 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: Mon, 23 Jun 2014 08:08:23 -0000 Author: kib Date: Mon Jun 23 08:08:22 2014 New Revision: 267772 URL: http://svnweb.freebsd.org/changeset/base/267772 Log: MFC r267254: Make mmap(MAP_STACK) search for the available address space. MFC r267497 (by alc): Use local variable instead of sgrowsiz. Modified: stable/10/sys/vm/vm_map.c stable/10/sys/vm/vm_mmap.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/vm/vm_map.c ============================================================================== --- stable/10/sys/vm/vm_map.c Mon Jun 23 07:58:41 2014 (r267771) +++ stable/10/sys/vm/vm_map.c Mon Jun 23 08:08:22 2014 (r267772) @@ -136,6 +136,9 @@ static void vm_map_entry_dispose(vm_map_ static void vm_map_zdtor(void *mem, int size, void *arg); static void vmspace_zdtor(void *mem, int size, void *arg); #endif +static int vm_map_stack_locked(vm_map_t map, vm_offset_t addrbos, + vm_size_t max_ssize, vm_size_t growsize, vm_prot_t prot, vm_prot_t max, + int cow); #define ENTRY_CHARGED(e) ((e)->cred != NULL || \ ((e)->object.vm_object != NULL && (e)->object.vm_object->cred != NULL && \ @@ -1399,11 +1402,19 @@ vm_map_fixed(vm_map_t map, vm_object_t o int result; end = start + length; + KASSERT((cow & (MAP_STACK_GROWS_DOWN | MAP_STACK_GROWS_UP)) == 0 || + object == NULL, + ("vm_map_fixed: non-NULL backing object for stack")); vm_map_lock(map); VM_MAP_RANGE_CHECK(map, start, end); (void) vm_map_delete(map, start, end); - result = vm_map_insert(map, object, offset, start, end, prot, - max, cow); + if ((cow & (MAP_STACK_GROWS_DOWN | MAP_STACK_GROWS_UP)) != 0) { + result = vm_map_stack_locked(map, start, length, sgrowsiz, + prot, max, cow); + } else { + result = vm_map_insert(map, object, offset, start, end, + prot, max, cow); + } vm_map_unlock(map); return (result); } @@ -1426,6 +1437,9 @@ vm_map_find(vm_map_t map, vm_object_t ob vm_offset_t alignment, initial_addr, start; int result; + KASSERT((cow & (MAP_STACK_GROWS_DOWN | MAP_STACK_GROWS_UP)) == 0 || + object == NULL, + ("vm_map_find: non-NULL backing object for stack")); if (find_space == VMFS_OPTIMAL_SPACE && (object == NULL || (object->flags & OBJ_COLORED) == 0)) find_space = VMFS_ANY_SPACE; @@ -1467,8 +1481,13 @@ again: start = *addr; } - result = vm_map_insert(map, object, offset, start, start + - length, prot, max, cow); + if ((cow & (MAP_STACK_GROWS_DOWN | MAP_STACK_GROWS_UP)) != 0) { + result = vm_map_stack_locked(map, start, length, + sgrowsiz, prot, max, cow); + } else { + result = vm_map_insert(map, object, offset, start, + start + length, prot, max, cow); + } } while (result == KERN_NO_SPACE && find_space != VMFS_NO_SPACE && find_space != VMFS_ANY_SPACE); vm_map_unlock(map); @@ -3334,11 +3353,43 @@ int vm_map_stack(vm_map_t map, vm_offset_t addrbos, vm_size_t max_ssize, vm_prot_t prot, vm_prot_t max, int cow) { + vm_size_t growsize, init_ssize; + rlim_t lmemlim, vmemlim; + int rv; + + growsize = sgrowsiz; + init_ssize = (max_ssize < growsize) ? max_ssize : growsize; + vm_map_lock(map); + PROC_LOCK(curproc); + lmemlim = lim_cur(curproc, RLIMIT_MEMLOCK); + vmemlim = lim_cur(curproc, RLIMIT_VMEM); + PROC_UNLOCK(curproc); + if (!old_mlock && map->flags & MAP_WIREFUTURE) { + if (ptoa(pmap_wired_count(map->pmap)) + init_ssize > lmemlim) { + rv = KERN_NO_SPACE; + goto out; + } + } + /* If we would blow our VMEM resource limit, no go */ + if (map->size + init_ssize > vmemlim) { + rv = KERN_NO_SPACE; + goto out; + } + rv = vm_map_stack_locked(map, addrbos, max_ssize, growsize, prot, + max, cow); +out: + vm_map_unlock(map); + return (rv); +} + +static int +vm_map_stack_locked(vm_map_t map, vm_offset_t addrbos, vm_size_t max_ssize, + vm_size_t growsize, vm_prot_t prot, vm_prot_t max, int cow) +{ vm_map_entry_t new_entry, prev_entry; vm_offset_t bot, top; - vm_size_t growsize, init_ssize; + vm_size_t init_ssize; int orient, rv; - rlim_t lmemlim, vmemlim; /* * The stack orientation is piggybacked with the cow argument. @@ -3354,34 +3405,11 @@ vm_map_stack(vm_map_t map, vm_offset_t a addrbos + max_ssize < addrbos) return (KERN_NO_SPACE); - growsize = sgrowsiz; init_ssize = (max_ssize < growsize) ? max_ssize : growsize; - PROC_LOCK(curproc); - lmemlim = lim_cur(curproc, RLIMIT_MEMLOCK); - vmemlim = lim_cur(curproc, RLIMIT_VMEM); - PROC_UNLOCK(curproc); - - vm_map_lock(map); - /* If addr is already mapped, no go */ - if (vm_map_lookup_entry(map, addrbos, &prev_entry)) { - vm_map_unlock(map); + if (vm_map_lookup_entry(map, addrbos, &prev_entry)) return (KERN_NO_SPACE); - } - - if (!old_mlock && map->flags & MAP_WIREFUTURE) { - if (ptoa(pmap_wired_count(map->pmap)) + init_ssize > lmemlim) { - vm_map_unlock(map); - return (KERN_NO_SPACE); - } - } - - /* If we would blow our VMEM resource limit, no go */ - if (map->size + init_ssize > vmemlim) { - vm_map_unlock(map); - return (KERN_NO_SPACE); - } /* * If we can't accomodate max_ssize in the current mapping, no go. @@ -3393,10 +3421,8 @@ vm_map_stack(vm_map_t map, vm_offset_t a * grow the stack. */ if ((prev_entry->next != &map->header) && - (prev_entry->next->start < addrbos + max_ssize)) { - vm_map_unlock(map); + (prev_entry->next->start < addrbos + max_ssize)) return (KERN_NO_SPACE); - } /* * We initially map a stack of only init_ssize. We will grow as @@ -3432,7 +3458,6 @@ vm_map_stack(vm_map_t map, vm_offset_t a new_entry->eflags |= MAP_ENTRY_GROWS_UP; } - vm_map_unlock(map); return (rv); } Modified: stable/10/sys/vm/vm_mmap.c ============================================================================== --- stable/10/sys/vm/vm_mmap.c Mon Jun 23 07:58:41 2014 (r267771) +++ stable/10/sys/vm/vm_mmap.c Mon Jun 23 08:08:22 2014 (r267772) @@ -1621,11 +1621,13 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, docow |= MAP_INHERIT_SHARE; if (writecounted) docow |= MAP_VN_WRITECOUNT; + if (flags & MAP_STACK) { + if (object != NULL) + return (EINVAL); + docow |= MAP_STACK_GROWS_DOWN; + } - if (flags & MAP_STACK) - rv = vm_map_stack(map, *addr, size, prot, maxprot, - docow | MAP_STACK_GROWS_DOWN); - else if (fitit) { + if (fitit) { if ((flags & MAP_ALIGNMENT_MASK) == MAP_ALIGNED_SUPER) findspace = VMFS_SUPER_SPACE; else if ((flags & MAP_ALIGNMENT_MASK) != 0) @@ -1638,9 +1640,10 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, flags & MAP_32BIT ? MAP_32BIT_MAX_ADDR : #endif 0, findspace, prot, maxprot, docow); - } else + } else { rv = vm_map_fixed(map, object, foff, *addr, size, - prot, maxprot, docow); + prot, maxprot, docow); + } if (rv == KERN_SUCCESS) { /*