Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 23 Jun 2012 01:30:52 +0000 (UTC)
From:      Attilio Rao <attilio@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r237466 - user/attilio/vmcontention/sys/vm
Message-ID:  <201206230130.q5N1Uqij011519@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: attilio
Date: Sat Jun 23 01:30:51 2012
New Revision: 237466
URL: http://svn.freebsd.org/changeset/base/237466

Log:
  Give vm_radix_lookupn() a way to specify that the whole range has been
  exhausted while searching and when a "maximum" value is passed as end
  (or end == 0).
  This allow for avoiding starting address overflow while searching
  through and avoids livelock with "start" wrapping up to "end".
  
  Reported by:	pho (supposedly)

Modified:
  user/attilio/vmcontention/sys/vm/vm_object.c
  user/attilio/vmcontention/sys/vm/vm_radix.c
  user/attilio/vmcontention/sys/vm/vm_radix.h

Modified: user/attilio/vmcontention/sys/vm/vm_object.c
==============================================================================
--- user/attilio/vmcontention/sys/vm/vm_object.c	Sat Jun 23 01:08:46 2012	(r237465)
+++ user/attilio/vmcontention/sys/vm/vm_object.c	Sat Jun 23 01:30:51 2012	(r237466)
@@ -679,6 +679,7 @@ vm_object_terminate(vm_object_t object)
 	vm_page_t pa[VM_RADIX_STACK];
 	vm_page_t p;
 	vm_pindex_t start;
+	u_int exhausted;
 	int n, i;
 
 	VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
@@ -725,8 +726,10 @@ vm_object_terminate(vm_object_t object)
 	 * the object, the page and object are reset to any empty state. 
 	 */
 	start = 0;
-	while ((n = vm_radix_lookupn(&object->rtree, start, 0, VM_RADIX_ANY,
-	    (void **)pa, VM_RADIX_STACK, &start)) != 0) {
+	exhausted = 0;
+	while (exhausted == 0 && (n = vm_radix_lookupn(&object->rtree, start,
+	    0, VM_RADIX_ANY, (void **)pa, VM_RADIX_STACK, &start,
+	    &exhausted)) != 0) {
 		for (i = 0; i < n; i++) {
 			p = pa[i];
 			/*
@@ -1315,6 +1318,7 @@ vm_object_split(vm_map_entry_t entry)
 	vm_object_t orig_object, new_object, source;
 	vm_pindex_t idx, offidxstart, start;
 	vm_size_t size;
+	u_int exhausted;
 	int i, n;
 
 	orig_object = entry->object.vm_object;
@@ -1370,9 +1374,10 @@ vm_object_split(vm_map_entry_t entry)
 	}
 	start = offidxstart;
 retry:
-	while ((n = vm_radix_lookupn(&orig_object->rtree, start,
-	    offidxstart + size, VM_RADIX_ANY, (void **)ma, VM_RADIX_STACK,
-	    &start)) != 0) {
+	exhausted = 0;
+	while (exhausted == 0 && (n = vm_radix_lookupn(&orig_object->rtree,
+	    start, offidxstart + size, VM_RADIX_ANY, (void **)ma,
+	    VM_RADIX_STACK, &start, &exhausted)) != 0) {
 		for (i = 0; i < n; i++) {
 			m = ma[i];
 			idx = m->pindex - offidxstart;
@@ -1457,6 +1462,7 @@ vm_object_backing_scan(vm_object_t objec
 	vm_object_t backing_object;
 	vm_pindex_t backing_offset_index, new_pindex;
 	vm_pindex_t start;
+	u_int exhausted;
 	int color, i, n;
 	int r = 1;
 
@@ -1495,13 +1501,15 @@ vm_object_backing_scan(vm_object_t objec
 restart:
 	start = 0;
 	i = n = VM_RADIX_STACK;
+	exhausted = 0;
 	for (;;) {
 		if (i == n) {
 			if (n < VM_RADIX_STACK)
 				break;
-			if ((n = vm_radix_lookupn(&backing_object->rtree,
+			if (exhausted != 0 &&
+			    (n = vm_radix_lookupn(&backing_object->rtree,
 			    start, 0, color, (void **)pa, VM_RADIX_STACK,
-			    &start)) == 0)
+			    &start, &exhausted)) == 0)
 				break;
 			i = 0;
 		}
@@ -1909,6 +1917,7 @@ vm_object_page_remove(vm_object_t object
 	struct vnode *vp;
 	vm_page_t pa[VM_RADIX_STACK];
 	vm_page_t p;
+	u_int exhausted;
 	int i, n;
 	int wirings;
 
@@ -1921,8 +1930,10 @@ vm_object_page_remove(vm_object_t object
 	vp = NULL;
 	vm_object_pip_add(object, 1);
 restart:
-	while ((n = vm_radix_lookupn(&object->rtree, start, end, VM_RADIX_ANY,
-	    (void **)pa, VM_RADIX_STACK, &start)) != 0) {
+	exhausted = 0;
+	while (exhausted == 0 && (n = vm_radix_lookupn(&object->rtree, start,
+	    end, VM_RADIX_ANY, (void **)pa, VM_RADIX_STACK, &start,
+	    &exhausted)) != 0) {
 		for (i = 0; i < n; i++) {
 			p = pa[i];
 			/*

Modified: user/attilio/vmcontention/sys/vm/vm_radix.c
==============================================================================
--- user/attilio/vmcontention/sys/vm/vm_radix.c	Sat Jun 23 01:08:46 2012	(r237465)
+++ user/attilio/vmcontention/sys/vm/vm_radix.c	Sat Jun 23 01:30:51 2012	(r237466)
@@ -726,7 +726,8 @@ out:
  */
 int
 vm_radix_lookupn(struct vm_radix *rtree, vm_pindex_t start,
-    vm_pindex_t end, int color, void **out, int cnt, vm_pindex_t *next)
+    vm_pindex_t end, int color, void **out, int cnt, vm_pindex_t *next,
+    u_int *exhausted)
 {
 	struct vm_radix_node *rnode;
 	void *val;
@@ -736,6 +737,8 @@ vm_radix_lookupn(struct vm_radix *rtree,
 	CTR5(KTR_VM, "lookupn: tree %p, " KFRMT64(start) ", " KFRMT64(end),
 	    rtree, KSPLT64L(start), KSPLT64H(start), KSPLT64L(end),
 	    KSPLT64H(end));
+	if (end == 0)
+		*exhausted = 0;
 	if (rtree->rt_root == 0)
 		return (0);
 	outidx = 0;
@@ -760,6 +763,8 @@ vm_radix_lookupn(struct vm_radix *rtree,
 				 */
 				if ((VM_RADIX_MAXVAL - start) == 0) {
 					start++;
+					if (end == 0)
+						*exhausted = 1;
 					goto out;
 				}
 				continue;
@@ -771,6 +776,8 @@ vm_radix_lookupn(struct vm_radix *rtree,
 			if (++outidx == cnt ||
 			    (VM_RADIX_MAXVAL - start) == 0) {
 				start++;
+				if (end == 0)
+					*exhausted = 1;
 				goto out;
 			}
 		} 

Modified: user/attilio/vmcontention/sys/vm/vm_radix.h
==============================================================================
--- user/attilio/vmcontention/sys/vm/vm_radix.h	Sat Jun 23 01:08:46 2012	(r237465)
+++ user/attilio/vmcontention/sys/vm/vm_radix.h	Sat Jun 23 01:30:51 2012	(r237466)
@@ -60,7 +60,7 @@ int 	vm_radix_insert(struct vm_radix *, 
 void	*vm_radix_color(struct vm_radix *, vm_pindex_t, int);
 void	*vm_radix_lookup(struct vm_radix *, vm_pindex_t, int);
 int	vm_radix_lookupn(struct vm_radix *, vm_pindex_t, vm_pindex_t, int,
-	    void **, int, vm_pindex_t *);
+	    void **, int, vm_pindex_t *, u_int *);
 void	*vm_radix_lookup_le(struct vm_radix *, vm_pindex_t, int);
 void	vm_radix_reclaim_allnodes(struct vm_radix *);
 void	vm_radix_remove(struct vm_radix *, vm_pindex_t, int);
@@ -72,8 +72,9 @@ static inline void *
 vm_radix_lookup_ge(struct vm_radix *rtree, vm_pindex_t index, int color)
 {
         void *val;
+	u_int dummy;
 
-        if (vm_radix_lookupn(rtree, index, 0, color, &val, 1, &index))
+        if (vm_radix_lookupn(rtree, index, 0, color, &val, 1, &index, &dummy))
                 return (val);
         return (NULL);
 }



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