aboutsummaryrefslogtreecommitdiffstats
path: root/tools/testing/radix-tree/multiorder.c
diff options
context:
space:
mode:
authorMatthew Wilcox <willy@linux.intel.com>2016-12-14 18:09:01 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-12-14 19:04:10 -0500
commite157b555945fb16ddc6cce605a1eb6b4135ea5f1 (patch)
treef0b53b641059c010cfd38a32ae7f4f3b27b04303 /tools/testing/radix-tree/multiorder.c
parent175542f575723e43f897ddb09d0011c13f7cf0ec (diff)
radix-tree: add radix_tree_split
This new function splits a larger multiorder entry into smaller entries (potentially multi-order entries). These entries are initialised to RADIX_TREE_RETRY to ensure that RCU walkers who see this state aren't confused. The caller should then call radix_tree_for_each_slot() and radix_tree_replace_slot() in order to turn these retry entries into the intended new entries. Tags are replicated from the original multiorder entry into each new entry. Link: http://lkml.kernel.org/r/1480369871-5271-59-git-send-email-mawilcox@linuxonhyperv.com Signed-off-by: Matthew Wilcox <willy@linux.intel.com> Tested-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: Konstantin Khlebnikov <koct9i@gmail.com> Cc: Ross Zwisler <ross.zwisler@linux.intel.com> Cc: Matthew Wilcox <mawilcox@microsoft.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'tools/testing/radix-tree/multiorder.c')
-rw-r--r--tools/testing/radix-tree/multiorder.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/tools/testing/radix-tree/multiorder.c b/tools/testing/radix-tree/multiorder.c
index c9f656cf5f52..fa6effe997a3 100644
--- a/tools/testing/radix-tree/multiorder.c
+++ b/tools/testing/radix-tree/multiorder.c
@@ -389,6 +389,69 @@ static void multiorder_join(void)
389 } 389 }
390} 390}
391 391
392static void __multiorder_split(int old_order, int new_order)
393{
394 RADIX_TREE(tree, GFP_KERNEL);
395 void **slot;
396 struct radix_tree_iter iter;
397 struct radix_tree_node *node;
398 void *item;
399
400 item_insert_order(&tree, 0, old_order);
401 radix_tree_tag_set(&tree, 0, 2);
402 radix_tree_split(&tree, 0, new_order);
403 radix_tree_for_each_slot(slot, &tree, &iter, 0) {
404 radix_tree_iter_replace(&tree, &iter, slot,
405 item_create(iter.index, new_order));
406 }
407
408 item_kill_tree(&tree);
409
410 __radix_tree_insert(&tree, 0, old_order, (void *)0x12);
411
412 item = __radix_tree_lookup(&tree, 0, &node, NULL);
413 assert(item == (void *)0x12);
414 assert(node->exceptional > 0);
415
416 radix_tree_split(&tree, 0, new_order);
417 radix_tree_for_each_slot(slot, &tree, &iter, 0) {
418 radix_tree_iter_replace(&tree, &iter, slot,
419 item_create(iter.index, new_order));
420 }
421
422 item = __radix_tree_lookup(&tree, 0, &node, NULL);
423 assert(item != (void *)0x12);
424 assert(node->exceptional == 0);
425
426 item_kill_tree(&tree);
427
428 __radix_tree_insert(&tree, 0, old_order, (void *)0x12);
429
430 item = __radix_tree_lookup(&tree, 0, &node, NULL);
431 assert(item == (void *)0x12);
432 assert(node->exceptional > 0);
433
434 radix_tree_split(&tree, 0, new_order);
435 radix_tree_for_each_slot(slot, &tree, &iter, 0) {
436 radix_tree_iter_replace(&tree, &iter, slot, (void *)0x16);
437 }
438
439 item = __radix_tree_lookup(&tree, 0, &node, NULL);
440 assert(item == (void *)0x16);
441 assert(node->exceptional > 0);
442
443 item_kill_tree(&tree);
444}
445
446static void multiorder_split(void)
447{
448 int i, j;
449
450 for (i = 9; i < 19; i++)
451 for (j = 0; j < i; j++)
452 __multiorder_split(i, j);
453}
454
392void multiorder_checks(void) 455void multiorder_checks(void)
393{ 456{
394 int i; 457 int i;
@@ -407,4 +470,5 @@ void multiorder_checks(void)
407 multiorder_iteration(); 470 multiorder_iteration();
408 multiorder_tagged_iteration(); 471 multiorder_tagged_iteration();
409 multiorder_join(); 472 multiorder_join();
473 multiorder_split();
410} 474}