Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Ross Zwisler and committed by
Linus Torvalds
0796c583 070c5ac2

+29 -18
+28 -18
lib/radix-tree.c
··· 215 215 return size; 216 216 } 217 217 218 - #if 0 219 - static void dump_node(void *slot, int height, int offset) 218 + #ifndef __KERNEL__ 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 - int i; 222 + unsigned long i; 223 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 - 232 - node = indirect_to_ptr(slot); 233 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], 235 - node->tags[2][0], node->path, node->count, node->parent); 225 + node, offset, 226 + node->tags[0][0], node->tags[1][0], node->tags[2][0], 227 + node->path, node->count, node->parent); 236 228 237 - for (i = 0; i < RADIX_TREE_MAP_SIZE; i++) 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 250 /* For debug */ ··· 255 246 root->gfp_mask >> __GFP_BITS_SHIFT); 256 247 if (!radix_tree_is_indirect_ptr(root->rnode)) 257 248 return; 258 - dump_node(root->rnode, root->height, 0); 249 + dump_node(indirect_to_ptr(root->rnode), 0, 250 + (root->height - 1) * RADIX_TREE_MAP_SHIFT, 0); 259 251 } 260 252 #endif 261 253
+1
tools/testing/radix-tree/test.h
··· 40 40 41 41 /* Normally private parts of lib/radix-tree.c */ 42 42 void *indirect_to_ptr(void *ptr); 43 + void radix_tree_dump(struct radix_tree_root *root); 43 44 int root_tag_get(struct radix_tree_root *root, unsigned int tag); 44 45 unsigned long radix_tree_maxindex(unsigned int height);