aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorMatthew Wilcox <willy@linux.intel.com>2016-12-14 18:09:04 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-12-14 19:04:10 -0500
commit2791653a6814d170fa893344618563a7b1da95c6 (patch)
tree635c8ca43b49ac15836e5d4b5786d64733661755 /tools
parente157b555945fb16ddc6cce605a1eb6b4135ea5f1 (diff)
radix-tree: add radix_tree_split_preload()
Calculate how many nodes we need to allocate to split an old_order entry into multiple entries, each of size new_order. The test suite checks that we allocated exactly the right number of nodes; neither too many (checked by rtp->nr == 0), nor too few (checked by comparing nr_allocated before and after the call to radix_tree_split()). Link: http://lkml.kernel.org/r/1480369871-5271-60-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')
-rw-r--r--tools/testing/radix-tree/multiorder.c42
-rw-r--r--tools/testing/radix-tree/test.h5
2 files changed, 45 insertions, 2 deletions
diff --git a/tools/testing/radix-tree/multiorder.c b/tools/testing/radix-tree/multiorder.c
index fa6effe997a3..5421f015f46c 100644
--- a/tools/testing/radix-tree/multiorder.c
+++ b/tools/testing/radix-tree/multiorder.c
@@ -389,35 +389,67 @@ static void multiorder_join(void)
389 } 389 }
390} 390}
391 391
392static void check_mem(unsigned old_order, unsigned new_order, unsigned alloc)
393{
394 struct radix_tree_preload *rtp = &radix_tree_preloads;
395 if (rtp->nr != 0)
396 printf("split(%u %u) remaining %u\n", old_order, new_order,
397 rtp->nr);
398 /*
399 * Can't check for equality here as some nodes may have been
400 * RCU-freed while we ran. But we should never finish with more
401 * nodes allocated since they should have all been preloaded.
402 */
403 if (nr_allocated > alloc)
404 printf("split(%u %u) allocated %u %u\n", old_order, new_order,
405 alloc, nr_allocated);
406}
407
392static void __multiorder_split(int old_order, int new_order) 408static void __multiorder_split(int old_order, int new_order)
393{ 409{
394 RADIX_TREE(tree, GFP_KERNEL); 410 RADIX_TREE(tree, GFP_ATOMIC);
395 void **slot; 411 void **slot;
396 struct radix_tree_iter iter; 412 struct radix_tree_iter iter;
397 struct radix_tree_node *node; 413 struct radix_tree_node *node;
398 void *item; 414 void *item;
415 unsigned alloc;
416
417 radix_tree_preload(GFP_KERNEL);
418 assert(item_insert_order(&tree, 0, old_order) == 0);
419 radix_tree_preload_end();
420
421 /* Wipe out the preloaded cache or it'll confuse check_mem() */
422 radix_tree_cpu_dead(0);
399 423
400 item_insert_order(&tree, 0, old_order);
401 radix_tree_tag_set(&tree, 0, 2); 424 radix_tree_tag_set(&tree, 0, 2);
425
426 radix_tree_split_preload(old_order, new_order, GFP_KERNEL);
427 alloc = nr_allocated;
402 radix_tree_split(&tree, 0, new_order); 428 radix_tree_split(&tree, 0, new_order);
429 check_mem(old_order, new_order, alloc);
403 radix_tree_for_each_slot(slot, &tree, &iter, 0) { 430 radix_tree_for_each_slot(slot, &tree, &iter, 0) {
404 radix_tree_iter_replace(&tree, &iter, slot, 431 radix_tree_iter_replace(&tree, &iter, slot,
405 item_create(iter.index, new_order)); 432 item_create(iter.index, new_order));
406 } 433 }
434 radix_tree_preload_end();
407 435
408 item_kill_tree(&tree); 436 item_kill_tree(&tree);
409 437
438 radix_tree_preload(GFP_KERNEL);
410 __radix_tree_insert(&tree, 0, old_order, (void *)0x12); 439 __radix_tree_insert(&tree, 0, old_order, (void *)0x12);
440 radix_tree_preload_end();
411 441
412 item = __radix_tree_lookup(&tree, 0, &node, NULL); 442 item = __radix_tree_lookup(&tree, 0, &node, NULL);
413 assert(item == (void *)0x12); 443 assert(item == (void *)0x12);
414 assert(node->exceptional > 0); 444 assert(node->exceptional > 0);
415 445
446 radix_tree_split_preload(old_order, new_order, GFP_KERNEL);
416 radix_tree_split(&tree, 0, new_order); 447 radix_tree_split(&tree, 0, new_order);
417 radix_tree_for_each_slot(slot, &tree, &iter, 0) { 448 radix_tree_for_each_slot(slot, &tree, &iter, 0) {
418 radix_tree_iter_replace(&tree, &iter, slot, 449 radix_tree_iter_replace(&tree, &iter, slot,
419 item_create(iter.index, new_order)); 450 item_create(iter.index, new_order));
420 } 451 }
452 radix_tree_preload_end();
421 453
422 item = __radix_tree_lookup(&tree, 0, &node, NULL); 454 item = __radix_tree_lookup(&tree, 0, &node, NULL);
423 assert(item != (void *)0x12); 455 assert(item != (void *)0x12);
@@ -425,16 +457,20 @@ static void __multiorder_split(int old_order, int new_order)
425 457
426 item_kill_tree(&tree); 458 item_kill_tree(&tree);
427 459
460 radix_tree_preload(GFP_KERNEL);
428 __radix_tree_insert(&tree, 0, old_order, (void *)0x12); 461 __radix_tree_insert(&tree, 0, old_order, (void *)0x12);
462 radix_tree_preload_end();
429 463
430 item = __radix_tree_lookup(&tree, 0, &node, NULL); 464 item = __radix_tree_lookup(&tree, 0, &node, NULL);
431 assert(item == (void *)0x12); 465 assert(item == (void *)0x12);
432 assert(node->exceptional > 0); 466 assert(node->exceptional > 0);
433 467
468 radix_tree_split_preload(old_order, new_order, GFP_KERNEL);
434 radix_tree_split(&tree, 0, new_order); 469 radix_tree_split(&tree, 0, new_order);
435 radix_tree_for_each_slot(slot, &tree, &iter, 0) { 470 radix_tree_for_each_slot(slot, &tree, &iter, 0) {
436 radix_tree_iter_replace(&tree, &iter, slot, (void *)0x16); 471 radix_tree_iter_replace(&tree, &iter, slot, (void *)0x16);
437 } 472 }
473 radix_tree_preload_end();
438 474
439 item = __radix_tree_lookup(&tree, 0, &node, NULL); 475 item = __radix_tree_lookup(&tree, 0, &node, NULL);
440 assert(item == (void *)0x16); 476 assert(item == (void *)0x16);
@@ -471,4 +507,6 @@ void multiorder_checks(void)
471 multiorder_tagged_iteration(); 507 multiorder_tagged_iteration();
472 multiorder_join(); 508 multiorder_join();
473 multiorder_split(); 509 multiorder_split();
510
511 radix_tree_cpu_dead(0);
474} 512}
diff --git a/tools/testing/radix-tree/test.h b/tools/testing/radix-tree/test.h
index e11e4d260b4e..7c2611caa6d2 100644
--- a/tools/testing/radix-tree/test.h
+++ b/tools/testing/radix-tree/test.h
@@ -52,3 +52,8 @@ int root_tag_get(struct radix_tree_root *root, unsigned int tag);
52unsigned long node_maxindex(struct radix_tree_node *); 52unsigned long node_maxindex(struct radix_tree_node *);
53unsigned long shift_maxindex(unsigned int shift); 53unsigned long shift_maxindex(unsigned int shift);
54int radix_tree_cpu_dead(unsigned int cpu); 54int radix_tree_cpu_dead(unsigned int cpu);
55struct radix_tree_preload {
56 unsigned nr;
57 struct radix_tree_node *nodes;
58};
59extern struct radix_tree_preload radix_tree_preloads;