radix-tree: test radix_tree_iter_retry From: Konstantin Khlebnikov Signed-off-by: Konstantin Khlebnikov --- lib/radix-tree.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 6b79e9026e24..f489334b9cb7 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c @@ -1491,6 +1491,66 @@ static int radix_tree_callback(struct notifier_block *nfb, return NOTIFY_OK; } +static void test_iter_retry(void) +{ + RADIX_TREE(root, GFP_KERNEL); + void *ptr = (void *)4ul; + struct radix_tree_iter iter; + void **slot; + bool first; + + radix_tree_insert(&root, 0, ptr); + radix_tree_tag_set(&root, 0, 0); + + first = true; + radix_tree_for_each_tagged(slot, &root, &iter, 0, 0) { + printk("tagged %ld %p\n", iter.index, *slot); + if (first) { + radix_tree_insert(&root, 1, ptr); + radix_tree_tag_set(&root, 1, 0); + first = false; + } + if (radix_tree_deref_retry(*slot)) { + printk("retry %ld\n", iter.index); + slot = radix_tree_iter_retry(&iter); + continue; + } + } + radix_tree_delete(&root, 1); + + first = true; + radix_tree_for_each_slot(slot, &root, &iter, 0) { + printk("slot %ld %p\n", iter.index, *slot); + if (first) { + radix_tree_insert(&root, 1, ptr); + first = false; + } + if (radix_tree_deref_retry(*slot)) { + printk("retry %ld\n", iter.index); + slot = radix_tree_iter_retry(&iter); + continue; + } + } + radix_tree_delete(&root, 1); + + first = true; + radix_tree_for_each_contig(slot, &root, &iter, 0) { + printk("contig %ld %p\n", iter.index, *slot); + if (first) { + radix_tree_insert(&root, 1, ptr); + first = false; + } + if (radix_tree_deref_retry(*slot)) { + printk("retry %ld\n", iter.index); + slot = radix_tree_iter_retry(&iter); + continue; + } + } + + radix_tree_delete(&root, 0); + radix_tree_delete(&root, 1); +} + void __init radix_tree_init(void) { radix_tree_node_cachep = kmem_cache_create("radix_tree_node", @@ -1499,4 +1559,6 @@ void __init radix_tree_init(void) radix_tree_node_ctor); radix_tree_init_maxindex(); hotcpu_notifier(radix_tree_callback, 0); + + test_iter_retry(); }