Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  * drivers/power/process.c - Functions for starting/stopping processes on 
  3  *                           suspend transitions.
  4  *
  5  * Originally from swsusp.
  6  */
  7 
  8 
  9 #undef DEBUG
 10 
 11 #include <linux/interrupt.h>
 12 #include <linux/suspend.h>
 13 #include <linux/module.h>
 14 #include <linux/syscalls.h>
 15 #include <linux/freezer.h>
 16 
 17 /* 
 18  * Timeout for stopping processes
 19  */
 20 #define TIMEOUT (20 * HZ)
 21 
 22 static inline int freezeable(struct task_struct * p)
 23 {
 24         if ((p == current) ||
 25             (p->flags & PF_NOFREEZE) ||
 26             (p->exit_state != 0))
 27                 return 0;
 28         return 1;
 29 }
 30 
 31 static int try_to_freeze_tasks(bool sig_only)
 32 {
 33         struct task_struct *g, *p;
 34         unsigned long end_time;
 35         unsigned int todo;
 36         struct timeval start, end;
 37         u64 elapsed_csecs64;
 38         unsigned int elapsed_csecs;
 39 
 40         do_gettimeofday(&start);
 41 
 42         end_time = jiffies + TIMEOUT;
 43         do {
 44                 todo = 0;
 45                 read_lock(&tasklist_lock);
 46                 do_each_thread(g, p) {
 47                         if (frozen(p) || !freezeable(p))
 48                                 continue;
 49 
 50                         if (!freeze_task(p, sig_only))
 51                                 continue;
 52 
 53                         /*
 54                          * Now that we've done set_freeze_flag, don't
 55                          * perturb a task in TASK_STOPPED or TASK_TRACED.
 56                          * It is "frozen enough".  If the task does wake
 57                          * up, it will immediately call try_to_freeze.
 58                          */
 59                         if (!task_is_stopped_or_traced(p) &&
 60                             !freezer_should_skip(p))
 61                                 todo++;
 62                 } while_each_thread(g, p);
 63                 read_unlock(&tasklist_lock);
 64                 yield();                        /* Yield is okay here */
 65                 if (time_after(jiffies, end_time))
 66                         break;
 67         } while (todo);
 68 
 69         do_gettimeofday(&end);
 70         elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start);
 71         do_div(elapsed_csecs64, NSEC_PER_SEC / 100);
 72         elapsed_csecs = elapsed_csecs64;
 73 
 74         if (todo) {
 75                 /* This does not unfreeze processes that are already frozen
 76                  * (we have slightly ugly calling convention in that respect,
 77                  * and caller must call thaw_processes() if something fails),
 78                  * but it cleans up leftover PF_FREEZE requests.
 79                  */
 80                 printk("\n");
 81                 printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds "
 82                                 "(%d tasks refusing to freeze):\n",
 83                                 elapsed_csecs / 100, elapsed_csecs % 100, todo);
 84                 show_state();
 85                 read_lock(&tasklist_lock);
 86                 do_each_thread(g, p) {
 87                         task_lock(p);
 88                         if (freezing(p) && !freezer_should_skip(p))
 89                                 printk(KERN_ERR " %s\n", p->comm);
 90                         cancel_freezing(p);
 91                         task_unlock(p);
 92                 } while_each_thread(g, p);
 93                 read_unlock(&tasklist_lock);
 94         } else {
 95                 printk("(elapsed %d.%02d seconds) ", elapsed_csecs / 100,
 96                         elapsed_csecs % 100);
 97         }
 98 
 99         return todo ? -EBUSY : 0;
100 }
101 
102 /**
103  *      freeze_processes - tell processes to enter the refrigerator
104  */
105 int freeze_processes(void)
106 {
107         int error;
108 
109         printk("Freezing user space processes ... ");
110         error = try_to_freeze_tasks(true);
111         if (error)
112                 goto Exit;
113         printk("done.\n");
114 
115         printk("Freezing remaining freezable tasks ... ");
116         error = try_to_freeze_tasks(false);
117         if (error)
118                 goto Exit;
119         printk("done.");
120 
121         oom_killer_disable();
122  Exit:
123         BUG_ON(in_atomic());
124         printk("\n");
125 
126         return error;
127 }
128 
129 static void thaw_tasks(bool nosig_only)
130 {
131         struct task_struct *g, *p;
132 
133         read_lock(&tasklist_lock);
134         do_each_thread(g, p) {
135                 if (!freezeable(p))
136                         continue;
137 
138                 if (nosig_only && should_send_signal(p))
139                         continue;
140 
141                 if (cgroup_frozen(p))
142                         continue;
143 
144                 thaw_process(p);
145         } while_each_thread(g, p);
146         read_unlock(&tasklist_lock);
147 }
148 
149 void thaw_processes(void)
150 {
151         oom_killer_enable();
152 
153         printk("Restarting tasks ... ");
154         thaw_tasks(true);
155         thaw_tasks(false);
156         schedule();
157         printk("done.\n");
158 }
159 
160 
  This page was automatically generated by the LXR engine.