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#include <linux/atomic.h>
   9
  10#ifdef CONFIG_FREEZER
  11extern atomic_t system_freezing_cnt;    /* nr of freezing conds in effect */
  12extern bool pm_freezing;                /* PM freezing in effect */
  13extern bool pm_nosig_freezing;          /* PM nosig freezing in effect */
  14
  15/*
  16 * Timeout for stopping processes
  17 */
  18extern unsigned int freeze_timeout_msecs;
  19
  20/*
  21 * Check if a process has been frozen
  22 */
  23static inline bool frozen(struct task_struct *p)
  24{
  25        return p->flags & PF_FROZEN;
  26}
  27
  28extern bool freezing_slow_path(struct task_struct *p);
  29
  30/*
  31 * Check if there is a request to freeze a process
  32 */
  33static inline bool freezing(struct task_struct *p)
  34{
  35        if (likely(!atomic_read(&system_freezing_cnt)))
  36                return false;
  37        return freezing_slow_path(p);
  38}
  39
  40/* Takes and releases task alloc lock using task_lock() */
  41extern void __thaw_task(struct task_struct *t);
  42
  43extern bool __refrigerator(bool check_kthr_stop);
  44extern int freeze_processes(void);
  45extern int freeze_kernel_threads(void);
  46extern void thaw_processes(void);
  47extern void thaw_kernel_threads(void);
  48
  49static inline bool try_to_freeze(void)
  50{
  51        might_sleep();
  52        if (likely(!freezing(current)))
  53                return false;
  54        return __refrigerator(false);
  55}
  56
  57extern bool freeze_task(struct task_struct *p);
  58extern bool set_freezable(void);
  59
  60#ifdef CONFIG_CGROUP_FREEZER
  61extern bool cgroup_freezing(struct task_struct *task);
  62#else /* !CONFIG_CGROUP_FREEZER */
  63static inline bool cgroup_freezing(struct task_struct *task)
  64{
  65        return false;
  66}
  67#endif /* !CONFIG_CGROUP_FREEZER */
  68
  69/*
  70 * The PF_FREEZER_SKIP flag should be set by a vfork parent right before it
  71 * calls wait_for_completion(&vfork) and reset right after it returns from this
  72 * function.  Next, the parent should call try_to_freeze() to freeze itself
  73 * appropriately in case the child has exited before the freezing of tasks is
  74 * complete.  However, we don't want kernel threads to be frozen in unexpected
  75 * places, so we allow them to block freeze_processes() instead or to set
  76 * PF_NOFREEZE if needed. Fortunately, in the ____call_usermodehelper() case the
  77 * parent won't really block freeze_processes(), since ____call_usermodehelper()
  78 * (the child) does a little before exec/exit and it can't be frozen before
  79 * waking up the parent.
  80 */
  81
  82
  83/**
  84 * freezer_do_not_count - tell freezer to ignore %current
  85 *
  86 * Tell freezers to ignore the current task when determining whether the
  87 * target frozen state is reached.  IOW, the current task will be
  88 * considered frozen enough by freezers.
  89 *
  90 * The caller shouldn't do anything which isn't allowed for a frozen task
  91 * until freezer_cont() is called.  Usually, freezer[_do_not]_count() pair
  92 * wrap a scheduling operation and nothing much else.
  93 */
  94static inline void freezer_do_not_count(void)
  95{
  96        current->flags |= PF_FREEZER_SKIP;
  97}
  98
  99/**
 100 * freezer_count - tell freezer to stop ignoring %current
 101 *
 102 * Undo freezer_do_not_count().  It tells freezers that %current should be
 103 * considered again and tries to freeze if freezing condition is already in
 104 * effect.
 105 */
 106static inline void freezer_count(void)
 107{
 108        current->flags &= ~PF_FREEZER_SKIP;
 109        /*
 110         * If freezing is in progress, the following paired with smp_mb()
 111         * in freezer_should_skip() ensures that either we see %true
 112         * freezing() or freezer_should_skip() sees !PF_FREEZER_SKIP.
 113         */
 114        smp_mb();
 115        try_to_freeze();
 116}
 117
 118/**
 119 * freezer_should_skip - whether to skip a task when determining frozen
 120 *                       state is reached
 121 * @p: task in quesion
 122 *
 123 * This function is used by freezers after establishing %true freezing() to
 124 * test whether a task should be skipped when determining the target frozen
 125 * state is reached.  IOW, if this function returns %true, @p is considered
 126 * frozen enough.
 127 */
 128static inline bool freezer_should_skip(struct task_struct *p)
 129{
 130        /*
 131         * The following smp_mb() paired with the one in freezer_count()
 132         * ensures that either freezer_count() sees %true freezing() or we
 133         * see cleared %PF_FREEZER_SKIP and return %false.  This makes it
 134         * impossible for a task to slip frozen state testing after
 135         * clearing %PF_FREEZER_SKIP.
 136         */
 137        smp_mb();
 138        return p->flags & PF_FREEZER_SKIP;
 139}
 140
 141/*
 142 * These macros are intended to be used whenever you want allow a sleeping
 143 * task to be frozen. Note that neither return any clear indication of
 144 * whether a freeze event happened while in this function.
 145 */
 146
 147/* Like schedule(), but should not block the freezer. */
 148#define freezable_schedule()                                            \
 149({                                                                      \
 150        freezer_do_not_count();                                         \
 151        schedule();                                                     \
 152        freezer_count();                                                \
 153})
 154
 155/* Like schedule_timeout_killable(), but should not block the freezer. */
 156#define freezable_schedule_timeout_killable(timeout)                    \
 157({                                                                      \
 158        long __retval;                                                  \
 159        freezer_do_not_count();                                         \
 160        __retval = schedule_timeout_killable(timeout);                  \
 161        freezer_count();                                                \
 162        __retval;                                                       \
 163})
 164
 165/*
 166 * Freezer-friendly wrappers around wait_event_interruptible(),
 167 * wait_event_killable() and wait_event_interruptible_timeout(), originally
 168 * defined in <linux/wait.h>
 169 */
 170
 171#define wait_event_freezekillable(wq, condition)                        \
 172({                                                                      \
 173        int __retval;                                                   \
 174        freezer_do_not_count();                                         \
 175        __retval = wait_event_killable(wq, (condition));                \
 176        freezer_count();                                                \
 177        __retval;                                                       \
 178})
 179
 180#define wait_event_freezable(wq, condition)                             \
 181({                                                                      \
 182        int __retval;                                                   \
 183        for (;;) {                                                      \
 184                __retval = wait_event_interruptible(wq,                 \
 185                                (condition) || freezing(current));      \
 186                if (__retval || (condition))                            \
 187                        break;                                          \
 188                try_to_freeze();                                        \
 189        }                                                               \
 190        __retval;                                                       \
 191})
 192
 193#define wait_event_freezable_timeout(wq, condition, timeout)            \
 194({                                                                      \
 195        long __retval = timeout;                                        \
 196        for (;;) {                                                      \
 197                __retval = wait_event_interruptible_timeout(wq,         \
 198                                (condition) || freezing(current),       \
 199                                __retval);                              \
 200                if (__retval <= 0 || (condition))                       \
 201                        break;                                          \
 202                try_to_freeze();                                        \
 203        }                                                               \
 204        __retval;                                                       \
 205})
 206
 207#else /* !CONFIG_FREEZER */
 208static inline bool frozen(struct task_struct *p) { return false; }
 209static inline bool freezing(struct task_struct *p) { return false; }
 210static inline void __thaw_task(struct task_struct *t) {}
 211
 212static inline bool __refrigerator(bool check_kthr_stop) { return false; }
 213static inline int freeze_processes(void) { return -ENOSYS; }
 214static inline int freeze_kernel_threads(void) { return -ENOSYS; }
 215static inline void thaw_processes(void) {}
 216static inline void thaw_kernel_threads(void) {}
 217
 218static inline bool try_to_freeze_nowarn(void) { return false; }
 219static inline bool try_to_freeze(void) { return false; }
 220
 221static inline void freezer_do_not_count(void) {}
 222static inline void freezer_count(void) {}
 223static inline int freezer_should_skip(struct task_struct *p) { return 0; }
 224static inline void set_freezable(void) {}
 225
 226#define freezable_schedule()  schedule()
 227
 228#define freezable_schedule_timeout_killable(timeout)                    \
 229        schedule_timeout_killable(timeout)
 230
 231#define wait_event_freezable(wq, condition)                             \
 232                wait_event_interruptible(wq, condition)
 233
 234#define wait_event_freezable_timeout(wq, condition, timeout)            \
 235                wait_event_interruptible_timeout(wq, condition, timeout)
 236
 237#define wait_event_freezekillable(wq, condition)                \
 238                wait_event_killable(wq, condition)
 239
 240#endif /* !CONFIG_FREEZER */
 241
 242#endif  /* FREEZER_H_INCLUDED */
 243
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.