diff options
author | Ross Zwisler <ross.zwisler@linux.intel.com> | 2016-05-20 20:02:55 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-20 20:58:30 -0400 |
commit | 0796c58325533f87c00949a545eb607baa8441cb (patch) | |
tree | e78de9ca122816731b9d32dfad4cc0ccf034d678 /lib | |
parent | 070c5ac2740b5db89d381a09fb03b2480b2f7a74 (diff) |
radix-tree: fix radix_tree_dump() for multi-order entries
- Print which indices are covered by every leaf entry
- Print sibling entries
- Print the node pointer instead of the slot entry
- Build by default in userspace, and make it accessible to the test-suite
Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>
Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
Cc: Konstantin Khlebnikov <koct9i@gmail.com>
Cc: Kirill Shutemov <kirill.shutemov@linux.intel.com>
Cc: Jan Kara <jack@suse.com>
Cc: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/radix-tree.c | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 8df0df2835b4..a1a44f94c171 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c | |||
@@ -215,27 +215,36 @@ radix_tree_find_next_bit(const unsigned long *addr, | |||
215 | return size; | 215 | return size; |
216 | } | 216 | } |
217 | 217 | ||
218 | #if 0 | 218 | #ifndef __KERNEL__ |
219 | static void dump_node(void *slot, int height, int offset) | 219 | static void dump_node(struct radix_tree_node *node, unsigned offset, |
220 | unsigned shift, unsigned long index) | ||
220 | { | 221 | { |
221 | struct radix_tree_node *node; | 222 | unsigned long i; |
222 | int i; | ||
223 | |||
224 | if (!slot) | ||
225 | return; | ||
226 | |||
227 | if (height == 0) { | ||
228 | pr_debug("radix entry %p offset %d\n", slot, offset); | ||
229 | return; | ||
230 | } | ||
231 | 223 | ||
232 | node = indirect_to_ptr(slot); | ||
233 | pr_debug("radix node: %p offset %d tags %lx %lx %lx path %x count %d parent %p\n", | 224 | pr_debug("radix node: %p offset %d tags %lx %lx %lx path %x count %d parent %p\n", |
234 | slot, offset, node->tags[0][0], node->tags[1][0], | 225 | node, offset, |
235 | node->tags[2][0], node->path, node->count, node->parent); | 226 | node->tags[0][0], node->tags[1][0], node->tags[2][0], |
236 | 227 | node->path, node->count, node->parent); | |
237 | for (i = 0; i < RADIX_TREE_MAP_SIZE; i++) | 228 | |
238 | dump_node(node->slots[i], height - 1, i); | 229 | for (i = 0; i < RADIX_TREE_MAP_SIZE; i++) { |
230 | unsigned long first = index | (i << shift); | ||
231 | unsigned long last = first | ((1UL << shift) - 1); | ||
232 | void *entry = node->slots[i]; | ||
233 | if (!entry) | ||
234 | continue; | ||
235 | if (is_sibling_entry(node, entry)) { | ||
236 | pr_debug("radix sblng %p offset %ld val %p indices %ld-%ld\n", | ||
237 | entry, i, | ||
238 | *(void **)indirect_to_ptr(entry), | ||
239 | first, last); | ||
240 | } else if (!radix_tree_is_indirect_ptr(entry)) { | ||
241 | pr_debug("radix entry %p offset %ld indices %ld-%ld\n", | ||
242 | entry, i, first, last); | ||
243 | } else { | ||
244 | dump_node(indirect_to_ptr(entry), i, | ||
245 | shift - RADIX_TREE_MAP_SHIFT, first); | ||
246 | } | ||
247 | } | ||
239 | } | 248 | } |
240 | 249 | ||
241 | /* For debug */ | 250 | /* For debug */ |
@@ -246,7 +255,8 @@ static void radix_tree_dump(struct radix_tree_root *root) | |||
246 | root->gfp_mask >> __GFP_BITS_SHIFT); | 255 | root->gfp_mask >> __GFP_BITS_SHIFT); |
247 | if (!radix_tree_is_indirect_ptr(root->rnode)) | 256 | if (!radix_tree_is_indirect_ptr(root->rnode)) |
248 | return; | 257 | return; |
249 | dump_node(root->rnode, root->height, 0); | 258 | dump_node(indirect_to_ptr(root->rnode), 0, |
259 | (root->height - 1) * RADIX_TREE_MAP_SHIFT, 0); | ||
250 | } | 260 | } |
251 | #endif | 261 | #endif |
252 | 262 | ||