diff options
author | Matthew Wilcox <willy@linux.intel.com> | 2016-12-14 18:09:01 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-14 19:04:10 -0500 |
commit | e157b555945fb16ddc6cce605a1eb6b4135ea5f1 (patch) | |
tree | f0b53b641059c010cfd38a32ae7f4f3b27b04303 /tools/testing/radix-tree/multiorder.c | |
parent | 175542f575723e43f897ddb09d0011c13f7cf0ec (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.c | 64 |
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 | ||
392 | static 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 | |||
446 | static 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 | |||
392 | void multiorder_checks(void) | 455 | void 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 | } |