forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
kernel/tools/testing/radix-tree/idr-test.c
....@@ -1,15 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * idr-test.c: Test the IDR API
34 * Copyright (c) 2016 Matthew Wilcox <willy@infradead.org>
4
- *
5
- * This program is free software; you can redistribute it and/or modify it
6
- * under the terms and conditions of the GNU General Public License,
7
- * version 2, as published by the Free Software Foundation.
8
- *
9
- * This program is distributed in the hope it will be useful, but WITHOUT
10
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
- * more details.
135 */
146 #include <linux/bitmap.h>
157 #include <linux/idr.h>
....@@ -19,7 +11,7 @@
1911
2012 #include "test.h"
2113
22
-#define DUMMY_PTR ((void *)0x12)
14
+#define DUMMY_PTR ((void *)0x10)
2315
2416 int item_idr_free(int id, void *p, void *data)
2517 {
....@@ -227,10 +219,64 @@
227219 idr_u32_test1(&idr, 0xffffffff);
228220 }
229221
230
-static inline void *idr_mk_value(unsigned long v)
222
+static void idr_align_test(struct idr *idr)
231223 {
232
- BUG_ON((long)v < 0);
233
- return (void *)((v & 1) | 2 | (v << 1));
224
+ char name[] = "Motorola 68000";
225
+ int i, id;
226
+ void *entry;
227
+
228
+ for (i = 0; i < 9; i++) {
229
+ BUG_ON(idr_alloc(idr, &name[i], 0, 0, GFP_KERNEL) != i);
230
+ idr_for_each_entry(idr, entry, id);
231
+ }
232
+ idr_destroy(idr);
233
+
234
+ for (i = 1; i < 10; i++) {
235
+ BUG_ON(idr_alloc(idr, &name[i], 0, 0, GFP_KERNEL) != i - 1);
236
+ idr_for_each_entry(idr, entry, id);
237
+ }
238
+ idr_destroy(idr);
239
+
240
+ for (i = 2; i < 11; i++) {
241
+ BUG_ON(idr_alloc(idr, &name[i], 0, 0, GFP_KERNEL) != i - 2);
242
+ idr_for_each_entry(idr, entry, id);
243
+ }
244
+ idr_destroy(idr);
245
+
246
+ for (i = 3; i < 12; i++) {
247
+ BUG_ON(idr_alloc(idr, &name[i], 0, 0, GFP_KERNEL) != i - 3);
248
+ idr_for_each_entry(idr, entry, id);
249
+ }
250
+ idr_destroy(idr);
251
+
252
+ for (i = 0; i < 8; i++) {
253
+ BUG_ON(idr_alloc(idr, &name[i], 0, 0, GFP_KERNEL) != 0);
254
+ BUG_ON(idr_alloc(idr, &name[i + 1], 0, 0, GFP_KERNEL) != 1);
255
+ idr_for_each_entry(idr, entry, id);
256
+ idr_remove(idr, 1);
257
+ idr_for_each_entry(idr, entry, id);
258
+ idr_remove(idr, 0);
259
+ BUG_ON(!idr_is_empty(idr));
260
+ }
261
+
262
+ for (i = 0; i < 8; i++) {
263
+ BUG_ON(idr_alloc(idr, NULL, 0, 0, GFP_KERNEL) != 0);
264
+ idr_for_each_entry(idr, entry, id);
265
+ idr_replace(idr, &name[i], 0);
266
+ idr_for_each_entry(idr, entry, id);
267
+ BUG_ON(idr_find(idr, 0) != &name[i]);
268
+ idr_remove(idr, 0);
269
+ }
270
+
271
+ for (i = 0; i < 8; i++) {
272
+ BUG_ON(idr_alloc(idr, &name[i], 0, 0, GFP_KERNEL) != 0);
273
+ BUG_ON(idr_alloc(idr, NULL, 0, 0, GFP_KERNEL) != 1);
274
+ idr_remove(idr, 1);
275
+ idr_for_each_entry(idr, entry, id);
276
+ idr_replace(idr, &name[i + 1], 0);
277
+ idr_for_each_entry(idr, entry, id);
278
+ idr_remove(idr, 0);
279
+ }
234280 }
235281
236282 DEFINE_IDR(find_idr);
....@@ -242,7 +288,7 @@
242288
243289 rcu_register_thread();
244290 do {
245
- idr_alloc(&find_idr, idr_mk_value(id), id, id + 1, GFP_KERNEL);
291
+ idr_alloc(&find_idr, xa_mk_value(id), id, id + 1, GFP_KERNEL);
246292 idr_remove(&find_idr, id);
247293 } while (time(NULL) < start + 10);
248294 rcu_unregister_thread();
....@@ -255,16 +301,20 @@
255301 pthread_t throbber;
256302 time_t start = time(NULL);
257303
258
- pthread_create(&throbber, NULL, idr_throbber, &throbber_id);
259
-
260
- BUG_ON(idr_alloc(&find_idr, idr_mk_value(anchor_id), anchor_id,
304
+ BUG_ON(idr_alloc(&find_idr, xa_mk_value(anchor_id), anchor_id,
261305 anchor_id + 1, GFP_KERNEL) != anchor_id);
262306
307
+ pthread_create(&throbber, NULL, idr_throbber, &throbber_id);
308
+
309
+ rcu_read_lock();
263310 do {
264311 int id = 0;
265312 void *entry = idr_get_next(&find_idr, &id);
266
- BUG_ON(entry != idr_mk_value(id));
313
+ rcu_read_unlock();
314
+ BUG_ON(entry != xa_mk_value(id));
315
+ rcu_read_lock();
267316 } while (time(NULL) < start + 11);
317
+ rcu_read_unlock();
268318
269319 pthread_join(throbber, NULL);
270320
....@@ -358,6 +408,7 @@
358408 idr_u32_test(4);
359409 idr_u32_test(1);
360410 idr_u32_test(0);
411
+ idr_align_test(&idr);
361412 idr_find_test();
362413 }
363414
....@@ -396,16 +447,16 @@
396447 DEFINE_IDA(ida);
397448 unsigned long i;
398449
399
- radix_tree_cpu_dead(1);
400450 for (i = 0; i < 1000000; i++) {
401451 int id = ida_alloc(&ida, GFP_NOWAIT);
402452 if (id == -ENOMEM) {
403
- IDA_BUG_ON(&ida, (i % IDA_BITMAP_BITS) !=
404
- BITS_PER_LONG - 2);
453
+ IDA_BUG_ON(&ida, ((i % IDA_BITMAP_BITS) !=
454
+ BITS_PER_XA_VALUE) &&
455
+ ((i % IDA_BITMAP_BITS) != 0));
405456 id = ida_alloc(&ida, GFP_KERNEL);
406457 } else {
407458 IDA_BUG_ON(&ida, (i % IDA_BITMAP_BITS) ==
408
- BITS_PER_LONG - 2);
459
+ BITS_PER_XA_VALUE);
409460 }
410461 IDA_BUG_ON(&ida, id != i);
411462 }
....@@ -476,8 +527,27 @@
476527 return NULL;
477528 }
478529
530
+static void *ida_leak_fn(void *arg)
531
+{
532
+ struct ida *ida = arg;
533
+ time_t s = time(NULL);
534
+ int i, ret;
535
+
536
+ rcu_register_thread();
537
+
538
+ do for (i = 0; i < 1000; i++) {
539
+ ret = ida_alloc_range(ida, 128, 128, GFP_KERNEL);
540
+ if (ret >= 0)
541
+ ida_free(ida, 128);
542
+ } while (time(NULL) < s + 2);
543
+
544
+ rcu_unregister_thread();
545
+ return NULL;
546
+}
547
+
479548 void ida_thread_tests(void)
480549 {
550
+ DEFINE_IDA(ida);
481551 pthread_t threads[20];
482552 int i;
483553
....@@ -489,6 +559,16 @@
489559
490560 while (i--)
491561 pthread_join(threads[i], NULL);
562
+
563
+ for (i = 0; i < ARRAY_SIZE(threads); i++)
564
+ if (pthread_create(&threads[i], NULL, ida_leak_fn, &ida)) {
565
+ perror("creating ida thread");
566
+ exit(1);
567
+ }
568
+
569
+ while (i--)
570
+ pthread_join(threads[i], NULL);
571
+ assert(ida_is_empty(&ida));
492572 }
493573
494574 void ida_tests(void)
....@@ -501,6 +581,7 @@
501581
502582 int __weak main(void)
503583 {
584
+ rcu_register_thread();
504585 radix_tree_init();
505586 idr_checks();
506587 ida_tests();
....@@ -508,5 +589,6 @@
508589 rcu_barrier();
509590 if (nr_allocated)
510591 printf("nr_allocated = %d\n", nr_allocated);
592
+ rcu_unregister_thread();
511593 return 0;
512594 }