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_freezing_or_frozen(struct task_struct *task);
  68#else /* !CONFIG_CGROUP_FREEZER */
  69static inline int cgroup_freezing_or_frozen(struct task_struct *task)
  70{
  71        return 0;
  72}
  73#endif /* !CONFIG_CGROUP_FREEZER */
  74
  75/*
  76 * The PF_FREEZER_SKIP flag should be set by a vfork parent right before it
  77 * calls wait_for_completion(&vfork) and reset right after it returns from this
  78 * function.  Next, the parent should call try_to_freeze() to freeze itself
  79 * appropriately in case the child has exited before the freezing of tasks is
  80 * complete.  However, we don't want kernel threads to be frozen in unexpected
  81 * places, so we allow them to block freeze_processes() instead or to set
  82 * PF_NOFREEZE if needed and PF_FREEZER_SKIP is only set for userland vfork
  83 * parents.  Fortunately, in the ____call_usermodehelper() case the parent won't
  84 * really block freeze_processes(), since ____call_usermodehelper() (the child)
  85 * does a little before exec/exit and it can't be frozen before waking up the
  86 * parent.
  87 */
  88
  89/*
  90 * If the current task is a user space one, tell the freezer not to count it as
  91 * freezable.
  92 */
  93static inline void freezer_do_not_count(void)
  94{
  95        if (current->mm)
  96                current->flags |= PF_FREEZER_SKIP;
  97}
  98
  99/*
 100 * If the current task is a user space one, tell the freezer to count it as
 101 * freezable again and try to freeze it.
 102 */
 103static inline void freezer_count(void)
 104{
 105        if (current->mm) {
 106                current->flags &= ~PF_FREEZER_SKIP;
 107                try_to_freeze();
 108        }
 109}
 110
 111/*
 112 * Check if the task should be counted as freezable by the freezer
 113 */
 114static inline int freezer_should_skip(struct task_struct *p)
 115{
 116        return !!(p->flags & PF_FREEZER_SKIP);
 117}
 118
 119/*
 120 * Tell the freezer that the current task should be frozen by it
 121 */
 122static inline void set_freezable(void)
 123{
 124        current->flags &= ~PF_NOFREEZE;
 125}
 126
 127/*
 128 * Tell the freezer that the current task should be frozen by it and that it
 129 * should send a fake signal to the task to freeze it.
 130 */
 131static inline void set_freezable_with_signal(void)
 132{
 133        current->flags &= ~(PF_NOFREEZE | PF_FREEZER_NOSIG);
 134}
 135
 136/*
 137 * Freezer-friendly wrappers around wait_event_interruptible() and
 138 * wait_event_interruptible_timeout(), originally defined in <linux/wait.h>
 139 */
 140
 141#define wait_event_freezable(wq, condition)                             \
 142({                                                                      \
 143        int __retval;                                                   \
 144        do {                                                            \
 145                __retval = wait_event_interruptible(wq,                 \
 146                                (condition) || freezing(current));      \
 147                if (__retval && !freezing(current))                     \
 148                        break;                                          \
 149                else if (!(condition))                                  \
 150                        __retval = -ERESTARTSYS;                        \
 151        } while (try_to_freeze());                                      \
 152        __retval;                                                       \
 153})
 154
 155
 156#define wait_event_freezable_timeout(wq, condition, timeout)            \
 157({                                                                      \
 158        long __retval = timeout;                                        \
 159        do {                                                            \
 160                __retval = wait_event_interruptible_timeout(wq,         \
 161                                (condition) || freezing(current),       \
 162                                __retval);                              \
 163        } while (try_to_freeze());                                      \
 164        __retval;                                                       \
 165})
 166#else /* !CONFIG_FREEZER */
 167static inline int frozen(struct task_struct *p) { return 0; }
 168static inline int freezing(struct task_struct *p) { return 0; }
 169static inline void set_freeze_flag(struct task_struct *p) {}
 170static inline void clear_freeze_flag(struct task_struct *p) {}
 171static inline int thaw_process(struct task_struct *p) { return 1; }
 172
 173static inline void refrigerator(void) {}
 174static inline int freeze_processes(void) { BUG(); return 0; }
 175static inline void thaw_processes(void) {}
 176
 177static inline int try_to_freeze(void) { return 0; }
 178
 179static inline void freezer_do_not_count(void) {}
 180static inline void freezer_count(void) {}
 181static inline int freezer_should_skip(struct task_struct *p) { return 0; }
 182static inline void set_freezable(void) {}
 183static inline void set_freezable_with_signal(void) {}
 184
 185#define wait_event_freezable(wq, condition)                             \
 186                wait_event_interruptible(wq, condition)
 187
 188#define wait_event_freezable_timeout(wq, condition, timeout)            \
 189                wait_event_interruptible_timeout(wq, condition, timeout)
 190
 191#endif /* !CONFIG_FREEZER */
 192
 193#endif  /* FREEZER_H_INCLUDED */
 194