xref: /openbmc/linux/tools/testing/radix-tree/iteration_check_2.c (revision ead5d1f4d877e92c051e1a1ade623d0d30e71619)
1*7e934cf5SMatthew Wilcox (Oracle) // SPDX-License-Identifier: GPL-2.0-or-later
2*7e934cf5SMatthew Wilcox (Oracle) /*
3*7e934cf5SMatthew Wilcox (Oracle)  * iteration_check_2.c: Check that deleting a tagged entry doesn't cause
4*7e934cf5SMatthew Wilcox (Oracle)  * an RCU walker to finish early.
5*7e934cf5SMatthew Wilcox (Oracle)  * Copyright (c) 2020 Oracle
6*7e934cf5SMatthew Wilcox (Oracle)  * Author: Matthew Wilcox <willy@infradead.org>
7*7e934cf5SMatthew Wilcox (Oracle)  */
8*7e934cf5SMatthew Wilcox (Oracle) #include <pthread.h>
9*7e934cf5SMatthew Wilcox (Oracle) #include "test.h"
10*7e934cf5SMatthew Wilcox (Oracle) 
11*7e934cf5SMatthew Wilcox (Oracle) static volatile bool test_complete;
12*7e934cf5SMatthew Wilcox (Oracle) 
iterator(void * arg)13*7e934cf5SMatthew Wilcox (Oracle) static void *iterator(void *arg)
14*7e934cf5SMatthew Wilcox (Oracle) {
15*7e934cf5SMatthew Wilcox (Oracle) 	XA_STATE(xas, arg, 0);
16*7e934cf5SMatthew Wilcox (Oracle) 	void *entry;
17*7e934cf5SMatthew Wilcox (Oracle) 
18*7e934cf5SMatthew Wilcox (Oracle) 	rcu_register_thread();
19*7e934cf5SMatthew Wilcox (Oracle) 
20*7e934cf5SMatthew Wilcox (Oracle) 	while (!test_complete) {
21*7e934cf5SMatthew Wilcox (Oracle) 		xas_set(&xas, 0);
22*7e934cf5SMatthew Wilcox (Oracle) 		rcu_read_lock();
23*7e934cf5SMatthew Wilcox (Oracle) 		xas_for_each_marked(&xas, entry, ULONG_MAX, XA_MARK_0)
24*7e934cf5SMatthew Wilcox (Oracle) 			;
25*7e934cf5SMatthew Wilcox (Oracle) 		rcu_read_unlock();
26*7e934cf5SMatthew Wilcox (Oracle) 		assert(xas.xa_index >= 100);
27*7e934cf5SMatthew Wilcox (Oracle) 	}
28*7e934cf5SMatthew Wilcox (Oracle) 
29*7e934cf5SMatthew Wilcox (Oracle) 	rcu_unregister_thread();
30*7e934cf5SMatthew Wilcox (Oracle) 	return NULL;
31*7e934cf5SMatthew Wilcox (Oracle) }
32*7e934cf5SMatthew Wilcox (Oracle) 
throbber(void * arg)33*7e934cf5SMatthew Wilcox (Oracle) static void *throbber(void *arg)
34*7e934cf5SMatthew Wilcox (Oracle) {
35*7e934cf5SMatthew Wilcox (Oracle) 	struct xarray *xa = arg;
36*7e934cf5SMatthew Wilcox (Oracle) 
37*7e934cf5SMatthew Wilcox (Oracle) 	rcu_register_thread();
38*7e934cf5SMatthew Wilcox (Oracle) 
39*7e934cf5SMatthew Wilcox (Oracle) 	while (!test_complete) {
40*7e934cf5SMatthew Wilcox (Oracle) 		int i;
41*7e934cf5SMatthew Wilcox (Oracle) 
42*7e934cf5SMatthew Wilcox (Oracle) 		for (i = 0; i < 100; i++) {
43*7e934cf5SMatthew Wilcox (Oracle) 			xa_store(xa, i, xa_mk_value(i), GFP_KERNEL);
44*7e934cf5SMatthew Wilcox (Oracle) 			xa_set_mark(xa, i, XA_MARK_0);
45*7e934cf5SMatthew Wilcox (Oracle) 		}
46*7e934cf5SMatthew Wilcox (Oracle) 		for (i = 0; i < 100; i++)
47*7e934cf5SMatthew Wilcox (Oracle) 			xa_erase(xa, i);
48*7e934cf5SMatthew Wilcox (Oracle) 	}
49*7e934cf5SMatthew Wilcox (Oracle) 
50*7e934cf5SMatthew Wilcox (Oracle) 	rcu_unregister_thread();
51*7e934cf5SMatthew Wilcox (Oracle) 	return NULL;
52*7e934cf5SMatthew Wilcox (Oracle) }
53*7e934cf5SMatthew Wilcox (Oracle) 
iteration_test2(unsigned test_duration)54*7e934cf5SMatthew Wilcox (Oracle) void iteration_test2(unsigned test_duration)
55*7e934cf5SMatthew Wilcox (Oracle) {
56*7e934cf5SMatthew Wilcox (Oracle) 	pthread_t threads[2];
57*7e934cf5SMatthew Wilcox (Oracle) 	DEFINE_XARRAY(array);
58*7e934cf5SMatthew Wilcox (Oracle) 	int i;
59*7e934cf5SMatthew Wilcox (Oracle) 
60*7e934cf5SMatthew Wilcox (Oracle) 	printv(1, "Running iteration test 2 for %d seconds\n", test_duration);
61*7e934cf5SMatthew Wilcox (Oracle) 
62*7e934cf5SMatthew Wilcox (Oracle) 	test_complete = false;
63*7e934cf5SMatthew Wilcox (Oracle) 
64*7e934cf5SMatthew Wilcox (Oracle) 	xa_store(&array, 100, xa_mk_value(100), GFP_KERNEL);
65*7e934cf5SMatthew Wilcox (Oracle) 	xa_set_mark(&array, 100, XA_MARK_0);
66*7e934cf5SMatthew Wilcox (Oracle) 
67*7e934cf5SMatthew Wilcox (Oracle) 	if (pthread_create(&threads[0], NULL, iterator, &array)) {
68*7e934cf5SMatthew Wilcox (Oracle) 		perror("create iterator thread");
69*7e934cf5SMatthew Wilcox (Oracle) 		exit(1);
70*7e934cf5SMatthew Wilcox (Oracle) 	}
71*7e934cf5SMatthew Wilcox (Oracle) 	if (pthread_create(&threads[1], NULL, throbber, &array)) {
72*7e934cf5SMatthew Wilcox (Oracle) 		perror("create throbber thread");
73*7e934cf5SMatthew Wilcox (Oracle) 		exit(1);
74*7e934cf5SMatthew Wilcox (Oracle) 	}
75*7e934cf5SMatthew Wilcox (Oracle) 
76*7e934cf5SMatthew Wilcox (Oracle) 	sleep(test_duration);
77*7e934cf5SMatthew Wilcox (Oracle) 	test_complete = true;
78*7e934cf5SMatthew Wilcox (Oracle) 
79*7e934cf5SMatthew Wilcox (Oracle) 	for (i = 0; i < 2; i++) {
80*7e934cf5SMatthew Wilcox (Oracle) 		if (pthread_join(threads[i], NULL)) {
81*7e934cf5SMatthew Wilcox (Oracle) 			perror("pthread_join");
82*7e934cf5SMatthew Wilcox (Oracle) 			exit(1);
83*7e934cf5SMatthew Wilcox (Oracle) 		}
84*7e934cf5SMatthew Wilcox (Oracle) 	}
85*7e934cf5SMatthew Wilcox (Oracle) 
86*7e934cf5SMatthew Wilcox (Oracle) 	xa_destroy(&array);
87*7e934cf5SMatthew Wilcox (Oracle) }
88