linux/include/linux/freezer.h
<<
>>
Prefs
   1/* Freezer declarations */
   2
   3#ifndef FREEZER_H_INCLUDED
   4#define FREEZER_H_INCLUDED
   5
   6#include <linux/sched.h>
   7#include <linux/wait.h>
   8
   9#ifdef CONFIG_FREEZER
  10/*
  11 * Check if a process has been frozen
  12 */
  13static inline int frozen(struct task_struct *p)
  14{
  15        return p->flags & PF_FROZEN;
  16}
  17
  18/*
  19 * Check if there is a request to freeze a process
  20 */
  21static inline int freezing(struct task_struct *p)
  22{
  23        return test_tsk_thread_flag(p, TIF_FREEZE);
  24}
  25
  26/*
  27 * Request that a process be frozen
  28 */
  29static inline void set_freeze_flag(struct task_struct *p)
  30{
  31        set_tsk_thread_flag(p, TIF_FREEZE);
  32}
  33
  34/*
  35 * Sometimes we may need to cancel the previous 'freeze' request
  36 */
  37static inline void clear_freeze_flag(struct task_struct *p)
  38{
  39        clear_tsk_thread_flag(p, TIF_FREEZE);
  40}
  41
  42static inline bool should_send_signal(struct task_struct *p)
  43{
  44        return !(p->flags & PF_FREEZER_NOSIG);
  45}
  46
  47/* Takes and releases task alloc lock using task_lock() */
  48extern int thaw_process(struct task_struct *p);
  49
  50extern void refrigerator(void);
  51extern int freeze_processes(void);
  52extern void thaw_processes(void);
  53
  54static inline int try_to_freeze(void)
  55{
  56        if (freezing(current)) {
  57                refrigerator();
  58                return 1;
  59        } else
  60                return 0;
  61}
  62
  63extern bool freeze_task(struct task_struct *p, bool sig_only);
  64extern void cancel_freezing(struct task_struct *p);
  65
  66#ifdef CONFIG_CGROUP_FREEZER
  67extern int cgroup_frozen(struct task_struct *task);
  68#else /* !CONFIG_CGROUP_FREEZER */
  69static inline int cgroup_frozen(struct task_struct *task) { return 0; }
  70#endif /* !CONFIG_CGROUP_FREEZER */
  71
  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 and PF_FREEZER_SKIP is only set for userland vfork
  80 * parents.  Fortunately, in the ____call_usermodehelper() case the parent won't
  81 * really block freeze_processes(), since ____call_usermodehelper() (the child)
  82 * does a little before exec/exit and it can't be frozen before waking up the
  83 * parent.
  84 */
  85
  86/*
  87 * If the current task is a user space one, tell the freezer not to count it as
  88 * freezable.
  89 */
  90static inline void freezer_do_not_count(void)
  91{
  92        if (current->mm)
  93                current->flags |= PF_FREEZER_SKIP;
  94}
  95
  96/*
  97 * If the current task is a user space one, tell the freezer to count it as
  98 * freezable again and try to freeze it.
  99 */
 100static inline void freezer_count(void)
 101{
 102        if (current->mm) {
 103                current->flags &= ~PF_FREEZER_SKIP;
 104                try_to_freeze();
 105        }
 106}
 107
 108/*
 109 * Check if the task should be counted as freezeable by the freezer
 110 */
 111static inline int freezer_should_skip(struct task_struct *p)
 112{
 113        return !!(p->flags & PF_FREEZER_SKIP);
 114}
 115
 116/*
 117 * Tell the freezer that the current task should be frozen by it
 118 */
 119static inline void set_freezable(void)
 120{
 121        current->flags &= ~PF_NOFREEZE;
 122}
 123
 124/*
 125 * Tell the freezer that the current task should be frozen by it and that it
 126 * should send a fake signal to the task to freeze it.
 127 */
 128static inline void set_freezable_with_signal(void)
 129{
 130        current->flags &= ~(PF_NOFREEZE | PF_FREEZER_NOSIG);
 131}
 132
 133/*
 134 * Freezer-friendly wrappers around wait_event_interruptible() and
 135 * wait_event_interruptible_timeout(), originally defined in <linux/wait.h>
 136 */
 137
 138#define wait_event_freezable(wq, condition)                             \
 139({                                                                      \
 140        int __retval;                                                   \
 141        do {                                                            \
 142                __retval = wait_event_interruptible(wq,                 \
 143                                (condition) || freezing(current));      \
 144                if (__retval && !freezing(current))                     \
 145                        break;                                          \
 146                else if (!(condition))                                  \
 147                        __retval = -ERESTARTSYS;                        \
 148        } while (try_to_freeze());                                      \
 149        __retval;                                                       \
 150})
 151
 152
 153#define wait_event_freezable_timeout(wq, condition, timeout)            \
 154({                                                                      \
 155        long __retval = timeout;                                        \
 156        do {                                                            \
 157                __retval = wait_event_interruptible_timeout(wq,         \
 158                                (condition) || freezing(current),       \
 159                                __retval);                              \
 160        } while (try_to_freeze());                                      \
 161        __retval;                                                       \
 162})
 163#else /* !CONFIG_FREEZER */
 164static inline int frozen(struct task_struct *p) { return 0; }
 165static inline int freezing(struct task_struct *p) { return 0; }
 166static inline void set_freeze_flag(struct task_struct *p) {}
 167static inline void clear_freeze_flag(struct task_struct *p) {}
 168static inline int thaw_process(struct task_struct *p) { return 1; }
 169
 170static inline void refrigerator(void) {}
 171static inline int freeze_processes(void) { BUG(); return 0; }
 172static inline void thaw_processes(void) {}
 173
 174static inline int try_to_freeze(void) { return 0; }
 175
 176static inline void freezer_do_not_count(void) {}
 177static inline void freezer_count(void) {}
 178static inline int freezer_should_skip(struct task_struct *p) { return 0; }
 179static inline void set_freezable(void) {}
 180static inline void set_freezable_with_signal(void) {}
 181
 182#define wait_event_freezable(wq, condition)                             \
 183                wait_event_interruptible(wq, condition)
 184
 185#define wait_event_freezable_timeout(wq, condition, timeout)            \
 186                wait_event_interruptible_timeout(wq, condition, timeout)
 187
 188#endif /* !CONFIG_FREEZER */
 189
 190#endif  /* FREEZER_H_INCLUDED */
 191