radix tree test suite: iteration test misuses RCU
[linux] / tools / testing / radix-tree / iteration_check.c
index 11d570c..df71cb8 100644 (file)
@@ -29,6 +29,8 @@ static void *add_entries_fn(void *arg)
 {
        int pgoff;
 
+       rcu_register_thread();
+
        while (!test_complete) {
                for (pgoff = 0; pgoff < 100; pgoff++) {
                        pthread_mutex_lock(&tree_lock);
@@ -38,6 +40,8 @@ static void *add_entries_fn(void *arg)
                }
        }
 
+       rcu_unregister_thread();
+
        return NULL;
 }
 
@@ -53,6 +57,8 @@ static void *tagged_iteration_fn(void *arg)
        struct radix_tree_iter iter;
        void **slot;
 
+       rcu_register_thread();
+
        while (!test_complete) {
                rcu_read_lock();
                radix_tree_for_each_tagged(slot, &tree, &iter, 0, TAG) {
@@ -72,12 +78,18 @@ static void *tagged_iteration_fn(void *arg)
                                continue;
                        }
 
-                       if (rand_r(&seeds[0]) % 50 == 0)
+                       if (rand_r(&seeds[0]) % 50 == 0) {
                                slot = radix_tree_iter_next(&iter);
+                               rcu_read_unlock();
+                               rcu_barrier();
+                               rcu_read_lock();
+                       }
                }
                rcu_read_unlock();
        }
 
+       rcu_unregister_thread();
+
        return NULL;
 }
 
@@ -93,6 +105,8 @@ static void *untagged_iteration_fn(void *arg)
        struct radix_tree_iter iter;
        void **slot;
 
+       rcu_register_thread();
+
        while (!test_complete) {
                rcu_read_lock();
                radix_tree_for_each_slot(slot, &tree, &iter, 0) {
@@ -112,12 +126,18 @@ static void *untagged_iteration_fn(void *arg)
                                continue;
                        }
 
-                       if (rand_r(&seeds[1]) % 50 == 0)
+                       if (rand_r(&seeds[1]) % 50 == 0) {
                                slot = radix_tree_iter_next(&iter);
+                               rcu_read_unlock();
+                               rcu_barrier();
+                               rcu_read_lock();
+                       }
                }
                rcu_read_unlock();
        }
 
+       rcu_unregister_thread();
+
        return NULL;
 }
 
@@ -127,6 +147,8 @@ static void *untagged_iteration_fn(void *arg)
  */
 static void *remove_entries_fn(void *arg)
 {
+       rcu_register_thread();
+
        while (!test_complete) {
                int pgoff;
 
@@ -137,6 +159,8 @@ static void *remove_entries_fn(void *arg)
                pthread_mutex_unlock(&tree_lock);
        }
 
+       rcu_unregister_thread();
+
        return NULL;
 }