Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

freezer: unexport refrigerator() and update try_to_freeze() slightly

There is no reason to export two functions for entering the
refrigerator. Calling refrigerator() instead of try_to_freeze()
doesn't save anything noticeable or removes any race condition.

* Rename refrigerator() to __refrigerator() and make it return bool
indicating whether it scheduled out for freezing.

* Update try_to_freeze() to return bool and relay the return value of
__refrigerator() if freezing().

* Convert all refrigerator() users to try_to_freeze().

* Update documentation accordingly.

* While at it, add might_sleep() to try_to_freeze().

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Samuel Ortiz <samuel@sortiz.org>
Cc: Chris Mason <chris.mason@oracle.com>
Cc: "Theodore Ts'o" <tytso@mit.edu>
Cc: Steven Whitehouse <swhiteho@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Jan Kara <jack@suse.cz>
Cc: KONISHI Ryusuke <konishi.ryusuke@lab.ntt.co.jp>
Cc: Christoph Hellwig <hch@infradead.org>

Tejun Heo a0acae0e 3a7cbd50

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