Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /* Freezer declarations */
0003 
0004 #ifndef FREEZER_H_INCLUDED
0005 #define FREEZER_H_INCLUDED
0006 
0007 #include <linux/debug_locks.h>
0008 #include <linux/sched.h>
0009 #include <linux/wait.h>
0010 #include <linux/atomic.h>
0011 
0012 #ifdef CONFIG_FREEZER
0013 extern atomic_t system_freezing_cnt;    /* nr of freezing conds in effect */
0014 extern bool pm_freezing;        /* PM freezing in effect */
0015 extern bool pm_nosig_freezing;      /* PM nosig freezing in effect */
0016 
0017 /*
0018  * Timeout for stopping processes
0019  */
0020 extern unsigned int freeze_timeout_msecs;
0021 
0022 /*
0023  * Check if a process has been frozen
0024  */
0025 static inline bool frozen(struct task_struct *p)
0026 {
0027     return p->flags & PF_FROZEN;
0028 }
0029 
0030 extern bool freezing_slow_path(struct task_struct *p);
0031 
0032 /*
0033  * Check if there is a request to freeze a process
0034  */
0035 static inline bool freezing(struct task_struct *p)
0036 {
0037     if (likely(!atomic_read(&system_freezing_cnt)))
0038         return false;
0039     return freezing_slow_path(p);
0040 }
0041 
0042 /* Takes and releases task alloc lock using task_lock() */
0043 extern void __thaw_task(struct task_struct *t);
0044 
0045 extern bool __refrigerator(bool check_kthr_stop);
0046 extern int freeze_processes(void);
0047 extern int freeze_kernel_threads(void);
0048 extern void thaw_processes(void);
0049 extern void thaw_kernel_threads(void);
0050 
0051 /*
0052  * DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION
0053  * If try_to_freeze causes a lockdep warning it means the caller may deadlock
0054  */
0055 static inline bool try_to_freeze_unsafe(void)
0056 {
0057     might_sleep();
0058     if (likely(!freezing(current)))
0059         return false;
0060     return __refrigerator(false);
0061 }
0062 
0063 static inline bool try_to_freeze(void)
0064 {
0065     if (!(current->flags & PF_NOFREEZE))
0066         debug_check_no_locks_held();
0067     return try_to_freeze_unsafe();
0068 }
0069 
0070 extern bool freeze_task(struct task_struct *p);
0071 extern bool set_freezable(void);
0072 
0073 #ifdef CONFIG_CGROUP_FREEZER
0074 extern bool cgroup_freezing(struct task_struct *task);
0075 #else /* !CONFIG_CGROUP_FREEZER */
0076 static inline bool cgroup_freezing(struct task_struct *task)
0077 {
0078     return false;
0079 }
0080 #endif /* !CONFIG_CGROUP_FREEZER */
0081 
0082 /*
0083  * The PF_FREEZER_SKIP flag should be set by a vfork parent right before it
0084  * calls wait_for_completion(&vfork) and reset right after it returns from this
0085  * function.  Next, the parent should call try_to_freeze() to freeze itself
0086  * appropriately in case the child has exited before the freezing of tasks is
0087  * complete.  However, we don't want kernel threads to be frozen in unexpected
0088  * places, so we allow them to block freeze_processes() instead or to set
0089  * PF_NOFREEZE if needed. Fortunately, in the ____call_usermodehelper() case the
0090  * parent won't really block freeze_processes(), since ____call_usermodehelper()
0091  * (the child) does a little before exec/exit and it can't be frozen before
0092  * waking up the parent.
0093  */
0094 
0095 
0096 /**
0097  * freezer_do_not_count - tell freezer to ignore %current
0098  *
0099  * Tell freezers to ignore the current task when determining whether the
0100  * target frozen state is reached.  IOW, the current task will be
0101  * considered frozen enough by freezers.
0102  *
0103  * The caller shouldn't do anything which isn't allowed for a frozen task
0104  * until freezer_cont() is called.  Usually, freezer[_do_not]_count() pair
0105  * wrap a scheduling operation and nothing much else.
0106  */
0107 static inline void freezer_do_not_count(void)
0108 {
0109     current->flags |= PF_FREEZER_SKIP;
0110 }
0111 
0112 /**
0113  * freezer_count - tell freezer to stop ignoring %current
0114  *
0115  * Undo freezer_do_not_count().  It tells freezers that %current should be
0116  * considered again and tries to freeze if freezing condition is already in
0117  * effect.
0118  */
0119 static inline void freezer_count(void)
0120 {
0121     current->flags &= ~PF_FREEZER_SKIP;
0122     /*
0123      * If freezing is in progress, the following paired with smp_mb()
0124      * in freezer_should_skip() ensures that either we see %true
0125      * freezing() or freezer_should_skip() sees !PF_FREEZER_SKIP.
0126      */
0127     smp_mb();
0128     try_to_freeze();
0129 }
0130 
0131 /* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */
0132 static inline void freezer_count_unsafe(void)
0133 {
0134     current->flags &= ~PF_FREEZER_SKIP;
0135     smp_mb();
0136     try_to_freeze_unsafe();
0137 }
0138 
0139 /**
0140  * freezer_should_skip - whether to skip a task when determining frozen
0141  *           state is reached
0142  * @p: task in quesion
0143  *
0144  * This function is used by freezers after establishing %true freezing() to
0145  * test whether a task should be skipped when determining the target frozen
0146  * state is reached.  IOW, if this function returns %true, @p is considered
0147  * frozen enough.
0148  */
0149 static inline bool freezer_should_skip(struct task_struct *p)
0150 {
0151     /*
0152      * The following smp_mb() paired with the one in freezer_count()
0153      * ensures that either freezer_count() sees %true freezing() or we
0154      * see cleared %PF_FREEZER_SKIP and return %false.  This makes it
0155      * impossible for a task to slip frozen state testing after
0156      * clearing %PF_FREEZER_SKIP.
0157      */
0158     smp_mb();
0159     return p->flags & PF_FREEZER_SKIP;
0160 }
0161 
0162 /*
0163  * These functions are intended to be used whenever you want allow a sleeping
0164  * task to be frozen. Note that neither return any clear indication of
0165  * whether a freeze event happened while in this function.
0166  */
0167 
0168 /* Like schedule(), but should not block the freezer. */
0169 static inline void freezable_schedule(void)
0170 {
0171     freezer_do_not_count();
0172     schedule();
0173     freezer_count();
0174 }
0175 
0176 /* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */
0177 static inline void freezable_schedule_unsafe(void)
0178 {
0179     freezer_do_not_count();
0180     schedule();
0181     freezer_count_unsafe();
0182 }
0183 
0184 /*
0185  * Like schedule_timeout(), but should not block the freezer.  Do not
0186  * call this with locks held.
0187  */
0188 static inline long freezable_schedule_timeout(long timeout)
0189 {
0190     long __retval;
0191     freezer_do_not_count();
0192     __retval = schedule_timeout(timeout);
0193     freezer_count();
0194     return __retval;
0195 }
0196 
0197 /*
0198  * Like schedule_timeout_interruptible(), but should not block the freezer.  Do not
0199  * call this with locks held.
0200  */
0201 static inline long freezable_schedule_timeout_interruptible(long timeout)
0202 {
0203     long __retval;
0204     freezer_do_not_count();
0205     __retval = schedule_timeout_interruptible(timeout);
0206     freezer_count();
0207     return __retval;
0208 }
0209 
0210 /* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */
0211 static inline long freezable_schedule_timeout_interruptible_unsafe(long timeout)
0212 {
0213     long __retval;
0214 
0215     freezer_do_not_count();
0216     __retval = schedule_timeout_interruptible(timeout);
0217     freezer_count_unsafe();
0218     return __retval;
0219 }
0220 
0221 /* Like schedule_timeout_killable(), but should not block the freezer. */
0222 static inline long freezable_schedule_timeout_killable(long timeout)
0223 {
0224     long __retval;
0225     freezer_do_not_count();
0226     __retval = schedule_timeout_killable(timeout);
0227     freezer_count();
0228     return __retval;
0229 }
0230 
0231 /* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */
0232 static inline long freezable_schedule_timeout_killable_unsafe(long timeout)
0233 {
0234     long __retval;
0235     freezer_do_not_count();
0236     __retval = schedule_timeout_killable(timeout);
0237     freezer_count_unsafe();
0238     return __retval;
0239 }
0240 
0241 /*
0242  * Like schedule_hrtimeout_range(), but should not block the freezer.  Do not
0243  * call this with locks held.
0244  */
0245 static inline int freezable_schedule_hrtimeout_range(ktime_t *expires,
0246         u64 delta, const enum hrtimer_mode mode)
0247 {
0248     int __retval;
0249     freezer_do_not_count();
0250     __retval = schedule_hrtimeout_range(expires, delta, mode);
0251     freezer_count();
0252     return __retval;
0253 }
0254 
0255 /*
0256  * Freezer-friendly wrappers around wait_event_interruptible(),
0257  * wait_event_killable() and wait_event_interruptible_timeout(), originally
0258  * defined in <linux/wait.h>
0259  */
0260 
0261 /* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */
0262 #define wait_event_freezekillable_unsafe(wq, condition)         \
0263 ({                                  \
0264     int __retval;                           \
0265     freezer_do_not_count();                     \
0266     __retval = wait_event_killable(wq, (condition));        \
0267     freezer_count_unsafe();                     \
0268     __retval;                           \
0269 })
0270 
0271 #else /* !CONFIG_FREEZER */
0272 static inline bool frozen(struct task_struct *p) { return false; }
0273 static inline bool freezing(struct task_struct *p) { return false; }
0274 static inline void __thaw_task(struct task_struct *t) {}
0275 
0276 static inline bool __refrigerator(bool check_kthr_stop) { return false; }
0277 static inline int freeze_processes(void) { return -ENOSYS; }
0278 static inline int freeze_kernel_threads(void) { return -ENOSYS; }
0279 static inline void thaw_processes(void) {}
0280 static inline void thaw_kernel_threads(void) {}
0281 
0282 static inline bool try_to_freeze(void) { return false; }
0283 
0284 static inline void freezer_do_not_count(void) {}
0285 static inline void freezer_count(void) {}
0286 static inline int freezer_should_skip(struct task_struct *p) { return 0; }
0287 static inline void set_freezable(void) {}
0288 
0289 #define freezable_schedule()  schedule()
0290 
0291 #define freezable_schedule_unsafe()  schedule()
0292 
0293 #define freezable_schedule_timeout(timeout)  schedule_timeout(timeout)
0294 
0295 #define freezable_schedule_timeout_interruptible(timeout)       \
0296     schedule_timeout_interruptible(timeout)
0297 
0298 #define freezable_schedule_timeout_interruptible_unsafe(timeout)    \
0299     schedule_timeout_interruptible(timeout)
0300 
0301 #define freezable_schedule_timeout_killable(timeout)            \
0302     schedule_timeout_killable(timeout)
0303 
0304 #define freezable_schedule_timeout_killable_unsafe(timeout)     \
0305     schedule_timeout_killable(timeout)
0306 
0307 #define freezable_schedule_hrtimeout_range(expires, delta, mode)    \
0308     schedule_hrtimeout_range(expires, delta, mode)
0309 
0310 #define wait_event_freezekillable_unsafe(wq, condition)         \
0311         wait_event_killable(wq, condition)
0312 
0313 #endif /* !CONFIG_FREEZER */
0314 
0315 #endif  /* FREEZER_H_INCLUDED */