Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 29 Jan 2001 16:27:37 -0700
From:      Drew Eckhardt <drew@PoohSticks.ORG>
To:        freebsd-hackers@freebsd.org
Subject:   Suboptimal mmap of devices on i86
Message-ID:  <200101292327.f0TNRbh22423@chopper.Poohsticks.ORG>

next in thread | raw e-mail | index | archive | help
On i86 boxes with 4M page capabilities, we want contiguous chunks
of physical address space for mmaped devices to use those larger pages 
when possible.

In practice, this doesn't happen in applications linked with shared
libraries when mmap() is used in the usual way with 0 as the address 
argument and no MAP_FIXED flag.

mmap() passes vm_mmap() a starting address after the heap.  vm_mmap() 
adjusts this with pmap_addr_hint(), and the result propogates down to 
vm_map_findspace().  When there's insufficient free space to map the 
object at the optimally aligned address because a shared library
is already there, vm_map_findspace() returns the first fit without
adjusting the starting address.

I tweaked my kernel as follows to get pmap_object_init_pt() functioning
as designed.  

--- old	Mon Jan 29 16:03:40 2001
+++ vm/vm_map.c	Fri Jan 26 18:47:24 2001
@@ -169,6 +169,8 @@
 static void vm_map_copy_entry __P((vm_map_t, vm_map_t, vm_map_entry_t,
 		vm_map_entry_t));
 static void vm_map_split __P((vm_map_entry_t));
+static int vm_map_findspace_for_object __P((vm_map_t, vm_object_t, vm_offset_t,
+		vm_size_t, vm_offset_t *));
 
 void
 vm_map_startup()
@@ -775,10 +777,20 @@
 /*
  * Find sufficient space for `length' bytes in the given map, starting at
  * `start'.  The map must be locked.  Returns 0 on success, 1 on no space.
+ * 
+ * This differs from the stock vm_map_findspace() in that we have an 
+ * additional parameter (object) which is used to get hints from the
+ * pmap layer which may result in stricter (coarser) alignment.
+ *
+ * FIXME: This should probably replace vm_map_findspace entirely.
+ * We may also want to revert to the historic behavior on failure, in the 
+ * rare event that we have space for the requested region but not at the
+ * optimal alignment suggested by pmap_addr_hint().
  */
-int
-vm_map_findspace(map, start, length, addr)
+static int
+vm_map_findspace_for_object(map, object, start, length, addr)
 	vm_map_t map;
+	vm_object_t object;
 	vm_offset_t start;
 	vm_size_t length;
 	vm_offset_t *addr;
@@ -811,6 +823,7 @@
 	 * gap between existing regions, or after the very last region.
 	 */
 	for (;; start = (entry = next)->end) {
+		start = pmap_addr_hint(object, start, length);
 		/*
 		 * Find the end of the proposed new region.  Be sure we didn't
 		 * go beyond the end of the map, or wrap around the address;
@@ -837,6 +850,21 @@
 }
 
 /*
+ * Find sufficient space for `length' bytes in the given map, starting at
+ * `start'.  The map must be locked.  Returns 0 on success, 1 on no space.
+ */
+int
+vm_map_findspace(map, start, length, addr)
+	vm_map_t map;
+	vm_offset_t start;
+	vm_size_t length;
+	vm_offset_t *addr;
+{
+	return (vm_map_findspace_for_object (map, NULL, start, length, 
+	    	addr));
+}
+
+/*
  *	vm_map_find finds an unallocated region in the target address
  *	map with the given length.  The search is defined to be
  *	first-fit from the specified address; the region found is
@@ -859,7 +887,8 @@
 
 	vm_map_lock(map);
 	if (find_space) {
-		if (vm_map_findspace(map, start, length, addr)) {
+		if (vm_map_findspace_for_object(map, object, start, length, 
+			addr)) {
 			vm_map_unlock(map);
 			if (map == kmem_map || map == mb_map)
 				splx(s);


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200101292327.f0TNRbh22423>