mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-23 23:32:14 +00:00
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>
This commit is contained in:
parent
175542f575
commit
e157b55594
3 changed files with 214 additions and 4 deletions
|
@ -389,6 +389,69 @@ static void multiorder_join(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void __multiorder_split(int old_order, int new_order)
|
||||
{
|
||||
RADIX_TREE(tree, GFP_KERNEL);
|
||||
void **slot;
|
||||
struct radix_tree_iter iter;
|
||||
struct radix_tree_node *node;
|
||||
void *item;
|
||||
|
||||
item_insert_order(&tree, 0, old_order);
|
||||
radix_tree_tag_set(&tree, 0, 2);
|
||||
radix_tree_split(&tree, 0, new_order);
|
||||
radix_tree_for_each_slot(slot, &tree, &iter, 0) {
|
||||
radix_tree_iter_replace(&tree, &iter, slot,
|
||||
item_create(iter.index, new_order));
|
||||
}
|
||||
|
||||
item_kill_tree(&tree);
|
||||
|
||||
__radix_tree_insert(&tree, 0, old_order, (void *)0x12);
|
||||
|
||||
item = __radix_tree_lookup(&tree, 0, &node, NULL);
|
||||
assert(item == (void *)0x12);
|
||||
assert(node->exceptional > 0);
|
||||
|
||||
radix_tree_split(&tree, 0, new_order);
|
||||
radix_tree_for_each_slot(slot, &tree, &iter, 0) {
|
||||
radix_tree_iter_replace(&tree, &iter, slot,
|
||||
item_create(iter.index, new_order));
|
||||
}
|
||||
|
||||
item = __radix_tree_lookup(&tree, 0, &node, NULL);
|
||||
assert(item != (void *)0x12);
|
||||
assert(node->exceptional == 0);
|
||||
|
||||
item_kill_tree(&tree);
|
||||
|
||||
__radix_tree_insert(&tree, 0, old_order, (void *)0x12);
|
||||
|
||||
item = __radix_tree_lookup(&tree, 0, &node, NULL);
|
||||
assert(item == (void *)0x12);
|
||||
assert(node->exceptional > 0);
|
||||
|
||||
radix_tree_split(&tree, 0, new_order);
|
||||
radix_tree_for_each_slot(slot, &tree, &iter, 0) {
|
||||
radix_tree_iter_replace(&tree, &iter, slot, (void *)0x16);
|
||||
}
|
||||
|
||||
item = __radix_tree_lookup(&tree, 0, &node, NULL);
|
||||
assert(item == (void *)0x16);
|
||||
assert(node->exceptional > 0);
|
||||
|
||||
item_kill_tree(&tree);
|
||||
}
|
||||
|
||||
static void multiorder_split(void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 9; i < 19; i++)
|
||||
for (j = 0; j < i; j++)
|
||||
__multiorder_split(i, j);
|
||||
}
|
||||
|
||||
void multiorder_checks(void)
|
||||
{
|
||||
int i;
|
||||
|
@ -407,4 +470,5 @@ void multiorder_checks(void)
|
|||
multiorder_iteration();
|
||||
multiorder_tagged_iteration();
|
||||
multiorder_join();
|
||||
multiorder_split();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue