freezer.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /* Freezer declarations */
  2. #include <linux/sched.h>
  3. #ifdef CONFIG_PM
  4. /*
  5. * Check if a process has been frozen
  6. */
  7. static inline int frozen(struct task_struct *p)
  8. {
  9. return p->flags & PF_FROZEN;
  10. }
  11. /*
  12. * Check if there is a request to freeze a process
  13. */
  14. static inline int freezing(struct task_struct *p)
  15. {
  16. return test_tsk_thread_flag(p, TIF_FREEZE);
  17. }
  18. /*
  19. * Request that a process be frozen
  20. */
  21. static inline void freeze(struct task_struct *p)
  22. {
  23. set_tsk_thread_flag(p, TIF_FREEZE);
  24. }
  25. /*
  26. * Sometimes we may need to cancel the previous 'freeze' request
  27. */
  28. static inline void do_not_freeze(struct task_struct *p)
  29. {
  30. clear_tsk_thread_flag(p, TIF_FREEZE);
  31. }
  32. /*
  33. * Wake up a frozen process
  34. *
  35. * task_lock() is taken to prevent the race with refrigerator() which may
  36. * occur if the freezing of tasks fails. Namely, without the lock, if the
  37. * freezing of tasks failed, thaw_tasks() might have run before a task in
  38. * refrigerator() could call frozen_process(), in which case the task would be
  39. * frozen and no one would thaw it.
  40. */
  41. static inline int thaw_process(struct task_struct *p)
  42. {
  43. task_lock(p);
  44. if (frozen(p)) {
  45. p->flags &= ~PF_FROZEN;
  46. task_unlock(p);
  47. wake_up_process(p);
  48. return 1;
  49. }
  50. clear_tsk_thread_flag(p, TIF_FREEZE);
  51. task_unlock(p);
  52. return 0;
  53. }
  54. /*
  55. * freezing is complete, mark process as frozen
  56. */
  57. static inline void frozen_process(struct task_struct *p)
  58. {
  59. if (!unlikely(p->flags & PF_NOFREEZE)) {
  60. p->flags |= PF_FROZEN;
  61. wmb();
  62. }
  63. clear_tsk_thread_flag(p, TIF_FREEZE);
  64. }
  65. extern void refrigerator(void);
  66. extern int freeze_processes(void);
  67. extern void thaw_processes(void);
  68. static inline int try_to_freeze(void)
  69. {
  70. if (freezing(current)) {
  71. refrigerator();
  72. return 1;
  73. } else
  74. return 0;
  75. }
  76. /*
  77. * The PF_FREEZER_SKIP flag should be set by a vfork parent right before it
  78. * calls wait_for_completion(&vfork) and reset right after it returns from this
  79. * function. Next, the parent should call try_to_freeze() to freeze itself
  80. * appropriately in case the child has exited before the freezing of tasks is
  81. * complete. However, we don't want kernel threads to be frozen in unexpected
  82. * places, so we allow them to block freeze_processes() instead or to set
  83. * PF_NOFREEZE if needed and PF_FREEZER_SKIP is only set for userland vfork
  84. * parents. Fortunately, in the ____call_usermodehelper() case the parent won't
  85. * really block freeze_processes(), since ____call_usermodehelper() (the child)
  86. * does a little before exec/exit and it can't be frozen before waking up the
  87. * parent.
  88. */
  89. /*
  90. * If the current task is a user space one, tell the freezer not to count it as
  91. * freezable.
  92. */
  93. static inline void freezer_do_not_count(void)
  94. {
  95. if (current->mm)
  96. current->flags |= PF_FREEZER_SKIP;
  97. }
  98. /*
  99. * If the current task is a user space one, tell the freezer to count it as
  100. * freezable again and try to freeze it.
  101. */
  102. static inline void freezer_count(void)
  103. {
  104. if (current->mm) {
  105. current->flags &= ~PF_FREEZER_SKIP;
  106. try_to_freeze();
  107. }
  108. }
  109. /*
  110. * Check if the task should be counted as freezeable by the freezer
  111. */
  112. static inline int freezer_should_skip(struct task_struct *p)
  113. {
  114. return !!(p->flags & PF_FREEZER_SKIP);
  115. }
  116. #else
  117. static inline int frozen(struct task_struct *p) { return 0; }
  118. static inline int freezing(struct task_struct *p) { return 0; }
  119. static inline void freeze(struct task_struct *p) { BUG(); }
  120. static inline int thaw_process(struct task_struct *p) { return 1; }
  121. static inline void frozen_process(struct task_struct *p) { BUG(); }
  122. static inline void refrigerator(void) {}
  123. static inline int freeze_processes(void) { BUG(); return 0; }
  124. static inline void thaw_processes(void) {}
  125. static inline int try_to_freeze(void) { return 0; }
  126. static inline void freezer_do_not_count(void) {}
  127. static inline void freezer_count(void) {}
  128. static inline int freezer_should_skip(struct task_struct *p) { return 0; }
  129. #endif