Commit 83144186 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki Committed by Linus Torvalds
Browse files

Freezer: make kernel threads nonfreezable by default


Currently, the freezer treats all tasks as freezable, except for the kernel
threads that explicitly set the PF_NOFREEZE flag for themselves.  This
approach is problematic, since it requires every kernel thread to either
set PF_NOFREEZE explicitly, or call try_to_freeze(), even if it doesn't
care for the freezing of tasks at all.

It seems better to only require the kernel threads that want to or need to
be frozen to use some freezer-related code and to remove any
freezer-related code from the other (nonfreezable) kernel threads, which is
done in this patch.

The patch causes all kernel threads to be nonfreezable by default (ie.  to
have PF_NOFREEZE set by default) and introduces the set_freezable()
function that should be called by the freezable kernel threads in order to
unset PF_NOFREEZE.  It also makes all of the currently freezable kernel
threads call set_freezable(), so it shouldn't cause any (intentional)
change of behaviour to appear.  Additionally, it updates documentation to
describe the freezing of tasks more accurately.

[akpm@linux-foundation.org: build fixes]
Signed-off-by: default avatarRafael J. Wysocki <rjw@sisk.pl>
Acked-by: default avatarNigel Cunningham <nigel@nigel.suspend2.net>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Gautham R Shenoy <ego@in.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 787d2214
......@@ -23,6 +23,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/freezer.h>
#include <linux/videodev.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
......@@ -468,6 +469,7 @@ int msp3400c_thread(void *data)
v4l_dbg(1, msp_debug, client, "msp3400 daemon started\n");
set_freezable();
for (;;) {
v4l_dbg(2, msp_debug, client, "msp3400 thread: sleep\n");
msp_sleep(state, -1);
......@@ -646,7 +648,7 @@ int msp3410d_thread(void *data)
int val, i, std, count;
v4l_dbg(1, msp_debug, client, "msp3410 daemon started\n");
set_freezable();
for (;;) {
v4l_dbg(2, msp_debug, client, "msp3410 thread: sleep\n");
msp_sleep(state,-1);
......@@ -940,7 +942,7 @@ int msp34xxg_thread(void *data)
int val, i;
v4l_dbg(1, msp_debug, client, "msp34xxg daemon started\n");
set_freezable();
for (;;) {
v4l_dbg(2, msp_debug, client, "msp34xxg thread: sleep\n");
msp_sleep(state, -1);
......
......@@ -271,7 +271,7 @@ static int chip_thread(void *data)
struct CHIPDESC *desc = chiplist + chip->type;
v4l_dbg(1, debug, &chip->c, "%s: thread started\n", chip->c.name);
set_freezable();
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
if (!kthread_should_stop())
......
......@@ -47,6 +47,7 @@ static int videobuf_dvb_thread(void *data)
int err;
dprintk("dvb thread started\n");
set_freezable();
videobuf_read_start(&dvb->dvbq);
for (;;) {
......
......@@ -573,6 +573,7 @@ static int vivi_thread(void *data)
dprintk(1,"thread started\n");
mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT);
set_freezable();
for (;;) {
vivi_sleep(dma_q);
......
......@@ -209,6 +209,7 @@ static int ucb1x00_thread(void *_ts)
DECLARE_WAITQUEUE(wait, tsk);
int valid = 0;
set_freezable();
add_wait_queue(&ts->irq_wait, &wait);
while (!kthread_should_stop()) {
unsigned int x, y, p;
......
......@@ -11,6 +11,7 @@
*/
#include <linux/module.h>
#include <linux/blkdev.h>
#include <linux/freezer.h>
#include <linux/kthread.h>
#include <linux/mmc/card.h>
......@@ -44,11 +45,7 @@ static int mmc_queue_thread(void *d)
struct mmc_queue *mq = d;
struct request_queue *q = mq->queue;
/*
* Set iothread to ensure that we aren't put to sleep by
* the process freezing. We handle suspension ourselves.
*/
current->flags |= PF_MEMALLOC|PF_NOFREEZE;
current->flags |= PF_MEMALLOC;
down(&mq->thread_sem);
do {
......
......@@ -16,6 +16,7 @@
#include <linux/mtd/mtd.h>
#include <linux/blkdev.h>
#include <linux/blkpg.h>
#include <linux/freezer.h>
#include <linux/spinlock.h>
#include <linux/hdreg.h>
#include <linux/init.h>
......@@ -80,7 +81,7 @@ static int mtd_blktrans_thread(void *arg)
struct request_queue *rq = tr->blkcore_priv->rq;
/* we might get involved when memory gets low, so use PF_MEMALLOC */
current->flags |= PF_MEMALLOC | PF_NOFREEZE;
current->flags |= PF_MEMALLOC;
spin_lock_irq(rq->queue_lock);
while (!kthread_should_stop()) {
......
......@@ -1346,6 +1346,7 @@ static int ubi_thread(void *u)
ubi_msg("background thread \"%s\" started, PID %d",
ubi->bgt_name, current->pid);
set_freezable();
for (;;) {
int err;
......
......@@ -3086,7 +3086,8 @@ static int airo_thread(void *data) {
struct net_device *dev = data;
struct airo_info *ai = dev->priv;
int locked;
set_freezable();
while(1) {
/* make swsusp happy with our thread */
try_to_freeze();
......
......@@ -613,6 +613,7 @@ static int wlan_service_main_thread(void *data)
init_waitqueue_entry(&wait, current);
set_freezable();
for (;;) {
lbs_deb_thread( "main-thread 111: intcounter=%d "
"currenttxskb=%p dnld_sent=%d\n",
......
......@@ -651,6 +651,7 @@ static int pccardd(void *__skt)
add_wait_queue(&skt->thread_wait, &wait);
complete(&skt->thread_done);
set_freezable();
for (;;) {
unsigned long flags;
unsigned int events;
......
......@@ -160,6 +160,7 @@ static int pnp_dock_thread(void * unused)
{
static struct pnp_docking_station_info now;
int docked = -1, d = 0;
set_freezable();
while (!unloading)
{
int status;
......
......@@ -40,6 +40,7 @@
#include <linux/err.h>
#include <linux/blkdev.h>
#include <linux/freezer.h>
#include <linux/scatterlist.h>
/* ---------- SCSI Host glue ---------- */
......@@ -868,8 +869,6 @@ static int sas_queue_thread(void *_sas_ha)
{
struct sas_ha_struct *sas_ha = _sas_ha;
current->flags |= PF_NOFREEZE;
while (1) {
set_current_state(TASK_INTERRUPTIBLE);
schedule();
......
......@@ -19,6 +19,7 @@
#include <linux/timer.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/freezer.h>
#include <linux/kthread.h>
#include <linux/interrupt.h>
#include <linux/blkdev.h>
......@@ -1516,8 +1517,6 @@ int scsi_error_handler(void *data)
{
struct Scsi_Host *shost = data;
current->flags |= PF_NOFREEZE;
/*
* We use TASK_INTERRUPTIBLE so that the thread is not
* counted against the load average as a running process.
......
......@@ -1168,6 +1168,7 @@ static int uea_kthread(void *data)
struct uea_softc *sc = data;
int ret = -EAGAIN;
set_freezable();
uea_enters(INS_TO_USBDEV(sc));
while (!kthread_should_stop()) {
if (ret < 0 || sc->reset)
......
......@@ -2728,6 +2728,7 @@ loop:
static int hub_thread(void *__unused)
{
set_freezable();
do {
hub_events();
wait_event_interruptible(khubd_wait,
......
......@@ -3434,6 +3434,9 @@ static int fsg_main_thread(void *fsg_)
allow_signal(SIGKILL);
allow_signal(SIGUSR1);
/* Allow the thread to be frozen */
set_freezable();
/* Arrange for userspace references to be interpreted as kernel
* pointers. That way we can pass a kernel pointer to a routine
* that expects a __user pointer and it will work okay. */
......
......@@ -311,8 +311,6 @@ static int usb_stor_control_thread(void * __us)
struct Scsi_Host *host = us_to_host(us);
int autopm_rc;
current->flags |= PF_NOFREEZE;
for(;;) {
US_DEBUGP("*** thread sleeping.\n");
if(down_interruptible(&us->sema))
......@@ -920,6 +918,7 @@ static int usb_stor_scan_thread(void * __us)
printk(KERN_DEBUG
"usb-storage: device found at %d\n", us->pusb_dev->devnum);
set_freezable();
/* Wait for the timeout to expire or for a disconnect */
if (delay_use > 0) {
printk(KERN_DEBUG "usb-storage: waiting for device "
......
......@@ -812,6 +812,7 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
static int ps3fbd(void *arg)
{
set_freezable();
while (!kthread_should_stop()) {
try_to_freeze();
set_current_state(TASK_INTERRUPTIBLE);
......
......@@ -805,6 +805,7 @@ static int w1_control(void *data)
struct w1_master *dev, *n;
int have_to_wait = 0;
set_freezable();
while (!kthread_should_stop() || have_to_wait) {
have_to_wait = 0;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment