Date: Tue, 1 Nov 2011 03:40:38 +0000 (UTC) From: Attilio Rao <attilio@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r226980 - user/attilio/vmcontention/sys/vm Message-ID: <201111010340.pA13ec6c047094@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 *));
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201111010340.pA13ec6c047094>