diff options
Diffstat (limited to 'tools/testing/radix-tree/test.c')
-rw-r--r-- | tools/testing/radix-tree/test.c | 92 |
1 files changed, 82 insertions, 10 deletions
diff --git a/tools/testing/radix-tree/test.c b/tools/testing/radix-tree/test.c index a6e8099eaf4f..e5726e373646 100644 --- a/tools/testing/radix-tree/test.c +++ b/tools/testing/radix-tree/test.c | |||
@@ -24,21 +24,29 @@ int item_tag_get(struct radix_tree_root *root, unsigned long index, int tag) | |||
24 | return radix_tree_tag_get(root, index, tag); | 24 | return radix_tree_tag_get(root, index, tag); |
25 | } | 25 | } |
26 | 26 | ||
27 | int __item_insert(struct radix_tree_root *root, struct item *item, | 27 | int __item_insert(struct radix_tree_root *root, struct item *item) |
28 | unsigned order) | ||
29 | { | 28 | { |
30 | return __radix_tree_insert(root, item->index, order, item); | 29 | return __radix_tree_insert(root, item->index, item->order, item); |
31 | } | 30 | } |
32 | 31 | ||
33 | int item_insert(struct radix_tree_root *root, unsigned long index) | 32 | int item_insert(struct radix_tree_root *root, unsigned long index) |
34 | { | 33 | { |
35 | return __item_insert(root, item_create(index), 0); | 34 | return __item_insert(root, item_create(index, 0)); |
36 | } | 35 | } |
37 | 36 | ||
38 | int item_insert_order(struct radix_tree_root *root, unsigned long index, | 37 | int item_insert_order(struct radix_tree_root *root, unsigned long index, |
39 | unsigned order) | 38 | unsigned order) |
40 | { | 39 | { |
41 | return __item_insert(root, item_create(index), order); | 40 | return __item_insert(root, item_create(index, order)); |
41 | } | ||
42 | |||
43 | void item_sanity(struct item *item, unsigned long index) | ||
44 | { | ||
45 | unsigned long mask; | ||
46 | assert(!radix_tree_is_internal_node(item)); | ||
47 | assert(item->order < BITS_PER_LONG); | ||
48 | mask = (1UL << item->order) - 1; | ||
49 | assert((item->index | mask) == (index | mask)); | ||
42 | } | 50 | } |
43 | 51 | ||
44 | int item_delete(struct radix_tree_root *root, unsigned long index) | 52 | int item_delete(struct radix_tree_root *root, unsigned long index) |
@@ -46,18 +54,19 @@ int item_delete(struct radix_tree_root *root, unsigned long index) | |||
46 | struct item *item = radix_tree_delete(root, index); | 54 | struct item *item = radix_tree_delete(root, index); |
47 | 55 | ||
48 | if (item) { | 56 | if (item) { |
49 | assert(item->index == index); | 57 | item_sanity(item, index); |
50 | free(item); | 58 | free(item); |
51 | return 1; | 59 | return 1; |
52 | } | 60 | } |
53 | return 0; | 61 | return 0; |
54 | } | 62 | } |
55 | 63 | ||
56 | struct item *item_create(unsigned long index) | 64 | struct item *item_create(unsigned long index, unsigned int order) |
57 | { | 65 | { |
58 | struct item *ret = malloc(sizeof(*ret)); | 66 | struct item *ret = malloc(sizeof(*ret)); |
59 | 67 | ||
60 | ret->index = index; | 68 | ret->index = index; |
69 | ret->order = order; | ||
61 | return ret; | 70 | return ret; |
62 | } | 71 | } |
63 | 72 | ||
@@ -66,8 +75,8 @@ void item_check_present(struct radix_tree_root *root, unsigned long index) | |||
66 | struct item *item; | 75 | struct item *item; |
67 | 76 | ||
68 | item = radix_tree_lookup(root, index); | 77 | item = radix_tree_lookup(root, index); |
69 | assert(item != 0); | 78 | assert(item != NULL); |
70 | assert(item->index == index); | 79 | item_sanity(item, index); |
71 | } | 80 | } |
72 | 81 | ||
73 | struct item *item_lookup(struct radix_tree_root *root, unsigned long index) | 82 | struct item *item_lookup(struct radix_tree_root *root, unsigned long index) |
@@ -80,7 +89,7 @@ void item_check_absent(struct radix_tree_root *root, unsigned long index) | |||
80 | struct item *item; | 89 | struct item *item; |
81 | 90 | ||
82 | item = radix_tree_lookup(root, index); | 91 | item = radix_tree_lookup(root, index); |
83 | assert(item == 0); | 92 | assert(item == NULL); |
84 | } | 93 | } |
85 | 94 | ||
86 | /* | 95 | /* |
@@ -142,6 +151,62 @@ void item_full_scan(struct radix_tree_root *root, unsigned long start, | |||
142 | assert(nfound == 0); | 151 | assert(nfound == 0); |
143 | } | 152 | } |
144 | 153 | ||
154 | /* Use the same pattern as tag_pages_for_writeback() in mm/page-writeback.c */ | ||
155 | int tag_tagged_items(struct radix_tree_root *root, pthread_mutex_t *lock, | ||
156 | unsigned long start, unsigned long end, unsigned batch, | ||
157 | unsigned iftag, unsigned thentag) | ||
158 | { | ||
159 | unsigned long tagged = 0; | ||
160 | struct radix_tree_iter iter; | ||
161 | void **slot; | ||
162 | |||
163 | if (batch == 0) | ||
164 | batch = 1; | ||
165 | |||
166 | if (lock) | ||
167 | pthread_mutex_lock(lock); | ||
168 | radix_tree_for_each_tagged(slot, root, &iter, start, iftag) { | ||
169 | if (iter.index > end) | ||
170 | break; | ||
171 | radix_tree_iter_tag_set(root, &iter, thentag); | ||
172 | tagged++; | ||
173 | if ((tagged % batch) != 0) | ||
174 | continue; | ||
175 | slot = radix_tree_iter_resume(slot, &iter); | ||
176 | if (lock) { | ||
177 | pthread_mutex_unlock(lock); | ||
178 | rcu_barrier(); | ||
179 | pthread_mutex_lock(lock); | ||
180 | } | ||
181 | } | ||
182 | if (lock) | ||
183 | pthread_mutex_unlock(lock); | ||
184 | |||
185 | return tagged; | ||
186 | } | ||
187 | |||
188 | /* Use the same pattern as find_swap_entry() in mm/shmem.c */ | ||
189 | unsigned long find_item(struct radix_tree_root *root, void *item) | ||
190 | { | ||
191 | struct radix_tree_iter iter; | ||
192 | void **slot; | ||
193 | unsigned long found = -1; | ||
194 | unsigned long checked = 0; | ||
195 | |||
196 | radix_tree_for_each_slot(slot, root, &iter, 0) { | ||
197 | if (*slot == item) { | ||
198 | found = iter.index; | ||
199 | break; | ||
200 | } | ||
201 | checked++; | ||
202 | if ((checked % 4) != 0) | ||
203 | continue; | ||
204 | slot = radix_tree_iter_resume(slot, &iter); | ||
205 | } | ||
206 | |||
207 | return found; | ||
208 | } | ||
209 | |||
145 | static int verify_node(struct radix_tree_node *slot, unsigned int tag, | 210 | static int verify_node(struct radix_tree_node *slot, unsigned int tag, |
146 | int tagged) | 211 | int tagged) |
147 | { | 212 | { |
@@ -200,9 +265,16 @@ void verify_tag_consistency(struct radix_tree_root *root, unsigned int tag) | |||
200 | 265 | ||
201 | void item_kill_tree(struct radix_tree_root *root) | 266 | void item_kill_tree(struct radix_tree_root *root) |
202 | { | 267 | { |
268 | struct radix_tree_iter iter; | ||
269 | void **slot; | ||
203 | struct item *items[32]; | 270 | struct item *items[32]; |
204 | int nfound; | 271 | int nfound; |
205 | 272 | ||
273 | radix_tree_for_each_slot(slot, root, &iter, 0) { | ||
274 | if (radix_tree_exceptional_entry(*slot)) | ||
275 | radix_tree_delete(root, iter.index); | ||
276 | } | ||
277 | |||
206 | while ((nfound = radix_tree_gang_lookup(root, (void **)items, 0, 32))) { | 278 | while ((nfound = radix_tree_gang_lookup(root, (void **)items, 0, 32))) { |
207 | int i; | 279 | int i; |
208 | 280 | ||