Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * kernel/freezer.c - Function to freeze a process
0004  *
0005  * Originally from kernel/power/process.c
0006  */
0007 
0008 #include <linux/interrupt.h>
0009 #include <linux/suspend.h>
0010 #include <linux/export.h>
0011 #include <linux/syscalls.h>
0012 #include <linux/freezer.h>
0013 #include <linux/kthread.h>
0014 
0015 /* total number of freezing conditions in effect */
0016 atomic_t system_freezing_cnt = ATOMIC_INIT(0);
0017 EXPORT_SYMBOL(system_freezing_cnt);
0018 
0019 /* indicate whether PM freezing is in effect, protected by
0020  * system_transition_mutex
0021  */
0022 bool pm_freezing;
0023 bool pm_nosig_freezing;
0024 
0025 /* protects freezing and frozen transitions */
0026 static DEFINE_SPINLOCK(freezer_lock);
0027 
0028 /**
0029  * freezing_slow_path - slow path for testing whether a task needs to be frozen
0030  * @p: task to be tested
0031  *
0032  * This function is called by freezing() if system_freezing_cnt isn't zero
0033  * and tests whether @p needs to enter and stay in frozen state.  Can be
0034  * called under any context.  The freezers are responsible for ensuring the
0035  * target tasks see the updated state.
0036  */
0037 bool freezing_slow_path(struct task_struct *p)
0038 {
0039     if (p->flags & (PF_NOFREEZE | PF_SUSPEND_TASK))
0040         return false;
0041 
0042     if (test_tsk_thread_flag(p, TIF_MEMDIE))
0043         return false;
0044 
0045     if (pm_nosig_freezing || cgroup_freezing(p))
0046         return true;
0047 
0048     if (pm_freezing && !(p->flags & PF_KTHREAD))
0049         return true;
0050 
0051     return false;
0052 }
0053 EXPORT_SYMBOL(freezing_slow_path);
0054 
0055 /* Refrigerator is place where frozen processes are stored :-). */
0056 bool __refrigerator(bool check_kthr_stop)
0057 {
0058     /* Hmm, should we be allowed to suspend when there are realtime
0059        processes around? */
0060     bool was_frozen = false;
0061     unsigned int save = get_current_state();
0062 
0063     pr_debug("%s entered refrigerator\n", current->comm);
0064 
0065     for (;;) {
0066         set_current_state(TASK_UNINTERRUPTIBLE);
0067 
0068         spin_lock_irq(&freezer_lock);
0069         current->flags |= PF_FROZEN;
0070         if (!freezing(current) ||
0071             (check_kthr_stop && kthread_should_stop()))
0072             current->flags &= ~PF_FROZEN;
0073         spin_unlock_irq(&freezer_lock);
0074 
0075         if (!(current->flags & PF_FROZEN))
0076             break;
0077         was_frozen = true;
0078         schedule();
0079     }
0080 
0081     pr_debug("%s left refrigerator\n", current->comm);
0082 
0083     /*
0084      * Restore saved task state before returning.  The mb'd version
0085      * needs to be used; otherwise, it might silently break
0086      * synchronization which depends on ordered task state change.
0087      */
0088     set_current_state(save);
0089 
0090     return was_frozen;
0091 }
0092 EXPORT_SYMBOL(__refrigerator);
0093 
0094 static void fake_signal_wake_up(struct task_struct *p)
0095 {
0096     unsigned long flags;
0097 
0098     if (lock_task_sighand(p, &flags)) {
0099         signal_wake_up(p, 0);
0100         unlock_task_sighand(p, &flags);
0101     }
0102 }
0103 
0104 /**
0105  * freeze_task - send a freeze request to given task
0106  * @p: task to send the request to
0107  *
0108  * If @p is freezing, the freeze request is sent either by sending a fake
0109  * signal (if it's not a kernel thread) or waking it up (if it's a kernel
0110  * thread).
0111  *
0112  * RETURNS:
0113  * %false, if @p is not freezing or already frozen; %true, otherwise
0114  */
0115 bool freeze_task(struct task_struct *p)
0116 {
0117     unsigned long flags;
0118 
0119     /*
0120      * This check can race with freezer_do_not_count, but worst case that
0121      * will result in an extra wakeup being sent to the task.  It does not
0122      * race with freezer_count(), the barriers in freezer_count() and
0123      * freezer_should_skip() ensure that either freezer_count() sees
0124      * freezing == true in try_to_freeze() and freezes, or
0125      * freezer_should_skip() sees !PF_FREEZE_SKIP and freezes the task
0126      * normally.
0127      */
0128     if (freezer_should_skip(p))
0129         return false;
0130 
0131     spin_lock_irqsave(&freezer_lock, flags);
0132     if (!freezing(p) || frozen(p)) {
0133         spin_unlock_irqrestore(&freezer_lock, flags);
0134         return false;
0135     }
0136 
0137     if (!(p->flags & PF_KTHREAD))
0138         fake_signal_wake_up(p);
0139     else
0140         wake_up_state(p, TASK_INTERRUPTIBLE);
0141 
0142     spin_unlock_irqrestore(&freezer_lock, flags);
0143     return true;
0144 }
0145 
0146 void __thaw_task(struct task_struct *p)
0147 {
0148     unsigned long flags;
0149 
0150     spin_lock_irqsave(&freezer_lock, flags);
0151     if (frozen(p))
0152         wake_up_process(p);
0153     spin_unlock_irqrestore(&freezer_lock, flags);
0154 }
0155 
0156 /**
0157  * set_freezable - make %current freezable
0158  *
0159  * Mark %current freezable and enter refrigerator if necessary.
0160  */
0161 bool set_freezable(void)
0162 {
0163     might_sleep();
0164 
0165     /*
0166      * Modify flags while holding freezer_lock.  This ensures the
0167      * freezer notices that we aren't frozen yet or the freezing
0168      * condition is visible to try_to_freeze() below.
0169      */
0170     spin_lock_irq(&freezer_lock);
0171     current->flags &= ~PF_NOFREEZE;
0172     spin_unlock_irq(&freezer_lock);
0173 
0174     return try_to_freeze();
0175 }
0176 EXPORT_SYMBOL(set_freezable);