LCOV - code coverage report
Current view: top level - kernel - freezer.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 3 37 8.1 %
Date: 2015-04-12 14:34:49 Functions: 1 6 16.7 %

          Line data    Source code
       1             : /*
       2             :  * kernel/freezer.c - Function to freeze a process
       3             :  *
       4             :  * Originally from kernel/power/process.c
       5             :  */
       6             : 
       7             : #include <linux/interrupt.h>
       8             : #include <linux/suspend.h>
       9             : #include <linux/export.h>
      10             : #include <linux/syscalls.h>
      11             : #include <linux/freezer.h>
      12             : #include <linux/kthread.h>
      13             : 
      14             : /* total number of freezing conditions in effect */
      15             : atomic_t system_freezing_cnt = ATOMIC_INIT(0);
      16             : EXPORT_SYMBOL(system_freezing_cnt);
      17             : 
      18             : /* indicate whether PM freezing is in effect, protected by pm_mutex */
      19             : bool pm_freezing;
      20             : bool pm_nosig_freezing;
      21             : 
      22             : /*
      23             :  * Temporary export for the deadlock workaround in ata_scsi_hotplug().
      24             :  * Remove once the hack becomes unnecessary.
      25             :  */
      26             : EXPORT_SYMBOL_GPL(pm_freezing);
      27             : 
      28             : /* protects freezing and frozen transitions */
      29             : static DEFINE_SPINLOCK(freezer_lock);
      30             : 
      31             : /**
      32             :  * freezing_slow_path - slow path for testing whether a task needs to be frozen
      33             :  * @p: task to be tested
      34             :  *
      35             :  * This function is called by freezing() if system_freezing_cnt isn't zero
      36             :  * and tests whether @p needs to enter and stay in frozen state.  Can be
      37             :  * called under any context.  The freezers are responsible for ensuring the
      38             :  * target tasks see the updated state.
      39             :  */
      40           0 : bool freezing_slow_path(struct task_struct *p)
      41             : {
      42           0 :         if (p->flags & (PF_NOFREEZE | PF_SUSPEND_TASK))
      43             :                 return false;
      44             : 
      45           0 :         if (test_thread_flag(TIF_MEMDIE))
      46             :                 return false;
      47             : 
      48           0 :         if (pm_nosig_freezing || cgroup_freezing(p))
      49             :                 return true;
      50             : 
      51           0 :         if (pm_freezing && !(p->flags & PF_KTHREAD))
      52             :                 return true;
      53             : 
      54           0 :         return false;
      55             : }
      56             : EXPORT_SYMBOL(freezing_slow_path);
      57             : 
      58             : /* Refrigerator is place where frozen processes are stored :-). */
      59           0 : bool __refrigerator(bool check_kthr_stop)
      60             : {
      61             :         /* Hmm, should we be allowed to suspend when there are realtime
      62             :            processes around? */
      63             :         bool was_frozen = false;
      64           0 :         long save = current->state;
      65             : 
      66             :         pr_debug("%s entered refrigerator\n", current->comm);
      67             : 
      68             :         for (;;) {
      69           0 :                 set_current_state(TASK_UNINTERRUPTIBLE);
      70             : 
      71             :                 spin_lock_irq(&freezer_lock);
      72           0 :                 current->flags |= PF_FROZEN;
      73           0 :                 if (!freezing(current) ||
      74           0 :                     (check_kthr_stop && kthread_should_stop()))
      75           0 :                         current->flags &= ~PF_FROZEN;
      76             :                 spin_unlock_irq(&freezer_lock);
      77             : 
      78           0 :                 if (!(current->flags & PF_FROZEN))
      79             :                         break;
      80             :                 was_frozen = true;
      81           0 :                 schedule();
      82           0 :         }
      83             : 
      84             :         pr_debug("%s left refrigerator\n", current->comm);
      85             : 
      86             :         /*
      87             :          * Restore saved task state before returning.  The mb'd version
      88             :          * needs to be used; otherwise, it might silently break
      89             :          * synchronization which depends on ordered task state change.
      90             :          */
      91           0 :         set_current_state(save);
      92             : 
      93           0 :         return was_frozen;
      94             : }
      95             : EXPORT_SYMBOL(__refrigerator);
      96             : 
      97           0 : static void fake_signal_wake_up(struct task_struct *p)
      98             : {
      99             :         unsigned long flags;
     100             : 
     101           0 :         if (lock_task_sighand(p, &flags)) {
     102             :                 signal_wake_up(p, 0);
     103           0 :                 unlock_task_sighand(p, &flags);
     104             :         }
     105           0 : }
     106             : 
     107             : /**
     108             :  * freeze_task - send a freeze request to given task
     109             :  * @p: task to send the request to
     110             :  *
     111             :  * If @p is freezing, the freeze request is sent either by sending a fake
     112             :  * signal (if it's not a kernel thread) or waking it up (if it's a kernel
     113             :  * thread).
     114             :  *
     115             :  * RETURNS:
     116             :  * %false, if @p is not freezing or already frozen; %true, otherwise
     117             :  */
     118           0 : bool freeze_task(struct task_struct *p)
     119             : {
     120             :         unsigned long flags;
     121             : 
     122             :         /*
     123             :          * This check can race with freezer_do_not_count, but worst case that
     124             :          * will result in an extra wakeup being sent to the task.  It does not
     125             :          * race with freezer_count(), the barriers in freezer_count() and
     126             :          * freezer_should_skip() ensure that either freezer_count() sees
     127             :          * freezing == true in try_to_freeze() and freezes, or
     128             :          * freezer_should_skip() sees !PF_FREEZE_SKIP and freezes the task
     129             :          * normally.
     130             :          */
     131           0 :         if (freezer_should_skip(p))
     132             :                 return false;
     133             : 
     134           0 :         spin_lock_irqsave(&freezer_lock, flags);
     135           0 :         if (!freezing(p) || frozen(p)) {
     136             :                 spin_unlock_irqrestore(&freezer_lock, flags);
     137             :                 return false;
     138             :         }
     139             : 
     140           0 :         if (!(p->flags & PF_KTHREAD))
     141           0 :                 fake_signal_wake_up(p);
     142             :         else
     143           0 :                 wake_up_state(p, TASK_INTERRUPTIBLE);
     144             : 
     145             :         spin_unlock_irqrestore(&freezer_lock, flags);
     146             :         return true;
     147             : }
     148             : 
     149           0 : void __thaw_task(struct task_struct *p)
     150             : {
     151             :         unsigned long flags;
     152             : 
     153           0 :         spin_lock_irqsave(&freezer_lock, flags);
     154           0 :         if (frozen(p))
     155           0 :                 wake_up_process(p);
     156             :         spin_unlock_irqrestore(&freezer_lock, flags);
     157           0 : }
     158             : 
     159             : /**
     160             :  * set_freezable - make %current freezable
     161             :  *
     162             :  * Mark %current freezable and enter refrigerator if necessary.
     163             :  */
     164           2 : bool set_freezable(void)
     165             : {
     166             :         might_sleep();
     167             : 
     168             :         /*
     169             :          * Modify flags while holding freezer_lock.  This ensures the
     170             :          * freezer notices that we aren't frozen yet or the freezing
     171             :          * condition is visible to try_to_freeze() below.
     172             :          */
     173             :         spin_lock_irq(&freezer_lock);
     174           2 :         current->flags &= ~PF_NOFREEZE;
     175             :         spin_unlock_irq(&freezer_lock);
     176             : 
     177           2 :         return try_to_freeze();
     178             : }
     179             : EXPORT_SYMBOL(set_freezable);

Generated by: LCOV version 1.11