Subject: PROT_EXEC mappings of vnodes -> VTEXT
To: None <tech-kern@netbsd.org>
From: Jason R Thorpe <thorpej@wasabisystems.com>
List: tech-kern
Date: 10/29/2001 15:01:38
--NMuMz9nt05w80d4+
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

So, Perry Metzger asked me to look into this today, and I cooked up
a patch that does:

	If a PROT_EXEC mapping for a vnode is established, mark
	the vnode as VTEXT.

	If a VA range has its protection changed to include PROT_EXEC,
	mark all vnodes mapped by the VA range as VTEXT.

The upshot of this is that dynamically loaded objects (both normal
shared libraries as well as other dlopen()'d objects) will be considered
as "text" by the pagedaemon, like normal executable images are.  This
changes how the pagedaemon considers the vnode's pages for replacement.

Perry reports that the behavior of his system under heavy filesystem
I/O load is much better (that is, once he tunes vm.vtextmin up to
around 30% or so).  Without my patch, tuning up vtextmin didn't make
much difference for him, since libc, etc. were still getting tossed
out when the file system wanted pages.

I'm going to go ahead and commit the patch -- eventually, we might want
to consider entirely different page replacement algorithms, but this is
a fair stop-gap for now, and seems logical when you consider that shlibs
are effectively part of the executable images that are already marked as
VTEXT by the kernels' exec code.

-- 
        -- Jason R. Thorpe <thorpej@wasabisystems.com>

--NMuMz9nt05w80d4+
Content-Type: text/plain; charset=us-ascii
Content-Description: vtext.patch
Content-Disposition: attachment; filename=foo

Index: uvm_map.c
===================================================================
RCS file: /cvsroot/syssrc/sys/uvm/uvm_map.c,v
retrieving revision 1.108
diff -c -r1.108 uvm_map.c
*** uvm_map.c	2001/09/23 06:35:30	1.108
--- uvm_map.c	2001/10/29 22:55:43
***************
*** 81,86 ****
--- 81,87 ----
  #include <sys/malloc.h>
  #include <sys/pool.h>
  #include <sys/kernel.h>
+ #include <sys/vnode.h>
  
  #ifdef SYSVSHM
  #include <sys/shm.h>
***************
*** 1827,1832 ****
--- 1828,1847 ----
  			/* update pmap! */
  			pmap_protect(map->pmap, current->start, current->end,
  			    current->protection & MASK(entry));
+ 
+ 			/*
+ 			 * If this entry points at a vnode, and the
+ 			 * protection includes VM_PROT_EXECUTE, mark
+ 			 * the vnode as VTEXT.
+ 			 */
+ 			if (UVM_ET_ISOBJ(current)) {
+ 				struct uvm_object *uobj =
+ 				    current->object.uvm_obj;
+ 
+ 				if (UVM_OBJ_IS_VNODE(uobj) &&
+ 				    (current->protection & VM_PROT_EXECUTE))
+ 					vn_marktext((struct vnode *) uobj);
+ 			}
  		}
  
  		/*
Index: uvm_mmap.c
===================================================================
RCS file: /cvsroot/syssrc/sys/uvm/uvm_mmap.c,v
retrieving revision 1.56
diff -c -r1.56 uvm_mmap.c
*** uvm_mmap.c	2001/09/15 20:36:46	1.56
--- uvm_mmap.c	2001/10/29 22:55:44
***************
*** 1069,1074 ****
--- 1069,1081 ----
  
  			/* XXX for now, attach doesn't gain a ref */
  			VREF(vp);
+ 
+ 			/*
+ 			 * If the vnode is being mapped with PROT_EXEC,
+ 			 * then mark it as text.
+ 			 */
+ 			if (prot & PROT_EXEC)
+ 				vn_marktext(vp);
  		} else {
  			uobj = udv_attach((void *) &vp->v_rdev,
  			    (flags & MAP_SHARED) ? maxprot :

--NMuMz9nt05w80d4+--