[PATCH] Cleanup patch for process freezing

1. Establish a simple API for process freezing defined in linux/include/sched.h:

   frozen(process)		Check for frozen process
   freezing(process)		Check if a process is being frozen
   freeze(process)		Tell a process to freeze (go to refrigerator)
   thaw_process(process)	Restart process
   frozen_process(process)	Process is frozen now

2. Remove all references to PF_FREEZE and PF_FROZEN from all
   kernel sources except sched.h

3. Fix numerous locations where try_to_freeze is manually done by a driver

4. Remove the argument that is no longer necessary from two function calls.

5. Some whitespace cleanup

6. Clear potential race in refrigerator (provides an open window of PF_FREEZE
   cleared before setting PF_FROZEN, recalc_sigpending does not check
   PF_FROZEN).

This patch does not address the problem of freeze_processes() violating the rule
that a task may only modify its own flags by setting PF_FREEZE. This is not clean
in an SMP environment. freeze(process) is therefore not SMP safe!

Signed-off-by: Christoph Lameter <christoph@lameter.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Christoph Lameter 2005-06-24 23:13:50 -07:00 committed by Linus Torvalds
parent b3e112bcc1
commit 3e1d1d28d9
47 changed files with 126 additions and 113 deletions

View file

@ -12,8 +12,7 @@ refrigerator. Code to do this looks like this:
do { do {
hub_events(); hub_events();
wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list)); wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list));
if (current->flags & PF_FREEZE) try_to_freeze();
refrigerator(PF_FREEZE);
} while (!signal_pending(current)); } while (!signal_pending(current));
from drivers/usb/core/hub.c::hub_thread() from drivers/usb/core/hub.c::hub_thread()

View file

@ -164,8 +164,7 @@ place where the thread is safe to be frozen (no kernel semaphores
should be held at that point and it must be safe to sleep there), and should be held at that point and it must be safe to sleep there), and
add: add:
if (current->flags & PF_FREEZE) try_to_freeze();
refrigerator(PF_FREEZE);
If the thread is needed for writing the image to storage, you should If the thread is needed for writing the image to storage, you should
instead set the PF_NOFREEZE process flag when creating the thread. instead set the PF_NOFREEZE process flag when creating the thread.

View file

@ -536,10 +536,8 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
if (!user_mode(regs)) if (!user_mode(regs))
return 1; return 1;
if (current->flags & PF_FREEZE) { if (try_to_freeze())
refrigerator(0);
goto no_signal; goto no_signal;
}
if (!oldset) if (!oldset)
oldset = &current->blocked; oldset = &current->blocked;

View file

@ -517,10 +517,8 @@ asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset)
if ((regs->ccr & 0x10)) if ((regs->ccr & 0x10))
return 1; return 1;
if (current->flags & PF_FREEZE) { if (try_to_freeze())
refrigerator(0);
goto no_signal; goto no_signal;
}
current->thread.esp0 = (unsigned long) regs; current->thread.esp0 = (unsigned long) regs;

View file

@ -573,7 +573,7 @@ static int balanced_irq(void *unused)
for ( ; ; ) { for ( ; ; ) {
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
time_remaining = schedule_timeout(time_remaining); time_remaining = schedule_timeout(time_remaining);
try_to_freeze(PF_FREEZE); try_to_freeze();
if (time_after(jiffies, if (time_after(jiffies,
prev_balance_time+balanced_irq_interval)) { prev_balance_time+balanced_irq_interval)) {
do_irq_balance(); do_irq_balance();

View file

@ -608,10 +608,8 @@ int fastcall do_signal(struct pt_regs *regs, sigset_t *oldset)
if (!user_mode(regs)) if (!user_mode(regs))
return 1; return 1;
if (current->flags & PF_FREEZE) { if (try_to_freeze)
refrigerator(0);
goto no_signal; goto no_signal;
}
if (!oldset) if (!oldset)
oldset = &current->blocked; oldset = &current->blocked;

View file

@ -371,10 +371,8 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
if (!user_mode(regs)) if (!user_mode(regs))
return 1; return 1;
if (current->flags & PF_FREEZE) { if (try_to_freeze())
refrigerator(0);
goto no_signal; goto no_signal;
}
if (!oldset) if (!oldset)
oldset = &current->blocked; oldset = &current->blocked;

View file

@ -705,8 +705,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
unsigned long frame, newsp; unsigned long frame, newsp;
int signr, ret; int signr, ret;
if (current->flags & PF_FREEZE) { if (try_to_freeze()) {
refrigerator(PF_FREEZE);
signr = 0; signr = 0;
if (!signal_pending(current)) if (!signal_pending(current))
goto no_signal; goto no_signal;

View file

@ -425,7 +425,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
if (!user_mode(regs)) if (!user_mode(regs))
return 1; return 1;
if (try_to_freeze(0)) if (try_to_freeze())
goto no_signal; goto no_signal;
if (!oldset) if (!oldset)

View file

@ -1251,8 +1251,7 @@ static int kcdrwd(void *foobar)
VPRINTK("kcdrwd: wake up\n"); VPRINTK("kcdrwd: wake up\n");
/* make swsusp happy with our thread */ /* make swsusp happy with our thread */
if (current->flags & PF_FREEZE) try_to_freeze();
refrigerator(PF_FREEZE);
list_for_each_entry(pkt, &pd->cdrw.pkt_active_list, list) { list_for_each_entry(pkt, &pd->cdrw.pkt_active_list, list) {
if (!pkt->sleep_time) if (!pkt->sleep_time)

View file

@ -1041,10 +1041,8 @@ static int hpsbpkt_thread(void *__hi)
while (1) { while (1) {
if (down_interruptible(&khpsbpkt_sig)) { if (down_interruptible(&khpsbpkt_sig)) {
if (current->flags & PF_FREEZE) { if (try_to_freeze())
refrigerator(0);
continue; continue;
}
printk("khpsbpkt: received unexpected signal?!\n" ); printk("khpsbpkt: received unexpected signal?!\n" );
break; break;
} }

View file

@ -1510,7 +1510,7 @@ static int nodemgr_host_thread(void *__hi)
if (down_interruptible(&hi->reset_sem) || if (down_interruptible(&hi->reset_sem) ||
down_interruptible(&nodemgr_serialize)) { down_interruptible(&nodemgr_serialize)) {
if (try_to_freeze(PF_FREEZE)) if (try_to_freeze())
continue; continue;
printk("NodeMgr: received unexpected signal?!\n" ); printk("NodeMgr: received unexpected signal?!\n" );
break; break;

View file

@ -439,7 +439,7 @@ static int gameport_thread(void *nothing)
do { do {
gameport_handle_events(); gameport_handle_events();
wait_event_interruptible(gameport_wait, !list_empty(&gameport_event_list)); wait_event_interruptible(gameport_wait, !list_empty(&gameport_event_list));
try_to_freeze(PF_FREEZE); try_to_freeze();
} while (!signal_pending(current)); } while (!signal_pending(current));
printk(KERN_DEBUG "gameport: kgameportd exiting\n"); printk(KERN_DEBUG "gameport: kgameportd exiting\n");

View file

@ -344,7 +344,7 @@ static int serio_thread(void *nothing)
do { do {
serio_handle_events(); serio_handle_events();
wait_event_interruptible(serio_wait, !list_empty(&serio_event_list)); wait_event_interruptible(serio_wait, !list_empty(&serio_event_list));
try_to_freeze(PF_FREEZE); try_to_freeze();
} while (!signal_pending(current)); } while (!signal_pending(current));
printk(KERN_DEBUG "serio: kseriod exiting\n"); printk(KERN_DEBUG "serio: kseriod exiting\n");

View file

@ -328,9 +328,7 @@ static int monitor_task(void *arg)
struct thermostat* th = arg; struct thermostat* th = arg;
while(!kthread_should_stop()) { while(!kthread_should_stop()) {
if (current->flags & PF_FREEZE) try_to_freeze();
refrigerator(PF_FREEZE);
msleep_interruptible(2000); msleep_interruptible(2000);
#ifndef DEBUG #ifndef DEBUG

View file

@ -2976,8 +2976,7 @@ static int md_thread(void * arg)
wait_event_interruptible_timeout(thread->wqueue, wait_event_interruptible_timeout(thread->wqueue,
test_bit(THREAD_WAKEUP, &thread->flags), test_bit(THREAD_WAKEUP, &thread->flags),
thread->timeout); thread->timeout);
if (current->flags & PF_FREEZE) try_to_freeze();
refrigerator(PF_FREEZE);
clear_bit(THREAD_WAKEUP, &thread->flags); clear_bit(THREAD_WAKEUP, &thread->flags);

View file

@ -391,8 +391,7 @@ static int dvb_frontend_thread(void *data)
break; break;
} }
if (current->flags & PF_FREEZE) try_to_freeze();
refrigerator(PF_FREEZE);
if (down_interruptible(&fepriv->sem)) if (down_interruptible(&fepriv->sem))
break; break;

View file

@ -750,8 +750,7 @@ static int msp34xx_sleep(struct msp3400c *msp, int timeout)
#endif #endif
} }
} }
if (current->flags & PF_FREEZE) try_to_freeze();
refrigerator(PF_FREEZE);
remove_wait_queue(&msp->wq, &wait); remove_wait_queue(&msp->wq, &wait);
return msp->restart; return msp->restart;
} }

View file

@ -62,8 +62,7 @@ static int videobuf_dvb_thread(void *data)
break; break;
if (kthread_should_stop()) if (kthread_should_stop())
break; break;
if (current->flags & PF_FREEZE) try_to_freeze();
refrigerator(PF_FREEZE);
/* feed buffer data to demux */ /* feed buffer data to demux */
if (buf->state == STATE_DONE) if (buf->state == STATE_DONE)

View file

@ -1606,7 +1606,7 @@ static int rtl8139_thread (void *data)
do { do {
timeout = interruptible_sleep_on_timeout (&tp->thr_wait, timeout); timeout = interruptible_sleep_on_timeout (&tp->thr_wait, timeout);
/* make swsusp happy with our thread */ /* make swsusp happy with our thread */
try_to_freeze(PF_FREEZE); try_to_freeze();
} while (!signal_pending (current) && (timeout > 0)); } while (!signal_pending (current) && (timeout > 0));
if (signal_pending (current)) { if (signal_pending (current)) {

View file

@ -135,8 +135,7 @@ static int irda_thread(void *startup)
remove_wait_queue(&irda_rq_queue.kick, &wait); remove_wait_queue(&irda_rq_queue.kick, &wait);
/* make swsusp happy with our thread */ /* make swsusp happy with our thread */
if (current->flags & PF_FREEZE) try_to_freeze();
refrigerator(PF_FREEZE);
run_irda_queue(); run_irda_queue();
} }

View file

@ -763,7 +763,7 @@ static int stir_transmit_thread(void *arg)
{ {
#ifdef CONFIG_PM #ifdef CONFIG_PM
/* if suspending, then power off and wait */ /* if suspending, then power off and wait */
if (unlikely(current->flags & PF_FREEZE)) { if (unlikely(freezing(current))) {
if (stir->receiving) if (stir->receiving)
receive_stop(stir); receive_stop(stir);
else else
@ -771,7 +771,7 @@ static int stir_transmit_thread(void *arg)
write_reg(stir, REG_CTRL1, CTRL1_TXPWD|CTRL1_RXPWD); write_reg(stir, REG_CTRL1, CTRL1_TXPWD|CTRL1_RXPWD);
refrigerator(PF_FREEZE); refrigerator();
if (change_speed(stir, stir->speed)) if (change_speed(stir, stir->speed))
break; break;

View file

@ -2918,7 +2918,7 @@ static int airo_thread(void *data) {
flush_signals(current); flush_signals(current);
/* make swsusp happy with our thread */ /* make swsusp happy with our thread */
try_to_freeze(PF_FREEZE); try_to_freeze();
if (test_bit(JOB_DIE, &ai->flags)) if (test_bit(JOB_DIE, &ai->flags))
break; break;

View file

@ -718,7 +718,7 @@ static int pccardd(void *__skt)
} }
schedule(); schedule();
try_to_freeze(PF_FREEZE); try_to_freeze();
if (!skt->thread) if (!skt->thread)
break; break;

View file

@ -182,7 +182,7 @@ static int pnp_dock_thread(void * unused)
msleep_interruptible(2000); msleep_interruptible(2000);
if(signal_pending(current)) { if(signal_pending(current)) {
if (try_to_freeze(PF_FREEZE)) if (try_to_freeze())
continue; continue;
break; break;
} }

View file

@ -2808,7 +2808,7 @@ static int hub_thread(void *__unused)
do { do {
hub_events(); hub_events();
wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list)); wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list));
try_to_freeze(PF_FREEZE); try_to_freeze();
} while (!signal_pending(current)); } while (!signal_pending(current));
pr_debug ("%s: khubd exiting\n", usbcore_name); pr_debug ("%s: khubd exiting\n", usbcore_name);

View file

@ -1554,8 +1554,7 @@ static int sleep_thread(struct fsg_dev *fsg)
rc = wait_event_interruptible(fsg->thread_wqh, rc = wait_event_interruptible(fsg->thread_wqh,
fsg->thread_wakeup_needed); fsg->thread_wakeup_needed);
fsg->thread_wakeup_needed = 0; fsg->thread_wakeup_needed = 0;
if (current->flags & PF_FREEZE) try_to_freeze();
refrigerator(PF_FREEZE);
return (rc ? -EINTR : 0); return (rc ? -EINTR : 0);
} }

View file

@ -847,10 +847,8 @@ retry:
wait_event_interruptible_timeout(us->delay_wait, wait_event_interruptible_timeout(us->delay_wait,
test_bit(US_FLIDX_DISCONNECTING, &us->flags), test_bit(US_FLIDX_DISCONNECTING, &us->flags),
delay_use * HZ); delay_use * HZ);
if (current->flags & PF_FREEZE) { if (try_to_freeze())
refrigerator(PF_FREEZE);
goto retry; goto retry;
}
} }
/* If the device is still connected, perform the scanning */ /* If the device is still connected, perform the scanning */

View file

@ -646,7 +646,7 @@ static int w1_control(void *data)
while (!control_needs_exit || have_to_wait) { while (!control_needs_exit || have_to_wait) {
have_to_wait = 0; have_to_wait = 0;
try_to_freeze(PF_FREEZE); try_to_freeze();
msleep_interruptible(w1_timeout * 1000); msleep_interruptible(w1_timeout * 1000);
if (signal_pending(current)) if (signal_pending(current))
@ -725,7 +725,7 @@ int w1_process(void *data)
allow_signal(SIGTERM); allow_signal(SIGTERM);
while (!test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) { while (!test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) {
try_to_freeze(PF_FREEZE); try_to_freeze();
msleep_interruptible(w1_timeout * 1000); msleep_interruptible(w1_timeout * 1000);
if (signal_pending(current)) if (signal_pending(current))

View file

@ -116,7 +116,7 @@ static int kafsasyncd(void *arg)
remove_wait_queue(&kafsasyncd_sleepq, &myself); remove_wait_queue(&kafsasyncd_sleepq, &myself);
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
try_to_freeze(PF_FREEZE); try_to_freeze();
/* discard pending signals */ /* discard pending signals */
afs_discard_my_signals(); afs_discard_my_signals();

View file

@ -91,7 +91,7 @@ static int kafstimod(void *arg)
complete_and_exit(&kafstimod_dead, 0); complete_and_exit(&kafstimod_dead, 0);
} }
try_to_freeze(PF_FREEZE); try_to_freeze();
/* discard pending signals */ /* discard pending signals */
afs_discard_my_signals(); afs_discard_my_signals();

View file

@ -167,7 +167,7 @@ loop:
} }
wake_up(&journal->j_wait_done_commit); wake_up(&journal->j_wait_done_commit);
if (current->flags & PF_FREEZE) { if (freezing(current)) {
/* /*
* The simpler the better. Flushing journal isn't a * The simpler the better. Flushing journal isn't a
* good idea, because that depends on threads that may * good idea, because that depends on threads that may
@ -175,7 +175,7 @@ loop:
*/ */
jbd_debug(1, "Now suspending kjournald\n"); jbd_debug(1, "Now suspending kjournald\n");
spin_unlock(&journal->j_state_lock); spin_unlock(&journal->j_state_lock);
refrigerator(PF_FREEZE); refrigerator();
spin_lock(&journal->j_state_lock); spin_lock(&journal->j_state_lock);
} else { } else {
/* /*

View file

@ -2359,9 +2359,9 @@ int jfsIOWait(void *arg)
lbmStartIO(bp); lbmStartIO(bp);
spin_lock_irq(&log_redrive_lock); spin_lock_irq(&log_redrive_lock);
} }
if (current->flags & PF_FREEZE) { if (freezing(current)) {
spin_unlock_irq(&log_redrive_lock); spin_unlock_irq(&log_redrive_lock);
refrigerator(PF_FREEZE); refrigerator();
} else { } else {
add_wait_queue(&jfs_IO_thread_wait, &wq); add_wait_queue(&jfs_IO_thread_wait, &wq);
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);

View file

@ -2788,9 +2788,9 @@ int jfs_lazycommit(void *arg)
/* In case a wakeup came while all threads were active */ /* In case a wakeup came while all threads were active */
jfs_commit_thread_waking = 0; jfs_commit_thread_waking = 0;
if (current->flags & PF_FREEZE) { if (freezing(current)) {
LAZY_UNLOCK(flags); LAZY_UNLOCK(flags);
refrigerator(PF_FREEZE); refrigerator();
} else { } else {
DECLARE_WAITQUEUE(wq, current); DECLARE_WAITQUEUE(wq, current);
@ -2987,9 +2987,9 @@ int jfs_sync(void *arg)
/* Add anon_list2 back to anon_list */ /* Add anon_list2 back to anon_list */
list_splice_init(&TxAnchor.anon_list2, &TxAnchor.anon_list); list_splice_init(&TxAnchor.anon_list2, &TxAnchor.anon_list);
if (current->flags & PF_FREEZE) { if (freezing(current)) {
TXN_UNLOCK(); TXN_UNLOCK();
refrigerator(PF_FREEZE); refrigerator();
} else { } else {
DECLARE_WAITQUEUE(wq, current); DECLARE_WAITQUEUE(wq, current);

View file

@ -313,7 +313,7 @@ static int nlm_wait_on_grace(wait_queue_head_t *queue)
prepare_to_wait(queue, &wait, TASK_INTERRUPTIBLE); prepare_to_wait(queue, &wait, TASK_INTERRUPTIBLE);
if (!signalled ()) { if (!signalled ()) {
schedule_timeout(NLMCLNT_GRACE_WAIT); schedule_timeout(NLMCLNT_GRACE_WAIT);
try_to_freeze(PF_FREEZE); try_to_freeze();
if (!signalled ()) if (!signalled ())
status = 0; status = 0;
} }

View file

@ -1771,9 +1771,9 @@ xfsbufd(
INIT_LIST_HEAD(&tmp); INIT_LIST_HEAD(&tmp);
do { do {
if (unlikely(current->flags & PF_FREEZE)) { if (unlikely(freezing(current))) {
xfsbufd_force_sleep = 1; xfsbufd_force_sleep = 1;
refrigerator(PF_FREEZE); refrigerator();
} else { } else {
xfsbufd_force_sleep = 0; xfsbufd_force_sleep = 0;
} }

View file

@ -483,7 +483,7 @@ xfssyncd(
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
timeleft = schedule_timeout(timeleft); timeleft = schedule_timeout(timeleft);
/* swsusp */ /* swsusp */
try_to_freeze(PF_FREEZE); try_to_freeze();
if (vfsp->vfs_flag & VFS_UMOUNT) if (vfsp->vfs_flag & VFS_UMOUNT)
break; break;

View file

@ -1245,33 +1245,78 @@ extern void normalize_rt_tasks(void);
#endif #endif
/* try_to_freeze
*
* Checks whether we need to enter the refrigerator
* and returns 1 if we did so.
*/
#ifdef CONFIG_PM #ifdef CONFIG_PM
extern void refrigerator(unsigned long); /*
* Check if a process has been frozen
*/
static inline int frozen(struct task_struct *p)
{
return p->flags & PF_FROZEN;
}
/*
* Check if there is a request to freeze a process
*/
static inline int freezing(struct task_struct *p)
{
return p->flags & PF_FREEZE;
}
/*
* Request that a process be frozen
* FIXME: SMP problem. We may not modify other process' flags!
*/
static inline void freeze(struct task_struct *p)
{
p->flags |= PF_FREEZE;
}
/*
* Wake up a frozen process
*/
static inline int thaw_process(struct task_struct *p)
{
if (frozen(p)) {
p->flags &= ~PF_FROZEN;
wake_up_process(p);
return 1;
}
return 0;
}
/*
* freezing is complete, mark process as frozen
*/
static inline void frozen_process(struct task_struct *p)
{
p->flags = (p->flags & ~PF_FREEZE) | PF_FROZEN;
}
extern void refrigerator(void);
extern int freeze_processes(void); extern int freeze_processes(void);
extern void thaw_processes(void); extern void thaw_processes(void);
static inline int try_to_freeze(unsigned long refrigerator_flags) static inline int try_to_freeze(void)
{ {
if (unlikely(current->flags & PF_FREEZE)) { if (freezing(current)) {
refrigerator(refrigerator_flags); refrigerator();
return 1; return 1;
} else } else
return 0; return 0;
} }
#else #else
static inline void refrigerator(unsigned long flag) {} static inline int frozen(struct task_struct *p) { return 0; }
static inline int freezing(struct task_struct *p) { return 0; }
static inline void freeze(struct task_struct *p) { BUG(); }
static inline int thaw_process(struct task_struct *p) { return 1; }
static inline void frozen_process(struct task_struct *p) { BUG(); }
static inline void refrigerator(void) {}
static inline int freeze_processes(void) { BUG(); return 0; } static inline int freeze_processes(void) { BUG(); return 0; }
static inline void thaw_processes(void) {} static inline void thaw_processes(void) {}
static inline int try_to_freeze(unsigned long refrigerator_flags) static inline int try_to_freeze(void) { return 0; }
{
return 0;
}
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */

View file

@ -32,7 +32,7 @@ static inline int freezeable(struct task_struct * p)
} }
/* Refrigerator is place where frozen processes are stored :-). */ /* Refrigerator is place where frozen processes are stored :-). */
void refrigerator(unsigned long flag) void refrigerator(void)
{ {
/* Hmm, should we be allowed to suspend when there are realtime /* Hmm, should we be allowed to suspend when there are realtime
processes around? */ processes around? */
@ -41,14 +41,13 @@ void refrigerator(unsigned long flag)
current->state = TASK_UNINTERRUPTIBLE; current->state = TASK_UNINTERRUPTIBLE;
pr_debug("%s entered refrigerator\n", current->comm); pr_debug("%s entered refrigerator\n", current->comm);
printk("="); printk("=");
current->flags &= ~PF_FREEZE;
frozen_process(current);
spin_lock_irq(&current->sighand->siglock); spin_lock_irq(&current->sighand->siglock);
recalc_sigpending(); /* We sent fake signal, clean it up */ recalc_sigpending(); /* We sent fake signal, clean it up */
spin_unlock_irq(&current->sighand->siglock); spin_unlock_irq(&current->sighand->siglock);
current->flags |= PF_FROZEN; while (frozen(current))
while (current->flags & PF_FROZEN)
schedule(); schedule();
pr_debug("%s left refrigerator\n", current->comm); pr_debug("%s left refrigerator\n", current->comm);
current->state = save; current->state = save;
@ -57,10 +56,10 @@ void refrigerator(unsigned long flag)
/* 0 = success, else # of processes that we failed to stop */ /* 0 = success, else # of processes that we failed to stop */
int freeze_processes(void) int freeze_processes(void)
{ {
int todo; int todo;
unsigned long start_time; unsigned long start_time;
struct task_struct *g, *p; struct task_struct *g, *p;
printk( "Stopping tasks: " ); printk( "Stopping tasks: " );
start_time = jiffies; start_time = jiffies;
do { do {
@ -70,14 +69,12 @@ int freeze_processes(void)
unsigned long flags; unsigned long flags;
if (!freezeable(p)) if (!freezeable(p))
continue; continue;
if ((p->flags & PF_FROZEN) || if ((frozen(p)) ||
(p->state == TASK_TRACED) || (p->state == TASK_TRACED) ||
(p->state == TASK_STOPPED)) (p->state == TASK_STOPPED))
continue; continue;
/* FIXME: smp problem here: we may not access other process' flags freeze(p);
without locking */
p->flags |= PF_FREEZE;
spin_lock_irqsave(&p->sighand->siglock, flags); spin_lock_irqsave(&p->sighand->siglock, flags);
signal_wake_up(p, 0); signal_wake_up(p, 0);
spin_unlock_irqrestore(&p->sighand->siglock, flags); spin_unlock_irqrestore(&p->sighand->siglock, flags);
@ -91,7 +88,7 @@ int freeze_processes(void)
return todo; return todo;
} }
} while(todo); } while(todo);
printk( "|\n" ); printk( "|\n" );
BUG_ON(in_atomic()); BUG_ON(in_atomic());
return 0; return 0;
@ -106,10 +103,7 @@ void thaw_processes(void)
do_each_thread(g, p) { do_each_thread(g, p) {
if (!freezeable(p)) if (!freezeable(p))
continue; continue;
if (p->flags & PF_FROZEN) { if (!thaw_process(p))
p->flags &= ~PF_FROZEN;
wake_up_process(p);
} else
printk(KERN_INFO " Strange, %s not stopped\n", p->comm ); printk(KERN_INFO " Strange, %s not stopped\n", p->comm );
} while_each_thread(g, p); } while_each_thread(g, p);

View file

@ -4174,8 +4174,7 @@ static int migration_thread(void * data)
struct list_head *head; struct list_head *head;
migration_req_t *req; migration_req_t *req;
if (current->flags & PF_FREEZE) try_to_freeze();
refrigerator(PF_FREEZE);
spin_lock_irq(&rq->lock); spin_lock_irq(&rq->lock);

View file

@ -213,7 +213,7 @@ static inline int has_pending_signals(sigset_t *signal, sigset_t *blocked)
fastcall void recalc_sigpending_tsk(struct task_struct *t) fastcall void recalc_sigpending_tsk(struct task_struct *t)
{ {
if (t->signal->group_stop_count > 0 || if (t->signal->group_stop_count > 0 ||
(t->flags & PF_FREEZE) || (freezing(t)) ||
PENDING(&t->pending, &t->blocked) || PENDING(&t->pending, &t->blocked) ||
PENDING(&t->signal->shared_pending, &t->blocked)) PENDING(&t->signal->shared_pending, &t->blocked))
set_tsk_thread_flag(t, TIF_SIGPENDING); set_tsk_thread_flag(t, TIF_SIGPENDING);
@ -2231,8 +2231,7 @@ sys_rt_sigtimedwait(const sigset_t __user *uthese,
current->state = TASK_INTERRUPTIBLE; current->state = TASK_INTERRUPTIBLE;
timeout = schedule_timeout(timeout); timeout = schedule_timeout(timeout);
if (current->flags & PF_FREEZE) try_to_freeze();
refrigerator(PF_FREEZE);
spin_lock_irq(&current->sighand->siglock); spin_lock_irq(&current->sighand->siglock);
sig = dequeue_signal(current, &these, &info); sig = dequeue_signal(current, &these, &info);
current->blocked = current->real_blocked; current->blocked = current->real_blocked;

View file

@ -105,7 +105,7 @@ static int __pdflush(struct pdflush_work *my_work)
spin_unlock_irq(&pdflush_lock); spin_unlock_irq(&pdflush_lock);
schedule(); schedule();
if (try_to_freeze(PF_FREEZE)) { if (try_to_freeze()) {
spin_lock_irq(&pdflush_lock); spin_lock_irq(&pdflush_lock);
continue; continue;
} }

View file

@ -1216,8 +1216,8 @@ static int kswapd(void *p)
order = 0; order = 0;
for ( ; ; ) { for ( ; ; ) {
unsigned long new_order; unsigned long new_order;
if (current->flags & PF_FREEZE)
refrigerator(PF_FREEZE); try_to_freeze();
prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE); prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE);
new_order = pgdat->kswapd_max_order; new_order = pgdat->kswapd_max_order;

View file

@ -138,7 +138,7 @@ static int rxrpc_krxiod(void *arg)
_debug("### End Work"); _debug("### End Work");
try_to_freeze(PF_FREEZE); try_to_freeze();
/* discard pending signals */ /* discard pending signals */
rxrpc_discard_my_signals(); rxrpc_discard_my_signals();

View file

@ -107,7 +107,7 @@ static int rxrpc_krxsecd(void *arg)
_debug("### End Inbound Calls"); _debug("### End Inbound Calls");
try_to_freeze(PF_FREEZE); try_to_freeze();
/* discard pending signals */ /* discard pending signals */
rxrpc_discard_my_signals(); rxrpc_discard_my_signals();

View file

@ -90,7 +90,7 @@ static int krxtimod(void *arg)
complete_and_exit(&krxtimod_dead, 0); complete_and_exit(&krxtimod_dead, 0);
} }
try_to_freeze(PF_FREEZE); try_to_freeze();
/* discard pending signals */ /* discard pending signals */
rxrpc_discard_my_signals(); rxrpc_discard_my_signals();

View file

@ -1185,8 +1185,8 @@ svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout)
arg->page_len = (pages-2)*PAGE_SIZE; arg->page_len = (pages-2)*PAGE_SIZE;
arg->len = (pages-1)*PAGE_SIZE; arg->len = (pages-1)*PAGE_SIZE;
arg->tail[0].iov_len = 0; arg->tail[0].iov_len = 0;
try_to_freeze(PF_FREEZE); try_to_freeze();
if (signalled()) if (signalled())
return -EINTR; return -EINTR;
@ -1227,7 +1227,7 @@ svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout)
schedule_timeout(timeout); schedule_timeout(timeout);
try_to_freeze(PF_FREEZE); try_to_freeze();
spin_lock_bh(&serv->sv_lock); spin_lock_bh(&serv->sv_lock);
remove_wait_queue(&rqstp->rq_wait, &wait); remove_wait_queue(&rqstp->rq_wait, &wait);