Module Name:    src
Committed By:   martin
Date:           Thu Nov 14 12:07:12 UTC 2013

Modified Files:
        src/sys/kern: exec_elf.c kern_exec.c kern_proc.c
        src/sys/rump/librump/rumpkern: vm.c
        src/sys/sys: exec.h
        src/sys/uvm: uvm_extern.h uvm_map.c

Log Message:
As discussed on tech-kern: make TOPDOWN-VM runtime selectable per process
(offer MD code or emulations to override it).


To generate a diff of this commit:
cvs rdiff -u -r1.50 -r1.51 src/sys/kern/exec_elf.c
cvs rdiff -u -r1.363 -r1.364 src/sys/kern/kern_exec.c
cvs rdiff -u -r1.189 -r1.190 src/sys/kern/kern_proc.c
cvs rdiff -u -r1.144 -r1.145 src/sys/rump/librump/rumpkern/vm.c
cvs rdiff -u -r1.141 -r1.142 src/sys/sys/exec.h
cvs rdiff -u -r1.184 -r1.185 src/sys/uvm/uvm_extern.h
cvs rdiff -u -r1.326 -r1.327 src/sys/uvm/uvm_map.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/exec_elf.c
diff -u src/sys/kern/exec_elf.c:1.50 src/sys/kern/exec_elf.c:1.51
--- src/sys/kern/exec_elf.c:1.50	Mon Nov 11 15:22:11 2013
+++ src/sys/kern/exec_elf.c	Thu Nov 14 12:07:11 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: exec_elf.c,v 1.50 2013/11/11 15:22:11 martin Exp $	*/
+/*	$NetBSD: exec_elf.c,v 1.51 2013/11/14 12:07:11 martin Exp $	*/
 
 /*-
  * Copyright (c) 1994, 2000, 2005 The NetBSD Foundation, Inc.
@@ -57,7 +57,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.50 2013/11/11 15:22:11 martin Exp $");
+__KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.51 2013/11/14 12:07:11 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_pax.h"
@@ -422,14 +422,15 @@ elf_load_file(struct lwp *l, struct exec
 	p = l->l_proc;
 
 	KASSERT(p->p_vmspace);
-	if (__predict_true(p->p_vmspace != proc0.p_vmspace))
+	if (__predict_true(p->p_vmspace != proc0.p_vmspace)) {
 		use_topdown = p->p_vmspace->vm_map.flags & VM_MAP_TOPDOWN;
-	else
+	} else {
 #ifdef __USING_TOPDOWN_VM
-		use_topdown = true;
+		use_topdown = epp->ep_flags & EXEC_TOPDOWN_VM;
 #else
 		use_topdown = false;
 #endif
+	}
 
 	/*
 	 * 1. open file

Index: src/sys/kern/kern_exec.c
diff -u src/sys/kern/kern_exec.c:1.363 src/sys/kern/kern_exec.c:1.364
--- src/sys/kern/kern_exec.c:1.363	Thu Sep 12 19:01:38 2013
+++ src/sys/kern/kern_exec.c	Thu Nov 14 12:07:11 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_exec.c,v 1.363 2013/09/12 19:01:38 christos Exp $	*/
+/*	$NetBSD: kern_exec.c,v 1.364 2013/11/14 12:07:11 martin Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -59,7 +59,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.363 2013/09/12 19:01:38 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.364 2013/11/14 12:07:11 martin Exp $");
 
 #include "opt_exec.h"
 #include "opt_execfmt.h"
@@ -112,6 +112,15 @@ __KERNEL_RCSID(0, "$NetBSD: kern_exec.c,
 
 #include <compat/common/compat_util.h>
 
+#ifndef MD_TOPDOWN_INIT
+#error MD_TOPDOWN_INIT fehlt
+#ifdef __USING_TOPDOWN_VM
+#define	MD_TOPDOWN_INIT(epp)	(epp)->ep_flags |= EXEC_TOPDOWN_VM
+#else
+#define	MD_TOPDOWN_INIT(epp)
+#endif
+#endif
+
 static int exec_sigcode_map(struct proc *, const struct emul *);
 
 #ifdef DEBUG_EXEC
@@ -653,6 +662,7 @@ execve_loadvm(struct lwp *l, const char 
 	data->ed_pack.ep_vmcmds.evs_used = 0;
 	data->ed_pack.ep_vap = &data->ed_attr;
 	data->ed_pack.ep_flags = 0;
+	MD_TOPDOWN_INIT(&data->ed_pack);
 	data->ed_pack.ep_emul_root = NULL;
 	data->ed_pack.ep_interp = NULL;
 	data->ed_pack.ep_esch = NULL;
@@ -933,10 +943,12 @@ execve_runproc(struct lwp *l, struct exe
 	 */
 	if (is_spawn)
 		uvmspace_spawn(l, data->ed_pack.ep_vm_minaddr,
-		    data->ed_pack.ep_vm_maxaddr);
+		    data->ed_pack.ep_vm_maxaddr,
+		    data->ed_pack.ep_flags & EXEC_TOPDOWN_VM);
 	else
 		uvmspace_exec(l, data->ed_pack.ep_vm_minaddr,
-		    data->ed_pack.ep_vm_maxaddr);
+		    data->ed_pack.ep_vm_maxaddr,
+		    data->ed_pack.ep_flags & EXEC_TOPDOWN_VM);
 
 	/* record proc's vnode, for use by procfs and others */
         if (p->p_textvp)

Index: src/sys/kern/kern_proc.c
diff -u src/sys/kern/kern_proc.c:1.189 src/sys/kern/kern_proc.c:1.190
--- src/sys/kern/kern_proc.c:1.189	Fri Oct 25 15:52:57 2013
+++ src/sys/kern/kern_proc.c	Thu Nov 14 12:07:11 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_proc.c,v 1.189 2013/10/25 15:52:57 martin Exp $	*/
+/*	$NetBSD: kern_proc.c,v 1.190 2013/11/14 12:07:11 martin Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.189 2013/10/25 15:52:57 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.190 2013/11/14 12:07:11 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_kstack.h"
@@ -483,7 +483,13 @@ proc0_init(void)
 	 * share proc0's vmspace, and thus, the kernel pmap.
 	 */
 	uvmspace_init(&vmspace0, pmap_kernel(), round_page(VM_MIN_ADDRESS),
-	    trunc_page(VM_MAX_ADDRESS));
+	    trunc_page(VM_MAX_ADDRESS),
+#ifdef __USING_TOPDOWN_VM
+	    true
+#else
+	    false
+#endif
+	    );
 
 	/* Initialize signal state for proc0. XXX IPL_SCHED */
 	mutex_init(&p->p_sigacts->sa_mutex, MUTEX_DEFAULT, IPL_SCHED);

Index: src/sys/rump/librump/rumpkern/vm.c
diff -u src/sys/rump/librump/rumpkern/vm.c:1.144 src/sys/rump/librump/rumpkern/vm.c:1.145
--- src/sys/rump/librump/rumpkern/vm.c:1.144	Tue Apr 30 16:03:44 2013
+++ src/sys/rump/librump/rumpkern/vm.c	Thu Nov 14 12:07:11 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: vm.c,v 1.144 2013/04/30 16:03:44 pooka Exp $	*/
+/*	$NetBSD: vm.c,v 1.145 2013/11/14 12:07:11 martin Exp $	*/
 
 /*
  * Copyright (c) 2007-2011 Antti Kantee.  All Rights Reserved.
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm.c,v 1.144 2013/04/30 16:03:44 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm.c,v 1.145 2013/11/14 12:07:11 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -363,7 +363,8 @@ uvm_init(void)
 }
 
 void
-uvmspace_init(struct vmspace *vm, struct pmap *pmap, vaddr_t vmin, vaddr_t vmax)
+uvmspace_init(struct vmspace *vm, struct pmap *pmap, vaddr_t vmin, vaddr_t vmax,
+    bool topdown)
 {
 
 	vm->vm_map.pmap = pmap_kernel();

Index: src/sys/sys/exec.h
diff -u src/sys/sys/exec.h:1.141 src/sys/sys/exec.h:1.142
--- src/sys/sys/exec.h:1.141	Wed Oct 30 23:32:30 2013
+++ src/sys/sys/exec.h	Thu Nov 14 12:07:11 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: exec.h,v 1.141 2013/10/30 23:32:30 joerg Exp $	*/
+/*	$NetBSD: exec.h,v 1.142 2013/11/14 12:07:11 martin Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -226,6 +226,7 @@ struct exec_package {
 #define	EXEC_DESTR	0x0010		/* destructive ops performed */
 #define	EXEC_32		0x0020		/* 32-bit binary emulation */
 #define	EXEC_FORCEAUX	0x0040		/* always use ELF AUX vector */
+#define	EXEC_TOPDOWN_VM	0x0080		/* may use top-down VM layout */
 
 struct exec_vmcmd {
 	int	(*ev_proc)(struct lwp *, struct exec_vmcmd *);

Index: src/sys/uvm/uvm_extern.h
diff -u src/sys/uvm/uvm_extern.h:1.184 src/sys/uvm/uvm_extern.h:1.185
--- src/sys/uvm/uvm_extern.h:1.184	Sat Sep  1 00:26:37 2012
+++ src/sys/uvm/uvm_extern.h	Thu Nov 14 12:07:11 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvm_extern.h,v 1.184 2012/09/01 00:26:37 matt Exp $	*/
+/*	$NetBSD: uvm_extern.h,v 1.185 2013/11/14 12:07:11 martin Exp $	*/
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -643,11 +643,11 @@ bool			uvm_map_checkprot(struct vm_map *
 			    vaddr_t, vm_prot_t);
 int			uvm_map_protect(struct vm_map *, vaddr_t,
 			    vaddr_t, vm_prot_t, bool);
-struct vmspace		*uvmspace_alloc(vaddr_t, vaddr_t);
+struct vmspace		*uvmspace_alloc(vaddr_t, vaddr_t, bool);
 void			uvmspace_init(struct vmspace *, struct pmap *,
-			    vaddr_t, vaddr_t);
-void			uvmspace_exec(struct lwp *, vaddr_t, vaddr_t);
-void			uvmspace_spawn(struct lwp *, vaddr_t, vaddr_t);
+			    vaddr_t, vaddr_t, bool);
+void			uvmspace_exec(struct lwp *, vaddr_t, vaddr_t, bool);
+void			uvmspace_spawn(struct lwp *, vaddr_t, vaddr_t, bool);
 struct vmspace		*uvmspace_fork(struct vmspace *);
 void			uvmspace_addref(struct vmspace *);
 void			uvmspace_free(struct vmspace *);

Index: src/sys/uvm/uvm_map.c
diff -u src/sys/uvm/uvm_map.c:1.326 src/sys/uvm/uvm_map.c:1.327
--- src/sys/uvm/uvm_map.c:1.326	Fri Oct 25 20:25:25 2013
+++ src/sys/uvm/uvm_map.c	Thu Nov 14 12:07:11 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvm_map.c,v 1.326 2013/10/25 20:25:25 martin Exp $	*/
+/*	$NetBSD: uvm_map.c,v 1.327 2013/11/14 12:07:11 martin Exp $	*/
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.326 2013/10/25 20:25:25 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.327 2013/11/14 12:07:11 martin Exp $");
 
 #include "opt_ddb.h"
 #include "opt_uvmhist.h"
@@ -3927,13 +3927,13 @@ uvm_map_checkprot(struct vm_map *map, va
  * - refcnt set to 1, rest must be init'd by caller
  */
 struct vmspace *
-uvmspace_alloc(vaddr_t vmin, vaddr_t vmax)
+uvmspace_alloc(vaddr_t vmin, vaddr_t vmax, bool topdown)
 {
 	struct vmspace *vm;
 	UVMHIST_FUNC("uvmspace_alloc"); UVMHIST_CALLED(maphist);
 
 	vm = pool_cache_get(&uvm_vmspace_cache, PR_WAITOK);
-	uvmspace_init(vm, NULL, vmin, vmax);
+	uvmspace_init(vm, NULL, vmin, vmax, topdown);
 	UVMHIST_LOG(maphist,"<- done (vm=0x%x)", vm,0,0,0);
 	return (vm);
 }
@@ -3945,15 +3945,14 @@ uvmspace_alloc(vaddr_t vmin, vaddr_t vma
  * - refcnt set to 1, rest must be init'd by caller
  */
 void
-uvmspace_init(struct vmspace *vm, struct pmap *pmap, vaddr_t vmin, vaddr_t vmax)
+uvmspace_init(struct vmspace *vm, struct pmap *pmap, vaddr_t vmin,
+    vaddr_t vmax, bool topdown)
 {
 	UVMHIST_FUNC("uvmspace_init"); UVMHIST_CALLED(maphist);
 
 	memset(vm, 0, sizeof(*vm));
 	uvm_map_setup(&vm->vm_map, vmin, vmax, VM_MAP_PAGEABLE
-#ifdef __USING_TOPDOWN_VM
-	    | VM_MAP_TOPDOWN
-#endif
+	    | (topdown ? VM_MAP_TOPDOWN : 0)
 	    );
 	if (pmap)
 		pmap_reference(pmap);
@@ -4016,7 +4015,7 @@ uvmspace_unshare(struct lwp *l)
  */
 
 void
-uvmspace_spawn(struct lwp *l, vaddr_t start, vaddr_t end)
+uvmspace_spawn(struct lwp *l, vaddr_t start, vaddr_t end, bool topdown)
 {
 	struct proc *p = l->l_proc;
 	struct vmspace *nvm;
@@ -4025,7 +4024,7 @@ uvmspace_spawn(struct lwp *l, vaddr_t st
 	cpu_vmspace_exec(l, start, end);
 #endif
 
-	nvm = uvmspace_alloc(start, end);
+	nvm = uvmspace_alloc(start, end, topdown);
 	kpreempt_disable();
 	p->p_vmspace = nvm;
 	pmap_activate(l);
@@ -4037,7 +4036,7 @@ uvmspace_spawn(struct lwp *l, vaddr_t st
  */
 
 void
-uvmspace_exec(struct lwp *l, vaddr_t start, vaddr_t end)
+uvmspace_exec(struct lwp *l, vaddr_t start, vaddr_t end, bool topdown)
 {
 	struct proc *p = l->l_proc;
 	struct vmspace *nvm, *ovm = p->p_vmspace;
@@ -4053,11 +4052,14 @@ uvmspace_exec(struct lwp *l, vaddr_t sta
 	 * see if more than one process is using this vmspace...
 	 */
 
-	if (ovm->vm_refcnt == 1) {
+	if (ovm->vm_refcnt == 1
+	    && topdown == ((ovm->vm_map.flags & VM_MAP_TOPDOWN) != 0)) {
 
 		/*
 		 * if p is the only process using its vmspace then we can safely
 		 * recycle that vmspace for the program that is being exec'd.
+		 * But only if TOPDOWN matches the requested value for the new
+		 * vm space!
 		 */
 
 #ifdef SYSVSHM
@@ -4099,7 +4101,7 @@ uvmspace_exec(struct lwp *l, vaddr_t sta
 		 * for p
 		 */
 
-		nvm = uvmspace_alloc(start, end);
+		nvm = uvmspace_alloc(start, end, topdown);
 
 		/*
 		 * install new vmspace and drop our ref to the old one.
@@ -4203,7 +4205,8 @@ uvmspace_fork(struct vmspace *vm1)
 
 	vm_map_lock(old_map);
 
-	vm2 = uvmspace_alloc(vm_map_min(old_map), vm_map_max(old_map));
+	vm2 = uvmspace_alloc(vm_map_min(old_map), vm_map_max(old_map),
+	    vm1->vm_map.flags & VM_MAP_TOPDOWN);
 	memcpy(&vm2->vm_startcopy, &vm1->vm_startcopy,
 	    (char *) (vm1 + 1) - (char *) &vm1->vm_startcopy);
 	new_map = &vm2->vm_map;		  /* XXX */

Reply via email to