test_ratelimit.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. #include <kunit/test.h>
  3. #include <linux/ratelimit.h>
  4. #include <linux/module.h>
  5. #include <linux/kthread.h>
  6. #include <linux/cpumask.h>
  7. /* a simple boot-time regression test */
  8. #define TESTRL_INTERVAL (5 * HZ)
  9. static DEFINE_RATELIMIT_STATE(testrl, TESTRL_INTERVAL, 3);
  10. #define test_ratelimited(test, expected) \
  11. KUNIT_ASSERT_EQ(test, ___ratelimit(&testrl, "test_ratelimit_smoke"), (expected))
  12. static void test_ratelimit_smoke(struct kunit *test)
  13. {
  14. // Check settings.
  15. KUNIT_ASSERT_GE(test, TESTRL_INTERVAL, 100);
  16. // Test normal operation.
  17. test_ratelimited(test, true);
  18. test_ratelimited(test, true);
  19. test_ratelimited(test, true);
  20. test_ratelimited(test, false);
  21. schedule_timeout_idle(TESTRL_INTERVAL / 2);
  22. test_ratelimited(test, false);
  23. schedule_timeout_idle(TESTRL_INTERVAL * 3 / 4);
  24. test_ratelimited(test, true);
  25. schedule_timeout_idle(2 * TESTRL_INTERVAL);
  26. test_ratelimited(test, true);
  27. test_ratelimited(test, true);
  28. schedule_timeout_idle(TESTRL_INTERVAL / 2 );
  29. test_ratelimited(test, true);
  30. schedule_timeout_idle(TESTRL_INTERVAL * 3 / 4);
  31. test_ratelimited(test, true);
  32. test_ratelimited(test, true);
  33. test_ratelimited(test, true);
  34. test_ratelimited(test, false);
  35. // Test disabling.
  36. testrl.burst = 0;
  37. test_ratelimited(test, false);
  38. testrl.burst = 2;
  39. testrl.interval = 0;
  40. test_ratelimited(test, true);
  41. test_ratelimited(test, true);
  42. test_ratelimited(test, true);
  43. test_ratelimited(test, true);
  44. test_ratelimited(test, true);
  45. test_ratelimited(test, true);
  46. test_ratelimited(test, true);
  47. // Testing re-enabling.
  48. testrl.interval = TESTRL_INTERVAL;
  49. test_ratelimited(test, true);
  50. test_ratelimited(test, true);
  51. test_ratelimited(test, false);
  52. test_ratelimited(test, false);
  53. }
  54. static struct ratelimit_state stressrl = RATELIMIT_STATE_INIT_FLAGS("stressrl", HZ / 10, 3,
  55. RATELIMIT_MSG_ON_RELEASE);
  56. static int doneflag;
  57. static const int stress_duration = 2 * HZ;
  58. struct stress_kthread {
  59. unsigned long nattempts;
  60. unsigned long nunlimited;
  61. unsigned long nlimited;
  62. unsigned long nmissed;
  63. struct task_struct *tp;
  64. };
  65. static int test_ratelimit_stress_child(void *arg)
  66. {
  67. struct stress_kthread *sktp = arg;
  68. set_user_nice(current, MAX_NICE);
  69. WARN_ON_ONCE(!sktp->tp);
  70. while (!READ_ONCE(doneflag)) {
  71. sktp->nattempts++;
  72. if (___ratelimit(&stressrl, __func__))
  73. sktp->nunlimited++;
  74. else
  75. sktp->nlimited++;
  76. cond_resched();
  77. }
  78. sktp->nmissed = ratelimit_state_reset_miss(&stressrl);
  79. return 0;
  80. }
  81. static void test_ratelimit_stress(struct kunit *test)
  82. {
  83. int i;
  84. const int n_stress_kthread = cpumask_weight(cpu_online_mask);
  85. struct stress_kthread skt = { 0 };
  86. struct stress_kthread *sktp = kzalloc_objs(*sktp, n_stress_kthread);
  87. KUNIT_EXPECT_NOT_NULL_MSG(test, sktp, "Memory allocation failure");
  88. for (i = 0; i < n_stress_kthread; i++) {
  89. sktp[i].tp = kthread_run(test_ratelimit_stress_child, &sktp[i], "%s/%i",
  90. "test_ratelimit_stress_child", i);
  91. KUNIT_EXPECT_NOT_NULL_MSG(test, sktp, "kthread creation failure");
  92. pr_alert("Spawned test_ratelimit_stress_child %d\n", i);
  93. }
  94. schedule_timeout_idle(stress_duration);
  95. WRITE_ONCE(doneflag, 1);
  96. for (i = 0; i < n_stress_kthread; i++) {
  97. kthread_stop(sktp[i].tp);
  98. skt.nattempts += sktp[i].nattempts;
  99. skt.nunlimited += sktp[i].nunlimited;
  100. skt.nlimited += sktp[i].nlimited;
  101. skt.nmissed += sktp[i].nmissed;
  102. }
  103. KUNIT_ASSERT_EQ_MSG(test, skt.nunlimited + skt.nlimited, skt.nattempts,
  104. "Outcomes not equal to attempts");
  105. KUNIT_ASSERT_EQ_MSG(test, skt.nlimited, skt.nmissed, "Misses not equal to limits");
  106. }
  107. static struct kunit_case ratelimit_test_cases[] = {
  108. KUNIT_CASE_SLOW(test_ratelimit_smoke),
  109. KUNIT_CASE_SLOW(test_ratelimit_stress),
  110. {}
  111. };
  112. static struct kunit_suite ratelimit_test_suite = {
  113. .name = "lib_ratelimit",
  114. .test_cases = ratelimit_test_cases,
  115. };
  116. kunit_test_suites(&ratelimit_test_suite);
  117. MODULE_DESCRIPTION("___ratelimit() KUnit test suite");
  118. MODULE_LICENSE("GPL");