test_ref_tracker.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Referrence tracker self test.
  4. *
  5. * Copyright (c) 2021 Eric Dumazet <[email protected]>
  6. */
  7. #include <linux/init.h>
  8. #include <linux/module.h>
  9. #include <linux/delay.h>
  10. #include <linux/ref_tracker.h>
  11. #include <linux/slab.h>
  12. #include <linux/timer.h>
  13. static struct ref_tracker_dir ref_dir;
  14. static struct ref_tracker *tracker[20];
  15. #define TRT_ALLOC(X) static noinline void \
  16. alloctest_ref_tracker_alloc##X(struct ref_tracker_dir *dir, \
  17. struct ref_tracker **trackerp) \
  18. { \
  19. ref_tracker_alloc(dir, trackerp, GFP_KERNEL); \
  20. }
  21. TRT_ALLOC(1)
  22. TRT_ALLOC(2)
  23. TRT_ALLOC(3)
  24. TRT_ALLOC(4)
  25. TRT_ALLOC(5)
  26. TRT_ALLOC(6)
  27. TRT_ALLOC(7)
  28. TRT_ALLOC(8)
  29. TRT_ALLOC(9)
  30. TRT_ALLOC(10)
  31. TRT_ALLOC(11)
  32. TRT_ALLOC(12)
  33. TRT_ALLOC(13)
  34. TRT_ALLOC(14)
  35. TRT_ALLOC(15)
  36. TRT_ALLOC(16)
  37. TRT_ALLOC(17)
  38. TRT_ALLOC(18)
  39. TRT_ALLOC(19)
  40. #undef TRT_ALLOC
  41. static noinline void
  42. alloctest_ref_tracker_free(struct ref_tracker_dir *dir,
  43. struct ref_tracker **trackerp)
  44. {
  45. ref_tracker_free(dir, trackerp);
  46. }
  47. static struct timer_list test_ref_tracker_timer;
  48. static atomic_t test_ref_timer_done = ATOMIC_INIT(0);
  49. static void test_ref_tracker_timer_func(struct timer_list *t)
  50. {
  51. ref_tracker_alloc(&ref_dir, &tracker[0], GFP_ATOMIC);
  52. atomic_set(&test_ref_timer_done, 1);
  53. }
  54. static int __init test_ref_tracker_init(void)
  55. {
  56. int i;
  57. ref_tracker_dir_init(&ref_dir, 100);
  58. timer_setup(&test_ref_tracker_timer, test_ref_tracker_timer_func, 0);
  59. mod_timer(&test_ref_tracker_timer, jiffies + 1);
  60. alloctest_ref_tracker_alloc1(&ref_dir, &tracker[1]);
  61. alloctest_ref_tracker_alloc2(&ref_dir, &tracker[2]);
  62. alloctest_ref_tracker_alloc3(&ref_dir, &tracker[3]);
  63. alloctest_ref_tracker_alloc4(&ref_dir, &tracker[4]);
  64. alloctest_ref_tracker_alloc5(&ref_dir, &tracker[5]);
  65. alloctest_ref_tracker_alloc6(&ref_dir, &tracker[6]);
  66. alloctest_ref_tracker_alloc7(&ref_dir, &tracker[7]);
  67. alloctest_ref_tracker_alloc8(&ref_dir, &tracker[8]);
  68. alloctest_ref_tracker_alloc9(&ref_dir, &tracker[9]);
  69. alloctest_ref_tracker_alloc10(&ref_dir, &tracker[10]);
  70. alloctest_ref_tracker_alloc11(&ref_dir, &tracker[11]);
  71. alloctest_ref_tracker_alloc12(&ref_dir, &tracker[12]);
  72. alloctest_ref_tracker_alloc13(&ref_dir, &tracker[13]);
  73. alloctest_ref_tracker_alloc14(&ref_dir, &tracker[14]);
  74. alloctest_ref_tracker_alloc15(&ref_dir, &tracker[15]);
  75. alloctest_ref_tracker_alloc16(&ref_dir, &tracker[16]);
  76. alloctest_ref_tracker_alloc17(&ref_dir, &tracker[17]);
  77. alloctest_ref_tracker_alloc18(&ref_dir, &tracker[18]);
  78. alloctest_ref_tracker_alloc19(&ref_dir, &tracker[19]);
  79. /* free all trackers but first 0 and 1. */
  80. for (i = 2; i < ARRAY_SIZE(tracker); i++)
  81. alloctest_ref_tracker_free(&ref_dir, &tracker[i]);
  82. /* Attempt to free an already freed tracker. */
  83. alloctest_ref_tracker_free(&ref_dir, &tracker[2]);
  84. while (!atomic_read(&test_ref_timer_done))
  85. msleep(1);
  86. /* This should warn about tracker[0] & tracker[1] being not freed. */
  87. ref_tracker_dir_exit(&ref_dir);
  88. return 0;
  89. }
  90. static void __exit test_ref_tracker_exit(void)
  91. {
  92. }
  93. module_init(test_ref_tracker_init);
  94. module_exit(test_ref_tracker_exit);
  95. MODULE_LICENSE("GPL v2");