summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_radix.c
diff options
context:
space:
mode:
authorattilio <attilio@FreeBSD.org>2012-07-08 14:01:25 +0000
committerattilio <attilio@FreeBSD.org>2012-07-08 14:01:25 +0000
commitffa3f082fffd0919e1fab9e61c5d2f6e3b660159 (patch)
treefb66d07b443940b951526bc54891166470963486 /sys/vm/vm_radix.c
parent3fc8e2687245790ea86e20d4e2ecb493bca60a00 (diff)
downloadFreeBSD-src-ffa3f082fffd0919e1fab9e61c5d2f6e3b660159.zip
FreeBSD-src-ffa3f082fffd0919e1fab9e61c5d2f6e3b660159.tar.gz
- Split the cached and resident pages tree into 2 distinct ones.
This makes the RED/BLACK support go away and simplifies a lot vmradix functions used here. This happens because with patricia trie support the trie will be little enough that keeping 2 diffetnt will be efficient too. - Reduce differences with head, in places like backing scan where the optimizazions used shuffled the code a little bit around. Tested by: flo, Andrea Barberio
Diffstat (limited to 'sys/vm/vm_radix.c')
-rw-r--r--sys/vm/vm_radix.c142
1 files changed, 22 insertions, 120 deletions
diff --git a/sys/vm/vm_radix.c b/sys/vm/vm_radix.c
index 36db1c6..1a50979 100644
--- a/sys/vm/vm_radix.c
+++ b/sys/vm/vm_radix.c
@@ -293,14 +293,12 @@ vm_radix_setroot(struct vm_radix *rtree, struct vm_radix_node *rnode,
}
static inline void *
-vm_radix_match(void *child, int color)
+vm_radix_match(void *child)
{
uintptr_t c;
c = (uintptr_t)child;
- if ((c & color) == 0)
- return (NULL);
return ((void *)(c & ~VM_RADIX_FLAGS));
}
@@ -429,9 +427,8 @@ vm_radix_insert(struct vm_radix *rtree, vm_pindex_t index, void *val)
KASSERT(rnode->rn_child[slot] == NULL,
("vm_radix_insert: Duplicate value %p at index: %lu\n",
rnode->rn_child[slot], (u_long)index));
- val = (void *)((uintptr_t)val | VM_RADIX_BLACK);
rnode->rn_child[slot] = val;
- atomic_add_32(&rnode->rn_count, 1);
+ rnode->rn_count++;
CTR5(KTR_VM,
"insert: tree %p, " KFRMT64(index) ", level %d, slot %d",
rtree, KSPLT64L(index), KSPLT64H(index), level, slot);
@@ -446,7 +443,7 @@ vm_radix_insert(struct vm_radix *rtree, vm_pindex_t index, void *val)
* NULL is returned.
*/
void *
-vm_radix_lookup(struct vm_radix *rtree, vm_pindex_t index, int color)
+vm_radix_lookup(struct vm_radix *rtree, vm_pindex_t index)
{
struct vm_radix_node *rnode;
int slot;
@@ -465,7 +462,7 @@ vm_radix_lookup(struct vm_radix *rtree, vm_pindex_t index, int color)
CTR2(KTR_VM, "lookup: rnode %p, child %p", rnode,
rnode->rn_child[slot]);
if (level == 0)
- return vm_radix_match(rnode->rn_child[slot], color);
+ return vm_radix_match(rnode->rn_child[slot]);
rnode = rnode->rn_child[slot];
level--;
}
@@ -475,40 +472,6 @@ vm_radix_lookup(struct vm_radix *rtree, vm_pindex_t index, int color)
return NULL;
}
-void *
-vm_radix_color(struct vm_radix *rtree, vm_pindex_t index, int color)
-{
- struct vm_radix_node *rnode;
- uintptr_t child;
- int slot;
- int level;
-
- level = vm_radix_height(rtree, &rnode);
- if (index > VM_RADIX_MAX(level))
- return NULL;
- level--;
- while (rnode) {
- slot = vm_radix_slot(index, level);
- CTR6(KTR_VM,
- "color: tree %p, " KFRMT64(index) ", level %d, slot %d, rnode %p",
- rtree, KSPLT64L(index), KSPLT64H(index), level, slot,
- rnode);
- CTR2(KTR_VM, "color: rnode %p, child %p", rnode,
- rnode->rn_child[slot]);
- if (level == 0)
- break;
- rnode = rnode->rn_child[slot];
- level--;
- }
- if (rnode == NULL || rnode->rn_child[slot] == NULL)
- return (NULL);
- child = (uintptr_t)rnode->rn_child[slot];
- child &= ~VM_RADIX_FLAGS;
- rnode->rn_child[slot] = (void *)(child | color);
-
- return (void *)child;
-}
-
/*
* Find the first leaf with a valid node between *startp and end. Return
* the index of the first valid item in the leaf in *startp.
@@ -598,7 +561,7 @@ 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, void **out, int cnt, vm_pindex_t *next, u_int *exhausted)
{
struct vm_radix_node *rnode;
void *val;
@@ -608,6 +571,8 @@ vm_radix_lookupn(struct vm_radix *rtree, vm_pindex_t start,
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;
@@ -616,7 +581,7 @@ vm_radix_lookupn(struct vm_radix *rtree, vm_pindex_t start,
for (; slot < VM_RADIX_COUNT; slot++, start++) {
if (end != 0 && start >= end)
goto out;
- val = vm_radix_match(rnode->rn_child[slot], color);
+ val = vm_radix_match(rnode->rn_child[slot]);
if (val == NULL) {
/*
@@ -632,6 +597,8 @@ vm_radix_lookupn(struct vm_radix *rtree, vm_pindex_t start,
*/
if ((VM_RADIX_MAXVAL - start) == 0) {
start++;
+ if (end == 0)
+ *exhausted = 1;
goto out;
}
continue;
@@ -640,10 +607,11 @@ vm_radix_lookupn(struct vm_radix *rtree, vm_pindex_t start,
"lookupn: tree %p " KFRMT64(index) " slot %d found child %p",
rtree, KSPLT64L(start), KSPLT64H(start), slot, val);
out[outidx] = val;
- if (++outidx == cnt)
- goto out;
- if ((VM_RADIX_MAXVAL - start) == 0) {
+ if (++outidx == cnt ||
+ (VM_RADIX_MAXVAL - start) == 0) {
start++;
+ if ((VM_RADIX_MAXVAL - start) == 0 && end == 0)
+ *exhausted = 1;
goto out;
}
}
@@ -656,38 +624,11 @@ out:
return (outidx);
}
-#if 0
-void
-vm_radix_foreach(struct vm_radix *rtree, vm_pindex_t start, vm_pindex_t end,
- int color, void (*iter)(void *))
-{
- struct vm_radix_node *rnode;
- void *val;
- int slot;
-
- if (rtree->rt_root == 0)
- return;
- while ((rnode = vm_radix_leaf(rtree, &start, end)) != NULL) {
- slot = vm_radix_slot(start, 0);
- for (; slot < VM_RADIX_COUNT; slot++, start++) {
- if (end != 0 && start >= end)
- return;
- val = vm_radix_match(rnode->rn_child[slot], color);
- if (val)
- iter(val);
- }
- if (end != 0 && start >= end)
- return;
- }
-}
-#endif
-
-
/*
* Look up any entry at a position less than or equal to index.
*/
void *
-vm_radix_lookup_le(struct vm_radix *rtree, vm_pindex_t index, int color)
+vm_radix_lookup_le(struct vm_radix *rtree, vm_pindex_t index)
{
struct vm_radix_node *rnode;
struct vm_radix_node *child;
@@ -751,7 +692,7 @@ restart:
}
if (rnode) {
for (; slot >= 0; slot--, index--) {
- val = vm_radix_match(rnode->rn_child[slot], color);
+ val = vm_radix_match(rnode->rn_child[slot]);
if (val)
return (val);
}
@@ -767,7 +708,7 @@ restart:
* panics if the key is not present.
*/
void
-vm_radix_remove(struct vm_radix *rtree, vm_pindex_t index, int color)
+vm_radix_remove(struct vm_radix *rtree, vm_pindex_t index)
{
struct vm_radix_node *stack[VM_RADIX_LIMIT];
struct vm_radix_node *rnode, *root;
@@ -798,7 +739,7 @@ vm_radix_remove(struct vm_radix *rtree, vm_pindex_t index, int color)
KASSERT(rnode != NULL,
("vm_radix_remove: index not present in the tree.\n"));
slot = vm_radix_slot(index, 0);
- KASSERT(vm_radix_match(rnode->rn_child[slot], color) != NULL,
+ KASSERT(vm_radix_match(rnode->rn_child[slot]) != NULL,
("vm_radix_remove: index not present in the tree.\n"));
for (;;) {
@@ -813,21 +754,14 @@ vm_radix_remove(struct vm_radix *rtree, vm_pindex_t index, int color)
(rnode != NULL) ? rnode->rn_count : 0);
rnode->rn_child[slot] = NULL;
/*
- * Use atomics for the last level since red and black
- * will both adjust it.
* Use a write memory barrier here in order to avoid
* rn_count reaching 0 before to fetch the actual pointer.
- * Concurrent black removal, infact, may want to reclaim
+ * Concurrent node removal, infact, may want to reclaim
* the radix node itself before to read it.
*/
- if (level == 0)
- atomic_add_rel_32(&rnode->rn_count, -1);
- else
- rnode->rn_count--;
- /*
- * Only allow black removes to prune the tree.
- */
- if ((color & VM_RADIX_BLACK) == 0 || rnode->rn_count > 0)
+ rnode->rn_count--;
+ wmb();
+ if (rnode->rn_count > 0)
break;
vm_radix_node_put(rnode);
if (rnode == root) {
@@ -857,35 +791,3 @@ vm_radix_reclaim_allnodes(struct vm_radix *rtree)
vm_radix_reclaim_allnodes_internal(root, level - 1);
rtree->rt_root = 0;
}
-
-#ifdef notyet
-/*
- * Attempts to reduce the height of the tree.
- */
-void
-vm_radix_shrink(struct vm_radix *rtree)
-{
- struct vm_radix_node *tmp, *root;
- int level;
-
- if (rtree->rt_root == 0)
- return;
- level = vm_radix_height(rtree, &root);
-
- /* Adjust the height of the tree. */
- while (root->rn_count == 1 && root->rn_child[0] != NULL) {
- tmp = root;
- root->rn_count--;
- root = root->rn_child[0];
- level--;
- vm_radix_node_put(tmp);
- }
- /* Finally see if we have an empty tree. */
- if (root->rn_count == 0) {
- vm_radix_node_put(root);
- root = NULL;
- level--;
- }
- vm_radix_setroot(rtree, root, level);
-}
-#endif
OpenPOWER on IntegriCloud