svn commit: r226980 - user/attilio/vmcontention/sys/vm

Attilio Rao attilio at FreeBSD.org
Tue Nov 1 03:40:38 UTC 2011


Author: attilio
Date: Tue Nov  1 03:40:38 2011
New Revision: 226980
URL: http://svn.freebsd.org/changeset/base/226980

Log:
  vm_object_terminate() doesn't actually free the pages in the splay
  tree.
  Reclaim all the nodes related to the radix tree for a specified
  vm_object when calling vm_object_terminate() via the newly added
  interface vm_radix_reclaim_nodes().
  The function is recursive, but we have a well-defined maximum depth,
  thus the amount of necessary stack can be easilly calculated.
  
  Reported by:	alc
  Discussed and reviewed by:	jeff

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	Tue Nov  1 02:04:52 2011	(r226979)
+++ user/attilio/vmcontention/sys/vm/vm_object.c	Tue Nov  1 03:40:38 2011	(r226980)
@@ -756,6 +756,9 @@ vm_object_terminate(vm_object_t object)
 			 * assignment is that vm_page_free()'s call to
 			 * vm_page_remove() will return immediately without
 			 * modifying the page or the object.
+			 * Anyway, the radix tree cannot be accessed anymore
+			 * from within the object, thus all the nodes need
+			 * to be reclaimed later on.
 			 */ 
 			p->object = NULL;
 			if (p->wire_count == 0) {
@@ -767,6 +770,7 @@ vm_object_terminate(vm_object_t object)
 		if (n < VM_RADIX_STACK)
 			break;
 	}
+	vm_radix_reclaim_allnodes(&object->rtree);
 	/*
 	 * If the object contained any pages, then reset it to an empty state.
 	 * None of the object's fields, including "resident_page_count", were

Modified: user/attilio/vmcontention/sys/vm/vm_radix.c
==============================================================================
--- user/attilio/vmcontention/sys/vm/vm_radix.c	Tue Nov  1 02:04:52 2011	(r226979)
+++ user/attilio/vmcontention/sys/vm/vm_radix.c	Tue Nov  1 03:40:38 2011	(r226980)
@@ -223,6 +223,38 @@ vm_radix_match(void *child, int color)
 	return ((void *)(c & ~VM_RADIX_FLAGS));
 }
 
+static void
+vm_radix_reclaim_allnodes_internal(struct vm_radix_node *rnode, int level)
+{
+	int slot;
+
+	MPASS(rnode != NULL && level >= 0);
+
+	/*
+	 * Level 0 just contains pages as children, thus make it a special
+	 * case, free the node and return.
+	 */
+	if (level == 0) {
+		CTR2(KTR_VM, "reclaiming: node %p, level %d", rnode, level);
+		rnode->rn_count = 0;
+		vm_radix_node_put(rnode);
+		return;
+	}
+	for (slot = 0; slot < VM_RADIX_COUNT && rnode->rn_count != 0; slot++) {
+		if (rnode->rn_child[slot] == NULL)
+			continue;
+		CTR3(KTR_VM,
+		    "reclaiming: node %p, level %d recursing in slot %d",
+		    rnode, level, slot);
+		vm_radix_reclaim_allnodes_internal(rnode->rn_child[slot],
+		    level - 1);
+		rnode->rn_count--;
+	}
+	MPASS(rnode->rn_count == 0);
+	CTR2(KTR_VM, "reclaiming: node %p, level %d", rnode, level);
+	vm_radix_node_put(rnode);
+}
+
 /*
  * Inserts the key-value pair in to the radix tree.  Returns errno.
  * Panics if the key already exists.
@@ -640,6 +672,24 @@ vm_radix_remove(struct vm_radix *rtree, 
 }
 
 /*
+ * Remove and free all the nodes from the radix tree.
+ * This function is recrusive but there is a tight control on it as the
+ * maximum depth of the tree is fixed.
+ */
+void
+vm_radix_reclaim_allnodes(struct vm_radix *rtree)
+{
+	struct vm_radix_node *root;
+	int level;
+
+	if (rtree->rt_root == 0)
+		return;
+	level = vm_radix_height(rtree, &root);
+	vm_radix_reclaim_allnodes_internal(root, level - 1);
+	rtree->rt_root = 0;
+}
+
+/*
  * Attempts to reduce the height of the tree.
  */
 void 

Modified: user/attilio/vmcontention/sys/vm/vm_radix.h
==============================================================================
--- user/attilio/vmcontention/sys/vm/vm_radix.h	Tue Nov  1 02:04:52 2011	(r226979)
+++ user/attilio/vmcontention/sys/vm/vm_radix.h	Tue Nov  1 03:40:38 2011	(r226980)
@@ -79,6 +79,7 @@ void	*vm_radix_lookup(struct vm_radix *,
 int	vm_radix_lookupn(struct vm_radix *, vm_pindex_t, vm_pindex_t, int,
 	    void **, int, vm_pindex_t *);
 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);
 void	vm_radix_foreach(struct vm_radix *, vm_pindex_t, vm_pindex_t, int,
 	    void (*)(void *));


More information about the svn-src-user mailing list