Subject: Re: deferred amap allocation (Re: CVS commit: src/sys/uvm)
To: None <chuq@chuq.com>
From: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
List: tech-kern
Date: 05/01/2005 19:49:16
hi,

> what does this do if a new, large map entry can be merged with an existing
> small map entry that has an amap allocated?  if the large one is 1 GB
> and the small one is one page, does this allocate amap space for the whole
> 1 GB?  that seems undesirable.  (I haven't looked at the code so maybe
> we avoid this somewhere else, but I thought I'd ask.)
> 
> -Chuck

i don't think it's a new problem.
how do you think about preventing amap extended beyond some threshold as
the following?  (UVM_AMAP_LARGE might be too small for this purpose.)

ideally we might be able to merge entries in fault handler.
although i don't want to put such complexity there.

YAMAMOTO Takashi

Index: uvm_map.c
===================================================================
--- uvm_map.c	(revision 1162)
+++ uvm_map.c	(working copy)
@@ -1052,7 +1052,7 @@ uvm_map_enter(struct vm_map *map, const 
 			error = amap_extend(prev_entry, size,
 			    amapwaitflag | AMAP_EXTEND_FORWARDS);
 			if (error)
-				goto done;
+				goto nomerge;
 		}
 
 		if (kmap)
@@ -1175,7 +1175,7 @@ forwardmerge:
 				error = amap_extend(prev_entry->next, size,
 				    amapwaitflag | AMAP_EXTEND_BACKWARDS);
 				if (error)
-					goto done;
+					goto nomerge;
 			}
 		}
 
Index: uvm_amap.c
===================================================================
--- uvm_amap.c	(revision 1163)
+++ uvm_amap.c	(working copy)
@@ -488,6 +488,11 @@ amap_extend(entry, addsize, flags)
 	 */
 
 	amap_unlock(amap);	/* unlock in case we sleep in malloc */
+
+	if (slotneed >= UVM_AMAP_LARGE) {
+		return E2BIG;
+	}
+
 	slotalloc = malloc_roundup(slotneed * sizeof(int)) / sizeof(int);
 #ifdef UVM_AMAP_PPREF
 	newppref = NULL;