monitor_rtapp.rst 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. Real-time application monitors
  2. ==============================
  3. - Name: rtapp
  4. - Type: container for multiple monitors
  5. - Author: Nam Cao <namcao@linutronix.de>
  6. Description
  7. -----------
  8. Real-time applications may have design flaws such that they experience
  9. unexpected latency and fail to meet their time requirements. Often, these flaws
  10. follow a few patterns:
  11. - Page faults: A real-time thread may access memory that does not have a
  12. mapped physical backing or must first be copied (such as for copy-on-write).
  13. Thus a page fault is raised and the kernel must first perform the expensive
  14. action. This causes significant delays to the real-time thread
  15. - Priority inversion: A real-time thread blocks waiting for a lower-priority
  16. thread. This causes the real-time thread to effectively take on the
  17. scheduling priority of the lower-priority thread. For example, the real-time
  18. thread needs to access a shared resource that is protected by a
  19. non-pi-mutex, but the mutex is currently owned by a non-real-time thread.
  20. The `rtapp` monitor detects these patterns. It aids developers to identify
  21. reasons for unexpected latency with real-time applications. It is a container of
  22. multiple sub-monitors described in the following sections.
  23. Monitor pagefault
  24. +++++++++++++++++
  25. The `pagefault` monitor reports real-time tasks raising page faults. Its
  26. specification is::
  27. RULE = always (RT imply not PAGEFAULT)
  28. To fix warnings reported by this monitor, `mlockall()` or `mlock()` can be used
  29. to ensure physical backing for memory.
  30. This monitor may have false negatives because the pages used by the real-time
  31. threads may just happen to be directly available during testing. To minimize
  32. this, the system can be put under memory pressure (e.g. invoking the OOM killer
  33. using a program that does `ptr = malloc(SIZE_OF_RAM); memset(ptr, 0,
  34. SIZE_OF_RAM);`) so that the kernel executes aggressive strategies to recycle as
  35. much physical memory as possible.
  36. Monitor sleep
  37. +++++++++++++
  38. The `sleep` monitor reports real-time threads sleeping in a manner that may
  39. cause undesirable latency. Real-time applications should only put a real-time
  40. thread to sleep for one of the following reasons:
  41. - Cyclic work: real-time thread sleeps waiting for the next cycle. For this
  42. case, only the `clock_nanosleep` syscall should be used with `TIMER_ABSTIME`
  43. (to avoid time drift) and `CLOCK_MONOTONIC` (to avoid the clock being
  44. changed). No other method is safe for real-time. For example, threads
  45. waiting for timerfd can be woken by softirq which provides no real-time
  46. guarantee.
  47. - Real-time thread waiting for something to happen (e.g. another thread
  48. releasing shared resources, or a completion signal from another thread). In
  49. this case, only futexes (FUTEX_LOCK_PI, FUTEX_LOCK_PI2 or one of
  50. FUTEX_WAIT_*) should be used. Applications usually do not use futexes
  51. directly, but use PI mutexes and PI condition variables which are built on
  52. top of futexes. Be aware that the C library might not implement conditional
  53. variables as safe for real-time. As an alternative, the librtpi library
  54. exists to provide a conditional variable implementation that is correct for
  55. real-time applications in Linux.
  56. Beside the reason for sleeping, the eventual waker should also be
  57. real-time-safe. Namely, one of:
  58. - An equal-or-higher-priority thread
  59. - Hard interrupt handler
  60. - Non-maskable interrupt handler
  61. This monitor's warning usually means one of the following:
  62. - Real-time thread is blocked by a non-real-time thread (e.g. due to
  63. contention on a mutex without priority inheritance). This is priority
  64. inversion.
  65. - Time-critical work waits for something which is not safe for real-time (e.g.
  66. timerfd).
  67. - The work executed by the real-time thread does not need to run at real-time
  68. priority at all. This is not a problem for the real-time thread itself, but
  69. it is potentially taking the CPU away from other important real-time work.
  70. Application developers may purposely choose to have their real-time application
  71. sleep in a way that is not safe for real-time. It is debatable whether that is a
  72. problem. Application developers must analyze the warnings to make a proper
  73. assessment.
  74. The monitor's specification is::
  75. RULE = always ((RT and SLEEP) imply (RT_FRIENDLY_SLEEP or ALLOWLIST))
  76. RT_FRIENDLY_SLEEP = (RT_VALID_SLEEP_REASON or KERNEL_THREAD)
  77. and ((not WAKE) until RT_FRIENDLY_WAKE)
  78. RT_VALID_SLEEP_REASON = FUTEX_WAIT
  79. or RT_FRIENDLY_NANOSLEEP
  80. RT_FRIENDLY_NANOSLEEP = CLOCK_NANOSLEEP
  81. and NANOSLEEP_TIMER_ABSTIME
  82. and NANOSLEEP_CLOCK_MONOTONIC
  83. RT_FRIENDLY_WAKE = WOKEN_BY_EQUAL_OR_HIGHER_PRIO
  84. or WOKEN_BY_HARDIRQ
  85. or WOKEN_BY_NMI
  86. or KTHREAD_SHOULD_STOP
  87. ALLOWLIST = BLOCK_ON_RT_MUTEX
  88. or FUTEX_LOCK_PI
  89. or TASK_IS_RCU
  90. or TASK_IS_MIGRATION
  91. Beside the scenarios described above, this specification also handle some
  92. special cases:
  93. - `KERNEL_THREAD`: kernel tasks do not have any pattern that can be recognized
  94. as valid real-time sleeping reasons. Therefore sleeping reason is not
  95. checked for kernel tasks.
  96. - `KTHREAD_SHOULD_STOP`: a non-real-time thread may stop a real-time kernel
  97. thread by waking it and waiting for it to exit (`kthread_stop()`). This
  98. wakeup is safe for real-time.
  99. - `ALLOWLIST`: to handle known false positives with the kernel.
  100. - `BLOCK_ON_RT_MUTEX` is included in the allowlist due to its implementation.
  101. In the release path of rt_mutex, a boosted task is de-boosted before waking
  102. the rt_mutex's waiter. Consequently, the monitor may see a real-time-unsafe
  103. wakeup (e.g. non-real-time task waking real-time task). This is actually
  104. real-time-safe because preemption is disabled for the duration.
  105. - `FUTEX_LOCK_PI` is included in the allowlist for the same reason as
  106. `BLOCK_ON_RT_MUTEX`.