freezer.h 10 KB

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