From: Matthew Wilcox <willy@linux.intel.com>
To: linux-kernel@vger.kernel.org, Andrew Morton <akpm@linux-foundation.org>
Cc: Matthew Wilcox <willy@linux.intel.com>,
linux-mm@kvack.org, linux-fsdevel@vger.kernel.org,
Konstantin Khlebnikov <koct9i@gmail.com>,
Kirill Shutemov <kirill.shutemov@linux.intel.com>,
Jan Kara <jack@suse.com>, Neil Brown <neilb@suse.de>,
Ross Zwisler <ross.zwisler@linux.intel.com>
Subject: [PATCH 13/19] radix-tree: Tidy up next_chunk
Date: Thu, 14 Apr 2016 10:37:16 -0400 [thread overview]
Message-ID: <1460644642-30642-14-git-send-email-willy@linux.intel.com> (raw)
In-Reply-To: <1460644642-30642-1-git-send-email-willy@linux.intel.com>
Convert radix_tree_next_chunk to use 'child' instead of 'slot' as the name
of the child node. Also use node_maxindex() where it makes sense.
The 'rnode' variable was unnecessary; it doesn't overlap in usage with
'node', so we can just use 'node' the whole way through the function.
Improve the testcase to start the walk from every index in the carefully
constructed tree, and to accept any index within the range covered by
the entry.
Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
---
lib/radix-tree.c | 53 +++++++------------
tools/testing/radix-tree/multiorder.c | 99 +++++++++++++++++++----------------
2 files changed, 74 insertions(+), 78 deletions(-)
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index 094dfc0..fab4485 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -876,7 +876,7 @@ void **radix_tree_next_chunk(struct radix_tree_root *root,
struct radix_tree_iter *iter, unsigned flags)
{
unsigned shift, tag = flags & RADIX_TREE_ITER_TAG_MASK;
- struct radix_tree_node *rnode, *node;
+ struct radix_tree_node *node, *child;
unsigned long index, offset, maxindex;
if ((flags & RADIX_TREE_ITER_TAGGED) && !root_tag_get(root, tag))
@@ -896,38 +896,29 @@ void **radix_tree_next_chunk(struct radix_tree_root *root,
return NULL;
restart:
- shift = radix_tree_load_root(root, &rnode, &maxindex);
+ shift = radix_tree_load_root(root, &child, &maxindex);
if (index > maxindex)
return NULL;
+ if (!child)
+ return NULL;
- if (radix_tree_is_internal_node(rnode)) {
- rnode = entry_to_node(rnode);
- } else if (rnode) {
+ if (!radix_tree_is_internal_node(child)) {
/* Single-slot tree */
iter->index = index;
iter->next_index = maxindex + 1;
iter->tags = 1;
- __set_iter_shift(iter, shift);
+ __set_iter_shift(iter, 0);
return (void **)&root->rnode;
- } else
- return NULL;
-
- shift -= RADIX_TREE_MAP_SHIFT;
- offset = index >> shift;
-
- node = rnode;
- while (1) {
- struct radix_tree_node *slot;
- unsigned new_off = radix_tree_descend(node, &slot, offset);
+ }
- if (new_off < offset) {
- offset = new_off;
- index &= ~((RADIX_TREE_MAP_SIZE << shift) - 1);
- index |= offset << shift;
- }
+ do {
+ node = entry_to_node(child);
+ shift -= RADIX_TREE_MAP_SHIFT;
+ offset = (index >> shift) & RADIX_TREE_MAP_MASK;
+ offset = radix_tree_descend(node, &child, offset);
if ((flags & RADIX_TREE_ITER_TAGGED) ?
- !tag_get(node, tag, offset) : !slot) {
+ !tag_get(node, tag, offset) : !child) {
/* Hole detected */
if (flags & RADIX_TREE_ITER_CONTIG)
return NULL;
@@ -945,29 +936,23 @@ void **radix_tree_next_chunk(struct radix_tree_root *root,
if (slot)
break;
}
- index &= ~((RADIX_TREE_MAP_SIZE << shift) - 1);
+ index &= ~node_maxindex(node);
index += offset << shift;
/* Overflow after ~0UL */
if (!index)
return NULL;
if (offset == RADIX_TREE_MAP_SIZE)
goto restart;
- slot = rcu_dereference_raw(node->slots[offset]);
+ child = rcu_dereference_raw(node->slots[offset]);
}
- if ((slot == NULL) || (slot == RADIX_TREE_RETRY))
+ if ((child == NULL) || (child == RADIX_TREE_RETRY))
goto restart;
- if (!radix_tree_is_internal_node(slot))
- break;
-
- node = entry_to_node(slot);
- shift -= RADIX_TREE_MAP_SHIFT;
- offset = (index >> shift) & RADIX_TREE_MAP_MASK;
- }
+ } while (radix_tree_is_internal_node(child));
/* Update the iterator state */
- iter->index = index & ~((1 << shift) - 1);
- iter->next_index = (index | ((RADIX_TREE_MAP_SIZE << shift) - 1)) + 1;
+ iter->index = (index &~ node_maxindex(node)) | (offset << node->shift);
+ iter->next_index = (index | node_maxindex(node)) + 1;
__set_iter_shift(iter, shift);
/* Construct iter->tags bit-mask from node->tags[tag] array */
diff --git a/tools/testing/radix-tree/multiorder.c b/tools/testing/radix-tree/multiorder.c
index c061f4b..39d9b95 100644
--- a/tools/testing/radix-tree/multiorder.c
+++ b/tools/testing/radix-tree/multiorder.c
@@ -202,7 +202,7 @@ void multiorder_iteration(void)
RADIX_TREE(tree, GFP_KERNEL);
struct radix_tree_iter iter;
void **slot;
- int i, err;
+ int i, j, err;
printf("Multiorder iteration test\n");
@@ -215,29 +215,21 @@ void multiorder_iteration(void)
assert(!err);
}
- i = 0;
- /* start from index 1 to verify we find the multi-order entry at 0 */
- radix_tree_for_each_slot(slot, &tree, &iter, 1) {
- int height = order[i] / RADIX_TREE_MAP_SHIFT;
- int shift = height * RADIX_TREE_MAP_SHIFT;
-
- assert(iter.index == index[i]);
- assert(iter.shift == shift);
- i++;
- }
-
- /*
- * Now iterate through the tree starting at an elevated multi-order
- * entry, beginning at an index in the middle of the range.
- */
- i = 8;
- radix_tree_for_each_slot(slot, &tree, &iter, 70) {
- int height = order[i] / RADIX_TREE_MAP_SHIFT;
- int shift = height * RADIX_TREE_MAP_SHIFT;
-
- assert(iter.index == index[i]);
- assert(iter.shift == shift);
- i++;
+ for (j = 0; j < 256; j++) {
+ for (i = 0; i < NUM_ENTRIES; i++)
+ if (j <= (index[i] | ((1 << order[i]) - 1)))
+ break;
+
+ radix_tree_for_each_slot(slot, &tree, &iter, j) {
+ int height = order[i] / RADIX_TREE_MAP_SHIFT;
+ int shift = height * RADIX_TREE_MAP_SHIFT;
+ int mask = (1 << order[i]) - 1;
+
+ assert(iter.index >= (index[i] &~ mask));
+ assert(iter.index <= (index[i] | mask));
+ assert(iter.shift == shift);
+ i++;
+ }
}
item_kill_tree(&tree);
@@ -249,7 +241,7 @@ void multiorder_tagged_iteration(void)
struct radix_tree_iter iter;
void **slot;
unsigned long first = 0;
- int i;
+ int i, j;
printf("Multiorder tagged iteration test\n");
@@ -268,30 +260,49 @@ void multiorder_tagged_iteration(void)
for (i = 0; i < TAG_ENTRIES; i++)
assert(radix_tree_tag_set(&tree, tag_index[i], 1));
- i = 0;
- /* start from index 1 to verify we find the multi-order entry at 0 */
- radix_tree_for_each_tagged(slot, &tree, &iter, 1, 1) {
- assert(iter.index == tag_index[i]);
- i++;
- }
-
- /*
- * Now iterate through the tree starting at an elevated multi-order
- * entry, beginning at an index in the middle of the range.
- */
- i = 4;
- radix_tree_for_each_slot(slot, &tree, &iter, 70) {
- assert(iter.index == tag_index[i]);
- i++;
+ for (j = 0; j < 256; j++) {
+ int mask, k;
+
+ for (i = 0; i < TAG_ENTRIES; i++) {
+ for (k = i; index[k] < tag_index[i]; k++)
+ ;
+ if (j <= (index[k] | ((1 << order[k]) - 1)))
+ break;
+ }
+
+ radix_tree_for_each_tagged(slot, &tree, &iter, j, 1) {
+ for (k = i; index[k] < tag_index[i]; k++)
+ ;
+ mask = (1 << order[k]) - 1;
+
+ assert(iter.index >= (tag_index[i] &~ mask));
+ assert(iter.index <= (tag_index[i] | mask));
+ i++;
+ }
}
radix_tree_range_tag_if_tagged(&tree, &first, ~0UL,
MT_NUM_ENTRIES, 1, 2);
- i = 0;
- radix_tree_for_each_tagged(slot, &tree, &iter, 1, 2) {
- assert(iter.index == tag_index[i]);
- i++;
+ for (j = 0; j < 256; j++) {
+ int mask, k;
+
+ for (i = 0; i < TAG_ENTRIES; i++) {
+ for (k = i; index[k] < tag_index[i]; k++)
+ ;
+ if (j <= (index[k] | ((1 << order[k]) - 1)))
+ break;
+ }
+
+ radix_tree_for_each_tagged(slot, &tree, &iter, j, 2) {
+ for (k = i; index[k] < tag_index[i]; k++)
+ ;
+ mask = (1 << order[k]) - 1;
+
+ assert(iter.index >= (tag_index[i] &~ mask));
+ assert(iter.index <= (tag_index[i] | mask));
+ i++;
+ }
}
first = 1;
--
2.8.0.rc3
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2016-04-14 14:38 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-14 14:37 [PATCH 00/19] Radix tree cleanups Matthew Wilcox
2016-04-14 14:37 ` [PATCH 01/19] drivers/hwspinlock: Use correct radix tree API Matthew Wilcox
2016-04-14 14:37 ` [PATCH 02/19] radix-tree: Miscellaneous fixes Matthew Wilcox
2016-04-27 5:43 ` NeilBrown
2016-04-14 14:37 ` [PATCH 03/19] radix-tree: Split node->path into offset and height Matthew Wilcox
2016-04-14 14:37 ` [PATCH 04/19] radix-tree: Replace node->height with node->shift Matthew Wilcox
2016-04-14 14:37 ` [PATCH 05/19] radix-tree: Remove a use of root->height from delete_node Matthew Wilcox
2016-04-14 14:37 ` [PATCH 06/19] radix tree test suite: Remove dependencies on height Matthew Wilcox
2016-04-14 14:37 ` [PATCH 07/19] radix-tree: Remove root->height Matthew Wilcox
2016-04-14 14:37 ` [PATCH 08/19] radix-tree: Rename INDIRECT_PTR to INTERNAL_NODE Matthew Wilcox
2016-04-14 14:37 ` [PATCH 09/19] radix-tree: Rename ptr_to_indirect() to node_to_entry() Matthew Wilcox
2016-04-14 14:37 ` [PATCH 10/19] radix-tree: Rename indirect_to_ptr() to entry_to_node() Matthew Wilcox
2016-04-14 14:37 ` [PATCH 11/19] radix-tree: Rename radix_tree_is_indirect_ptr() Matthew Wilcox
2016-04-14 14:37 ` [PATCH 12/19] radix-tree: Change naming conventions in radix_tree_shrink Matthew Wilcox
2016-04-14 14:37 ` Matthew Wilcox [this message]
2016-04-14 14:37 ` [PATCH 14/19] radix-tree: Tidy up range_tag_if_tagged Matthew Wilcox
2016-04-14 14:37 ` [PATCH 15/19] radix-tree: Tidy up __radix_tree_create() Matthew Wilcox
2016-04-14 14:37 ` [PATCH 16/19] radix-tree: Introduce radix_tree_replace_clear_tags() Matthew Wilcox
2016-04-14 14:37 ` [PATCH 17/19] radix-tree: Make radix_tree_descend() more useful Matthew Wilcox
2016-04-14 14:37 ` [PATCH 18/19] dax: move RADIX_DAX_ definitions to dax.c Matthew Wilcox
2016-04-14 14:37 ` [PATCH 19/19] radix-tree: Free up the bottom bit of exceptional entries for reuse Matthew Wilcox
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1460644642-30642-14-git-send-email-willy@linux.intel.com \
--to=willy@linux.intel.com \
--cc=akpm@linux-foundation.org \
--cc=jack@suse.com \
--cc=kirill.shutemov@linux.intel.com \
--cc=koct9i@gmail.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=neilb@suse.de \
--cc=ross.zwisler@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).