diff options
-rw-r--r-- | Documentation/power/freezing-of-tasks.txt | 12 | ||||
-rw-r--r-- | drivers/net/irda/stir4200.c | 2 | ||||
-rw-r--r-- | fs/btrfs/async-thread.c | 2 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 8 | ||||
-rw-r--r-- | fs/ext4/super.c | 3 | ||||
-rw-r--r-- | fs/gfs2/log.c | 4 | ||||
-rw-r--r-- | fs/gfs2/quota.c | 4 | ||||
-rw-r--r-- | fs/jbd/journal.c | 2 | ||||
-rw-r--r-- | fs/jbd2/journal.c | 2 | ||||
-rw-r--r-- | fs/jfs/jfs_logmgr.c | 2 | ||||
-rw-r--r-- | fs/jfs/jfs_txnmgr.c | 4 | ||||
-rw-r--r-- | fs/nilfs2/segment.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_buf.c | 2 | ||||
-rw-r--r-- | include/linux/freezer.h | 17 | ||||
-rw-r--r-- | kernel/freezer.c | 10 |
15 files changed, 37 insertions, 39 deletions
diff --git a/Documentation/power/freezing-of-tasks.txt b/Documentation/power/freezing-of-tasks.txt index 587e0828053f..3ab9fbd2800a 100644 --- a/Documentation/power/freezing-of-tasks.txt +++ b/Documentation/power/freezing-of-tasks.txt | |||
@@ -21,7 +21,7 @@ freeze_processes() (defined in kernel/power/process.c) is called. It executes | |||
21 | try_to_freeze_tasks() that sets TIF_FREEZE for all of the freezable tasks and | 21 | try_to_freeze_tasks() that sets TIF_FREEZE for all of the freezable tasks and |
22 | either wakes them up, if they are kernel threads, or sends fake signals to them, | 22 | either wakes them up, if they are kernel threads, or sends fake signals to them, |
23 | if they are user space processes. A task that has TIF_FREEZE set, should react | 23 | if they are user space processes. A task that has TIF_FREEZE set, should react |
24 | to it by calling the function called refrigerator() (defined in | 24 | to it by calling the function called __refrigerator() (defined in |
25 | kernel/freezer.c), which sets the task's PF_FROZEN flag, changes its state | 25 | kernel/freezer.c), which sets the task's PF_FROZEN flag, changes its state |
26 | to TASK_UNINTERRUPTIBLE and makes it loop until PF_FROZEN is cleared for it. | 26 | to TASK_UNINTERRUPTIBLE and makes it loop until PF_FROZEN is cleared for it. |
27 | Then, we say that the task is 'frozen' and therefore the set of functions | 27 | Then, we say that the task is 'frozen' and therefore the set of functions |
@@ -29,10 +29,10 @@ handling this mechanism is referred to as 'the freezer' (these functions are | |||
29 | defined in kernel/power/process.c, kernel/freezer.c & include/linux/freezer.h). | 29 | defined in kernel/power/process.c, kernel/freezer.c & include/linux/freezer.h). |
30 | User space processes are generally frozen before kernel threads. | 30 | User space processes are generally frozen before kernel threads. |
31 | 31 | ||
32 | It is not recommended to call refrigerator() directly. Instead, it is | 32 | __refrigerator() must not be called directly. Instead, use the |
33 | recommended to use the try_to_freeze() function (defined in | 33 | try_to_freeze() function (defined in include/linux/freezer.h), that checks |
34 | include/linux/freezer.h), that checks the task's TIF_FREEZE flag and makes the | 34 | the task's TIF_FREEZE flag and makes the task enter __refrigerator() if the |
35 | task enter refrigerator() if the flag is set. | 35 | flag is set. |
36 | 36 | ||
37 | For user space processes try_to_freeze() is called automatically from the | 37 | For user space processes try_to_freeze() is called automatically from the |
38 | signal-handling code, but the freezable kernel threads need to call it | 38 | signal-handling code, but the freezable kernel threads need to call it |
@@ -61,7 +61,7 @@ wait_event_freezable() and wait_event_freezable_timeout() macros. | |||
61 | After the system memory state has been restored from a hibernation image and | 61 | After the system memory state has been restored from a hibernation image and |
62 | devices have been reinitialized, the function thaw_processes() is called in | 62 | devices have been reinitialized, the function thaw_processes() is called in |
63 | order to clear the PF_FROZEN flag for each frozen task. Then, the tasks that | 63 | order to clear the PF_FROZEN flag for each frozen task. Then, the tasks that |
64 | have been frozen leave refrigerator() and continue running. | 64 | have been frozen leave __refrigerator() and continue running. |
65 | 65 | ||
66 | III. Which kernel threads are freezable? | 66 | III. Which kernel threads are freezable? |
67 | 67 | ||
diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c index 41c96b3d8152..e880c79d7bd8 100644 --- a/drivers/net/irda/stir4200.c +++ b/drivers/net/irda/stir4200.c | |||
@@ -750,7 +750,7 @@ static int stir_transmit_thread(void *arg) | |||
750 | 750 | ||
751 | write_reg(stir, REG_CTRL1, CTRL1_TXPWD|CTRL1_RXPWD); | 751 | write_reg(stir, REG_CTRL1, CTRL1_TXPWD|CTRL1_RXPWD); |
752 | 752 | ||
753 | refrigerator(); | 753 | try_to_freeze(); |
754 | 754 | ||
755 | if (change_speed(stir, stir->speed)) | 755 | if (change_speed(stir, stir->speed)) |
756 | break; | 756 | break; |
diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c index 7ec14097fef1..98ab240072e5 100644 --- a/fs/btrfs/async-thread.c +++ b/fs/btrfs/async-thread.c | |||
@@ -340,7 +340,7 @@ again: | |||
340 | if (freezing(current)) { | 340 | if (freezing(current)) { |
341 | worker->working = 0; | 341 | worker->working = 0; |
342 | spin_unlock_irq(&worker->lock); | 342 | spin_unlock_irq(&worker->lock); |
343 | refrigerator(); | 343 | try_to_freeze(); |
344 | } else { | 344 | } else { |
345 | spin_unlock_irq(&worker->lock); | 345 | spin_unlock_irq(&worker->lock); |
346 | if (!kthread_should_stop()) { | 346 | if (!kthread_should_stop()) { |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 62afe5c5694e..622654fe051f 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -1579,9 +1579,7 @@ static int cleaner_kthread(void *arg) | |||
1579 | btrfs_run_defrag_inodes(root->fs_info); | 1579 | btrfs_run_defrag_inodes(root->fs_info); |
1580 | } | 1580 | } |
1581 | 1581 | ||
1582 | if (freezing(current)) { | 1582 | if (!try_to_freeze()) { |
1583 | refrigerator(); | ||
1584 | } else { | ||
1585 | set_current_state(TASK_INTERRUPTIBLE); | 1583 | set_current_state(TASK_INTERRUPTIBLE); |
1586 | if (!kthread_should_stop()) | 1584 | if (!kthread_should_stop()) |
1587 | schedule(); | 1585 | schedule(); |
@@ -1635,9 +1633,7 @@ sleep: | |||
1635 | wake_up_process(root->fs_info->cleaner_kthread); | 1633 | wake_up_process(root->fs_info->cleaner_kthread); |
1636 | mutex_unlock(&root->fs_info->transaction_kthread_mutex); | 1634 | mutex_unlock(&root->fs_info->transaction_kthread_mutex); |
1637 | 1635 | ||
1638 | if (freezing(current)) { | 1636 | if (!try_to_freeze()) { |
1639 | refrigerator(); | ||
1640 | } else { | ||
1641 | set_current_state(TASK_INTERRUPTIBLE); | 1637 | set_current_state(TASK_INTERRUPTIBLE); |
1642 | if (!kthread_should_stop() && | 1638 | if (!kthread_should_stop() && |
1643 | !btrfs_transaction_blocked(root->fs_info)) | 1639 | !btrfs_transaction_blocked(root->fs_info)) |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 9953d80145ad..877350ef0253 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -2882,8 +2882,7 @@ cont_thread: | |||
2882 | } | 2882 | } |
2883 | mutex_unlock(&eli->li_list_mtx); | 2883 | mutex_unlock(&eli->li_list_mtx); |
2884 | 2884 | ||
2885 | if (freezing(current)) | 2885 | try_to_freeze(); |
2886 | refrigerator(); | ||
2887 | 2886 | ||
2888 | cur = jiffies; | 2887 | cur = jiffies; |
2889 | if ((time_after_eq(cur, next_wakeup)) || | 2888 | if ((time_after_eq(cur, next_wakeup)) || |
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 598646434362..8154d42e4647 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -951,8 +951,8 @@ int gfs2_logd(void *data) | |||
951 | wake_up(&sdp->sd_log_waitq); | 951 | wake_up(&sdp->sd_log_waitq); |
952 | 952 | ||
953 | t = gfs2_tune_get(sdp, gt_logd_secs) * HZ; | 953 | t = gfs2_tune_get(sdp, gt_logd_secs) * HZ; |
954 | if (freezing(current)) | 954 | |
955 | refrigerator(); | 955 | try_to_freeze(); |
956 | 956 | ||
957 | do { | 957 | do { |
958 | prepare_to_wait(&sdp->sd_logd_waitq, &wait, | 958 | prepare_to_wait(&sdp->sd_logd_waitq, &wait, |
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 7e528dc14f85..d49669e92652 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
@@ -1427,8 +1427,8 @@ int gfs2_quotad(void *data) | |||
1427 | /* Check for & recover partially truncated inodes */ | 1427 | /* Check for & recover partially truncated inodes */ |
1428 | quotad_check_trunc_list(sdp); | 1428 | quotad_check_trunc_list(sdp); |
1429 | 1429 | ||
1430 | if (freezing(current)) | 1430 | try_to_freeze(); |
1431 | refrigerator(); | 1431 | |
1432 | t = min(quotad_timeo, statfs_timeo); | 1432 | t = min(quotad_timeo, statfs_timeo); |
1433 | 1433 | ||
1434 | prepare_to_wait(&sdp->sd_quota_wait, &wait, TASK_INTERRUPTIBLE); | 1434 | prepare_to_wait(&sdp->sd_quota_wait, &wait, TASK_INTERRUPTIBLE); |
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index fea8dd661d2b..a96cff0c5f1d 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c | |||
@@ -166,7 +166,7 @@ loop: | |||
166 | */ | 166 | */ |
167 | jbd_debug(1, "Now suspending kjournald\n"); | 167 | jbd_debug(1, "Now suspending kjournald\n"); |
168 | spin_unlock(&journal->j_state_lock); | 168 | spin_unlock(&journal->j_state_lock); |
169 | refrigerator(); | 169 | try_to_freeze(); |
170 | spin_lock(&journal->j_state_lock); | 170 | spin_lock(&journal->j_state_lock); |
171 | } else { | 171 | } else { |
172 | /* | 172 | /* |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 0fa0123151d3..c0a5f9f1b127 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -173,7 +173,7 @@ loop: | |||
173 | */ | 173 | */ |
174 | jbd_debug(1, "Now suspending kjournald2\n"); | 174 | jbd_debug(1, "Now suspending kjournald2\n"); |
175 | write_unlock(&journal->j_state_lock); | 175 | write_unlock(&journal->j_state_lock); |
176 | refrigerator(); | 176 | try_to_freeze(); |
177 | write_lock(&journal->j_state_lock); | 177 | write_lock(&journal->j_state_lock); |
178 | } else { | 178 | } else { |
179 | /* | 179 | /* |
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index cc5f811ed383..2eb952c41a69 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c | |||
@@ -2349,7 +2349,7 @@ int jfsIOWait(void *arg) | |||
2349 | 2349 | ||
2350 | if (freezing(current)) { | 2350 | if (freezing(current)) { |
2351 | spin_unlock_irq(&log_redrive_lock); | 2351 | spin_unlock_irq(&log_redrive_lock); |
2352 | refrigerator(); | 2352 | try_to_freeze(); |
2353 | } else { | 2353 | } else { |
2354 | set_current_state(TASK_INTERRUPTIBLE); | 2354 | set_current_state(TASK_INTERRUPTIBLE); |
2355 | spin_unlock_irq(&log_redrive_lock); | 2355 | spin_unlock_irq(&log_redrive_lock); |
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c index af9606057dde..bb8b661bcc50 100644 --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c | |||
@@ -2800,7 +2800,7 @@ int jfs_lazycommit(void *arg) | |||
2800 | 2800 | ||
2801 | if (freezing(current)) { | 2801 | if (freezing(current)) { |
2802 | LAZY_UNLOCK(flags); | 2802 | LAZY_UNLOCK(flags); |
2803 | refrigerator(); | 2803 | try_to_freeze(); |
2804 | } else { | 2804 | } else { |
2805 | DECLARE_WAITQUEUE(wq, current); | 2805 | DECLARE_WAITQUEUE(wq, current); |
2806 | 2806 | ||
@@ -2994,7 +2994,7 @@ int jfs_sync(void *arg) | |||
2994 | 2994 | ||
2995 | if (freezing(current)) { | 2995 | if (freezing(current)) { |
2996 | TXN_UNLOCK(); | 2996 | TXN_UNLOCK(); |
2997 | refrigerator(); | 2997 | try_to_freeze(); |
2998 | } else { | 2998 | } else { |
2999 | set_current_state(TASK_INTERRUPTIBLE); | 2999 | set_current_state(TASK_INTERRUPTIBLE); |
3000 | TXN_UNLOCK(); | 3000 | TXN_UNLOCK(); |
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index bb24ab6c282f..0e72ad6f22aa 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
@@ -2470,7 +2470,7 @@ static int nilfs_segctor_thread(void *arg) | |||
2470 | 2470 | ||
2471 | if (freezing(current)) { | 2471 | if (freezing(current)) { |
2472 | spin_unlock(&sci->sc_state_lock); | 2472 | spin_unlock(&sci->sc_state_lock); |
2473 | refrigerator(); | 2473 | try_to_freeze(); |
2474 | spin_lock(&sci->sc_state_lock); | 2474 | spin_lock(&sci->sc_state_lock); |
2475 | } else { | 2475 | } else { |
2476 | DEFINE_WAIT(wait); | 2476 | DEFINE_WAIT(wait); |
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index cf0ac056815f..018829936d6d 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c | |||
@@ -1703,7 +1703,7 @@ xfsbufd( | |||
1703 | 1703 | ||
1704 | if (unlikely(freezing(current))) { | 1704 | if (unlikely(freezing(current))) { |
1705 | set_bit(XBT_FORCE_SLEEP, &target->bt_flags); | 1705 | set_bit(XBT_FORCE_SLEEP, &target->bt_flags); |
1706 | refrigerator(); | 1706 | try_to_freeze(); |
1707 | } else { | 1707 | } else { |
1708 | clear_bit(XBT_FORCE_SLEEP, &target->bt_flags); | 1708 | clear_bit(XBT_FORCE_SLEEP, &target->bt_flags); |
1709 | } | 1709 | } |
diff --git a/include/linux/freezer.h b/include/linux/freezer.h index a5386e3ee756..7a9427e9fe47 100644 --- a/include/linux/freezer.h +++ b/include/linux/freezer.h | |||
@@ -47,18 +47,17 @@ static inline bool should_send_signal(struct task_struct *p) | |||
47 | /* Takes and releases task alloc lock using task_lock() */ | 47 | /* Takes and releases task alloc lock using task_lock() */ |
48 | extern int thaw_process(struct task_struct *p); | 48 | extern int thaw_process(struct task_struct *p); |
49 | 49 | ||
50 | extern void refrigerator(void); | 50 | extern bool __refrigerator(void); |
51 | extern int freeze_processes(void); | 51 | extern int freeze_processes(void); |
52 | extern int freeze_kernel_threads(void); | 52 | extern int freeze_kernel_threads(void); |
53 | extern void thaw_processes(void); | 53 | extern void thaw_processes(void); |
54 | 54 | ||
55 | static inline int try_to_freeze(void) | 55 | static inline bool try_to_freeze(void) |
56 | { | 56 | { |
57 | if (freezing(current)) { | 57 | might_sleep(); |
58 | refrigerator(); | 58 | if (likely(!freezing(current))) |
59 | return 1; | 59 | return false; |
60 | } else | 60 | return __refrigerator(); |
61 | return 0; | ||
62 | } | 61 | } |
63 | 62 | ||
64 | extern bool freeze_task(struct task_struct *p, bool sig_only); | 63 | extern bool freeze_task(struct task_struct *p, bool sig_only); |
@@ -181,12 +180,12 @@ static inline void set_freeze_flag(struct task_struct *p) {} | |||
181 | static inline void clear_freeze_flag(struct task_struct *p) {} | 180 | static inline void clear_freeze_flag(struct task_struct *p) {} |
182 | static inline int thaw_process(struct task_struct *p) { return 1; } | 181 | static inline int thaw_process(struct task_struct *p) { return 1; } |
183 | 182 | ||
184 | static inline void refrigerator(void) {} | 183 | static inline bool __refrigerator(void) { return false; } |
185 | static inline int freeze_processes(void) { return -ENOSYS; } | 184 | static inline int freeze_processes(void) { return -ENOSYS; } |
186 | static inline int freeze_kernel_threads(void) { return -ENOSYS; } | 185 | static inline int freeze_kernel_threads(void) { return -ENOSYS; } |
187 | static inline void thaw_processes(void) {} | 186 | static inline void thaw_processes(void) {} |
188 | 187 | ||
189 | static inline int try_to_freeze(void) { return 0; } | 188 | static inline bool try_to_freeze(void) { return false; } |
190 | 189 | ||
191 | static inline void freezer_do_not_count(void) {} | 190 | static inline void freezer_do_not_count(void) {} |
192 | static inline void freezer_count(void) {} | 191 | static inline void freezer_count(void) {} |
diff --git a/kernel/freezer.c b/kernel/freezer.c index 3f460104a9d6..732f14f5944f 100644 --- a/kernel/freezer.c +++ b/kernel/freezer.c | |||
@@ -23,10 +23,11 @@ static inline void frozen_process(void) | |||
23 | } | 23 | } |
24 | 24 | ||
25 | /* Refrigerator is place where frozen processes are stored :-). */ | 25 | /* Refrigerator is place where frozen processes are stored :-). */ |
26 | void refrigerator(void) | 26 | bool __refrigerator(void) |
27 | { | 27 | { |
28 | /* Hmm, should we be allowed to suspend when there are realtime | 28 | /* Hmm, should we be allowed to suspend when there are realtime |
29 | processes around? */ | 29 | processes around? */ |
30 | bool was_frozen = false; | ||
30 | long save; | 31 | long save; |
31 | 32 | ||
32 | task_lock(current); | 33 | task_lock(current); |
@@ -35,7 +36,7 @@ void refrigerator(void) | |||
35 | task_unlock(current); | 36 | task_unlock(current); |
36 | } else { | 37 | } else { |
37 | task_unlock(current); | 38 | task_unlock(current); |
38 | return; | 39 | return was_frozen; |
39 | } | 40 | } |
40 | save = current->state; | 41 | save = current->state; |
41 | pr_debug("%s entered refrigerator\n", current->comm); | 42 | pr_debug("%s entered refrigerator\n", current->comm); |
@@ -51,6 +52,7 @@ void refrigerator(void) | |||
51 | set_current_state(TASK_UNINTERRUPTIBLE); | 52 | set_current_state(TASK_UNINTERRUPTIBLE); |
52 | if (!frozen(current)) | 53 | if (!frozen(current)) |
53 | break; | 54 | break; |
55 | was_frozen = true; | ||
54 | schedule(); | 56 | schedule(); |
55 | } | 57 | } |
56 | 58 | ||
@@ -65,8 +67,10 @@ void refrigerator(void) | |||
65 | * synchronization which depends on ordered task state change. | 67 | * synchronization which depends on ordered task state change. |
66 | */ | 68 | */ |
67 | set_current_state(save); | 69 | set_current_state(save); |
70 | |||
71 | return was_frozen; | ||
68 | } | 72 | } |
69 | EXPORT_SYMBOL(refrigerator); | 73 | EXPORT_SYMBOL(__refrigerator); |
70 | 74 | ||
71 | static void fake_signal_wake_up(struct task_struct *p) | 75 | static void fake_signal_wake_up(struct task_struct *p) |
72 | { | 76 | { |