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