freezer.h 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /* Freezer declarations */
  3. #ifndef FREEZER_H_INCLUDED
  4. #define FREEZER_H_INCLUDED
  5. #include <linux/debug_locks.h>
  6. #include <linux/sched.h>
  7. #include <linux/wait.h>
  8. #include <linux/atomic.h>
  9. #ifdef CONFIG_FREEZER
  10. extern atomic_t system_freezing_cnt; /* nr of freezing conds in effect */
  11. extern bool pm_freezing; /* PM freezing in effect */
  12. extern bool pm_nosig_freezing; /* PM nosig freezing in effect */
  13. /*
  14. * Timeout for stopping processes
  15. */
  16. extern unsigned int freeze_timeout_msecs;
  17. /*
  18. * Check if a process has been frozen
  19. */
  20. static inline bool frozen(struct task_struct *p)
  21. {
  22. return p->flags & PF_FROZEN;
  23. }
  24. static inline bool frozen_or_skipped(struct task_struct *p)
  25. {
  26. return p->flags & (PF_FROZEN | PF_FREEZER_SKIP);
  27. }
  28. extern bool freezing_slow_path(struct task_struct *p);
  29. /*
  30. * Check if there is a request to freeze a process
  31. */
  32. static inline bool freezing(struct task_struct *p)
  33. {
  34. if (likely(!atomic_read(&system_freezing_cnt)))
  35. return false;
  36. return freezing_slow_path(p);
  37. }
  38. /* Takes and releases task alloc lock using task_lock() */
  39. extern void __thaw_task(struct task_struct *t);
  40. extern bool __refrigerator(bool check_kthr_stop);
  41. extern int freeze_processes(void);
  42. extern int freeze_kernel_threads(void);
  43. extern void thaw_processes(void);
  44. extern void thaw_kernel_threads(void);
  45. /*
  46. * DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION
  47. * If try_to_freeze causes a lockdep warning it means the caller may deadlock
  48. */
  49. static inline bool try_to_freeze_unsafe(void)
  50. {
  51. might_sleep();
  52. if (likely(!freezing(current)))
  53. return false;
  54. return __refrigerator(false);
  55. }
  56. static inline bool try_to_freeze(void)
  57. {
  58. if (!(current->flags & PF_NOFREEZE))
  59. debug_check_no_locks_held();
  60. return try_to_freeze_unsafe();
  61. }
  62. extern bool freeze_task(struct task_struct *p);
  63. extern bool set_freezable(void);
  64. #ifdef CONFIG_CGROUP_FREEZER
  65. extern bool cgroup_freezing(struct task_struct *task);
  66. #else /* !CONFIG_CGROUP_FREEZER */
  67. static inline bool cgroup_freezing(struct task_struct *task)
  68. {
  69. return false;
  70. }
  71. #endif /* !CONFIG_CGROUP_FREEZER */
  72. /*
  73. * The PF_FREEZER_SKIP flag should be set by a vfork parent right before it
  74. * calls wait_for_completion(&vfork) and reset right after it returns from this
  75. * function. Next, the parent should call try_to_freeze() to freeze itself
  76. * appropriately in case the child has exited before the freezing of tasks is
  77. * complete. However, we don't want kernel threads to be frozen in unexpected
  78. * places, so we allow them to block freeze_processes() instead or to set
  79. * PF_NOFREEZE if needed. Fortunately, in the ____call_usermodehelper() case the
  80. * parent won't really block freeze_processes(), since ____call_usermodehelper()
  81. * (the child) does a little before exec/exit and it can't be frozen before
  82. * waking up the parent.
  83. */
  84. /**
  85. * freezer_do_not_count - tell freezer to ignore %current
  86. *
  87. * Tell freezers to ignore the current task when determining whether the
  88. * target frozen state is reached. IOW, the current task will be
  89. * considered frozen enough by freezers.
  90. *
  91. * The caller shouldn't do anything which isn't allowed for a frozen task
  92. * until freezer_cont() is called. Usually, freezer[_do_not]_count() pair
  93. * wrap a scheduling operation and nothing much else.
  94. */
  95. static inline void freezer_do_not_count(void)
  96. {
  97. current->flags |= PF_FREEZER_SKIP;
  98. }
  99. /**
  100. * freezer_count - tell freezer to stop ignoring %current
  101. *
  102. * Undo freezer_do_not_count(). It tells freezers that %current should be
  103. * considered again and tries to freeze if freezing condition is already in
  104. * effect.
  105. */
  106. static inline void freezer_count(void)
  107. {
  108. current->flags &= ~PF_FREEZER_SKIP;
  109. /*
  110. * If freezing is in progress, the following paired with smp_mb()
  111. * in freezer_should_skip() ensures that either we see %true
  112. * freezing() or freezer_should_skip() sees !PF_FREEZER_SKIP.
  113. */
  114. smp_mb();
  115. try_to_freeze();
  116. }
  117. /* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */
  118. static inline void freezer_count_unsafe(void)
  119. {
  120. current->flags &= ~PF_FREEZER_SKIP;
  121. smp_mb();
  122. try_to_freeze_unsafe();
  123. }
  124. /**
  125. * freezer_should_skip - whether to skip a task when determining frozen
  126. * state is reached
  127. * @p: task in quesion
  128. *
  129. * This function is used by freezers after establishing %true freezing() to
  130. * test whether a task should be skipped when determining the target frozen
  131. * state is reached. IOW, if this function returns %true, @p is considered
  132. * frozen enough.
  133. */
  134. static inline bool freezer_should_skip(struct task_struct *p)
  135. {
  136. /*
  137. * The following smp_mb() paired with the one in freezer_count()
  138. * ensures that either freezer_count() sees %true freezing() or we
  139. * see cleared %PF_FREEZER_SKIP and return %false. This makes it
  140. * impossible for a task to slip frozen state testing after
  141. * clearing %PF_FREEZER_SKIP.
  142. */
  143. smp_mb();
  144. return p->flags & PF_FREEZER_SKIP;
  145. }
  146. /*
  147. * These functions are intended to be used whenever you want allow a sleeping
  148. * task to be frozen. Note that neither return any clear indication of
  149. * whether a freeze event happened while in this function.
  150. */
  151. /* Like schedule(), but should not block the freezer. */
  152. static inline void freezable_schedule(void)
  153. {
  154. freezer_do_not_count();
  155. schedule();
  156. freezer_count();
  157. }
  158. /* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */
  159. static inline void freezable_schedule_unsafe(void)
  160. {
  161. freezer_do_not_count();
  162. schedule();
  163. freezer_count_unsafe();
  164. }
  165. /*
  166. * Like schedule_timeout(), but should not block the freezer. Do not
  167. * call this with locks held.
  168. */
  169. static inline long freezable_schedule_timeout(long timeout)
  170. {
  171. long __retval;
  172. freezer_do_not_count();
  173. __retval = schedule_timeout(timeout);
  174. freezer_count();
  175. return __retval;
  176. }
  177. /*
  178. * Like schedule_timeout_interruptible(), but should not block the freezer. Do not
  179. * call this with locks held.
  180. */
  181. static inline long freezable_schedule_timeout_interruptible(long timeout)
  182. {
  183. long __retval;
  184. freezer_do_not_count();
  185. __retval = schedule_timeout_interruptible(timeout);
  186. freezer_count();
  187. return __retval;
  188. }
  189. /* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */
  190. static inline long freezable_schedule_timeout_interruptible_unsafe(long timeout)
  191. {
  192. long __retval;
  193. freezer_do_not_count();
  194. __retval = schedule_timeout_interruptible(timeout);
  195. freezer_count_unsafe();
  196. return __retval;
  197. }
  198. /* Like schedule_timeout_killable(), but should not block the freezer. */
  199. static inline long freezable_schedule_timeout_killable(long timeout)
  200. {
  201. long __retval;
  202. freezer_do_not_count();
  203. __retval = schedule_timeout_killable(timeout);
  204. freezer_count();
  205. return __retval;
  206. }
  207. /* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */
  208. static inline long freezable_schedule_timeout_killable_unsafe(long timeout)
  209. {
  210. long __retval;
  211. freezer_do_not_count();
  212. __retval = schedule_timeout_killable(timeout);
  213. freezer_count_unsafe();
  214. return __retval;
  215. }
  216. /*
  217. * Like schedule_hrtimeout_range(), but should not block the freezer. Do not
  218. * call this with locks held.
  219. */
  220. static inline int freezable_schedule_hrtimeout_range(ktime_t *expires,
  221. u64 delta, const enum hrtimer_mode mode)
  222. {
  223. int __retval;
  224. freezer_do_not_count();
  225. __retval = schedule_hrtimeout_range(expires, delta, mode);
  226. freezer_count();
  227. return __retval;
  228. }
  229. /*
  230. * Freezer-friendly wrappers around wait_event_interruptible(),
  231. * wait_event_killable() and wait_event_interruptible_timeout(), originally
  232. * defined in <linux/wait.h>
  233. */
  234. /* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */
  235. #define wait_event_freezekillable_unsafe(wq, condition) \
  236. ({ \
  237. int __retval; \
  238. freezer_do_not_count(); \
  239. __retval = wait_event_killable(wq, (condition)); \
  240. freezer_count_unsafe(); \
  241. __retval; \
  242. })
  243. #else /* !CONFIG_FREEZER */
  244. static inline bool frozen(struct task_struct *p) { return false; }
  245. static inline bool frozen_or_skipped(struct task_struct *p) { return false; }
  246. static inline bool freezing(struct task_struct *p) { return false; }
  247. static inline void __thaw_task(struct task_struct *t) {}
  248. static inline bool __refrigerator(bool check_kthr_stop) { return false; }
  249. static inline int freeze_processes(void) { return -ENOSYS; }
  250. static inline int freeze_kernel_threads(void) { return -ENOSYS; }
  251. static inline void thaw_processes(void) {}
  252. static inline void thaw_kernel_threads(void) {}
  253. static inline bool try_to_freeze_nowarn(void) { return false; }
  254. static inline bool try_to_freeze(void) { return false; }
  255. static inline void freezer_do_not_count(void) {}
  256. static inline void freezer_count(void) {}
  257. static inline int freezer_should_skip(struct task_struct *p) { return 0; }
  258. static inline void set_freezable(void) {}
  259. #define freezable_schedule() schedule()
  260. #define freezable_schedule_unsafe() schedule()
  261. #define freezable_schedule_timeout(timeout) schedule_timeout(timeout)
  262. #define freezable_schedule_timeout_interruptible(timeout) \
  263. schedule_timeout_interruptible(timeout)
  264. #define freezable_schedule_timeout_interruptible_unsafe(timeout) \
  265. schedule_timeout_interruptible(timeout)
  266. #define freezable_schedule_timeout_killable(timeout) \
  267. schedule_timeout_killable(timeout)
  268. #define freezable_schedule_timeout_killable_unsafe(timeout) \
  269. schedule_timeout_killable(timeout)
  270. #define freezable_schedule_hrtimeout_range(expires, delta, mode) \
  271. schedule_hrtimeout_range(expires, delta, mode)
  272. #define wait_event_freezekillable_unsafe(wq, condition) \
  273. wait_event_killable(wq, condition)
  274. #endif /* !CONFIG_FREEZER */
  275. #endif /* FREEZER_H_INCLUDED */