freezer.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. * kernel/freezer.c - Function to freeze a process
  3. *
  4. * Originally from kernel/power/process.c
  5. */
  6. #include <linux/interrupt.h>
  7. #include <linux/suspend.h>
  8. #include <linux/export.h>
  9. #include <linux/syscalls.h>
  10. #include <linux/freezer.h>
  11. #include <linux/kthread.h>
  12. /* protects freezing and frozen transitions */
  13. static DEFINE_SPINLOCK(freezer_lock);
  14. /* Refrigerator is place where frozen processes are stored :-). */
  15. bool __refrigerator(bool check_kthr_stop)
  16. {
  17. /* Hmm, should we be allowed to suspend when there are realtime
  18. processes around? */
  19. bool was_frozen = false;
  20. long save;
  21. spin_lock_irq(&freezer_lock);
  22. if (!freezing(current)) {
  23. spin_unlock_irq(&freezer_lock);
  24. return was_frozen;
  25. }
  26. if (!(current->flags & PF_NOFREEZE))
  27. current->flags |= PF_FROZEN;
  28. clear_freeze_flag(current);
  29. spin_unlock_irq(&freezer_lock);
  30. save = current->state;
  31. pr_debug("%s entered refrigerator\n", current->comm);
  32. spin_lock_irq(&current->sighand->siglock);
  33. recalc_sigpending(); /* We sent fake signal, clean it up */
  34. spin_unlock_irq(&current->sighand->siglock);
  35. /* prevent accounting of that task to load */
  36. current->flags |= PF_FREEZING;
  37. for (;;) {
  38. set_current_state(TASK_UNINTERRUPTIBLE);
  39. if (!frozen(current) ||
  40. (check_kthr_stop && kthread_should_stop()))
  41. break;
  42. was_frozen = true;
  43. schedule();
  44. }
  45. /* Remove the accounting blocker */
  46. current->flags &= ~PF_FREEZING;
  47. pr_debug("%s left refrigerator\n", current->comm);
  48. /*
  49. * Restore saved task state before returning. The mb'd version
  50. * needs to be used; otherwise, it might silently break
  51. * synchronization which depends on ordered task state change.
  52. */
  53. set_current_state(save);
  54. return was_frozen;
  55. }
  56. EXPORT_SYMBOL(__refrigerator);
  57. static void fake_signal_wake_up(struct task_struct *p)
  58. {
  59. unsigned long flags;
  60. spin_lock_irqsave(&p->sighand->siglock, flags);
  61. signal_wake_up(p, 0);
  62. spin_unlock_irqrestore(&p->sighand->siglock, flags);
  63. }
  64. /**
  65. * freeze_task - send a freeze request to given task
  66. * @p: task to send the request to
  67. * @sig_only: if set, the request will only be sent if the task has the
  68. * PF_FREEZER_NOSIG flag unset
  69. * Return value: 'false', if @sig_only is set and the task has
  70. * PF_FREEZER_NOSIG set or the task is frozen, 'true', otherwise
  71. *
  72. * The freeze request is sent by setting the tasks's TIF_FREEZE flag and
  73. * either sending a fake signal to it or waking it up, depending on whether
  74. * or not it has PF_FREEZER_NOSIG set. If @sig_only is set and the task
  75. * has PF_FREEZER_NOSIG set (ie. it is a typical kernel thread), its
  76. * TIF_FREEZE flag will not be set.
  77. */
  78. bool freeze_task(struct task_struct *p, bool sig_only)
  79. {
  80. unsigned long flags;
  81. bool ret = false;
  82. spin_lock_irqsave(&freezer_lock, flags);
  83. if (sig_only && !should_send_signal(p))
  84. goto out_unlock;
  85. if (frozen(p))
  86. goto out_unlock;
  87. set_freeze_flag(p);
  88. if (should_send_signal(p)) {
  89. fake_signal_wake_up(p);
  90. /*
  91. * fake_signal_wake_up() goes through p's scheduler
  92. * lock and guarantees that TASK_STOPPED/TRACED ->
  93. * TASK_RUNNING transition can't race with task state
  94. * testing in try_to_freeze_tasks().
  95. */
  96. } else {
  97. wake_up_state(p, TASK_INTERRUPTIBLE);
  98. }
  99. ret = true;
  100. out_unlock:
  101. spin_unlock_irqrestore(&freezer_lock, flags);
  102. return ret;
  103. }
  104. void cancel_freezing(struct task_struct *p)
  105. {
  106. unsigned long flags;
  107. spin_lock_irqsave(&freezer_lock, flags);
  108. if (freezing(p)) {
  109. pr_debug(" clean up: %s\n", p->comm);
  110. clear_freeze_flag(p);
  111. spin_lock(&p->sighand->siglock);
  112. recalc_sigpending_and_wake(p);
  113. spin_unlock(&p->sighand->siglock);
  114. }
  115. spin_unlock_irqrestore(&freezer_lock, flags);
  116. }
  117. /*
  118. * Wake up a frozen task
  119. *
  120. * task_lock() is needed to prevent the race with refrigerator() which may
  121. * occur if the freezing of tasks fails. Namely, without the lock, if the
  122. * freezing of tasks failed, thaw_tasks() might have run before a task in
  123. * refrigerator() could call frozen_process(), in which case the task would be
  124. * frozen and no one would thaw it.
  125. */
  126. void __thaw_task(struct task_struct *p)
  127. {
  128. unsigned long flags;
  129. spin_lock_irqsave(&freezer_lock, flags);
  130. if (frozen(p)) {
  131. p->flags &= ~PF_FROZEN;
  132. wake_up_process(p);
  133. } else {
  134. clear_freeze_flag(p);
  135. }
  136. spin_unlock_irqrestore(&freezer_lock, flags);
  137. }