Re: [PATCH -mm] Allow selective freezing of the system for different events

From: Rafael J. Wysocki
Date: Sun Apr 29 2007 - 13:47:44 EST


Hi,

Sorry for the delay.

On Saturday, 28 April 2007 03:34, Gautham R Shenoy wrote:
> This patch
> * Provides an interface to selectively freeze the system for different events.
> * Allows tasks to exempt themselves or other tasks from specific freeze
> events.
> * Allow nesting of freezer calls. For eg:
>
> freeze_processes(EVENT_A);
> /* Do something with respect to event A */
> .
> .
> .
> freeze_processes(EVENT_B);
> /* Do something with respect to event B */
> .
> .
> .
> thaw_processes(EVENT_B);
> .
> .
> .
> thaw_processes(EVENT_B);
>
> This type of behaviour would be required when cpu hotplug would start
> using the process freezer, where EVENT_A would be SUSPEND and EVENT_B
> would be HOTPLUG_CPU.
>
> This patch applies on the top of 2.6.21-rc7-mm2 + Rafael's freezer
> changes from http://lkml.org/lkml/2007/4/27/302.
>
> Signed-off-by: Gautham R Shenoy <ego@xxxxxxxxxx>
> ---
> arch/i386/kernel/apm.c | 2 -
> drivers/block/loop.c | 2 -
> drivers/char/apm-emulation.c | 6 +--
> drivers/ieee1394/ieee1394_core.c | 2 -
> drivers/md/md.c | 2 -
> drivers/mmc/card/queue.c | 2 -
> drivers/mtd/mtd_blkdevs.c | 2 -
> drivers/scsi/libsas/sas_scsi_host.c | 2 -
> drivers/scsi/scsi_error.c | 2 -
> drivers/usb/storage/usb.c | 2 -
> include/linux/freezer.h | 44 +++++++++++++++++++-----
> kernel/freezer.c | 64 ++++++++++++++++++++++++++++++------
> kernel/kprobes.c | 4 +-
> kernel/kthread.c | 2 -
> kernel/power/disk.c | 4 +-
> kernel/power/main.c | 8 ++--
> kernel/power/user.c | 6 +--
> kernel/rcutorture.c | 4 +-
> kernel/sched.c | 2 -
> kernel/softirq.c | 2 -
> kernel/softlockup.c | 2 -
> kernel/workqueue.c | 2 -
> 22 files changed, 119 insertions(+), 49 deletions(-)
>
> Index: linux-2.6.21-rc7/include/linux/freezer.h
> ===================================================================
> --- linux-2.6.21-rc7.orig/include/linux/freezer.h
> +++ linux-2.6.21-rc7/include/linux/freezer.h
> @@ -4,17 +4,27 @@
>
> #ifdef CONFIG_FREEZER
>
> +
> /*
> * Per task flags used by the freezer
> *
> * They should not be referred to directly outside of this file.
> */
> -#define TFF_NOFREEZE 0 /* task should not be frozen */
> +#define TFF_FE_SUSPEND 0 /* Do not freeze task for software suspend */
> +#define TFF_FE_KPROBES 1 /* Do not freeze task for kprobes */
> #define TFF_FREEZE 8 /* task should go to the refrigerator ASAP */
> #define TFF_SKIP 9 /* do not count this task as freezable */
> #define TFF_FROZEN 10 /* task is frozen */
>
> /*
> + * Codes of different events which use the freezer
> + * These are the only flags that can be referred outside this file
> + */
> +#define FE_SUSPEND (1 << TFF_FE_SUSPEND) /* Software Suspend */
> +#define FE_KPROBES (1 << TFF_FE_KPROBES) /* Kprobes */
> +#define FE_ALL (FE_SUSPEND | FE_KPROBES) /* All events using freezer */
> +
> +/*
> * Check if a process has been frozen
> */
> static inline int frozen(struct task_struct *p)
> @@ -57,19 +67,29 @@ static inline void clear_freeze_flag(str
> }
>
> /*
> - * Check if the task wants to be exempted from freezing
> + * Check if the task wants to be exempted from freezing for
> + * freeze_event.
> */
> -static inline int freezer_should_exempt(struct task_struct *p)
> +static inline int freezer_should_exempt(struct task_struct *p,
> + unsigned long freeze_event)
> {
> - return test_bit(TFF_NOFREEZE, &p->freezer_flags);
> + return p->freezer_flags & freeze_event;
> }
>
> /*
> * Tell the freezer to exempt this task from freezing
> + * for events in freeze_event_mask.
> */
> -static inline void freezer_exempt(struct task_struct *p)

I, personally, would introduce

static inline void freezer_exempt_event(struct task_struct *p,
unsigned long freeze_event_mask)
{
atomic_set_mask(freeze_event_mask, &p->freezer_flags);
}

and then

static inline void freezer_exempt(struct task_struct *p)
{
freezer_exempt_event(p, FE_ALL);
}

The patch would be shorter. ;-)

[In that case I'd probably rename freezer_should_exempt() to
freezer_should_exempt_event(), for symmetry.]

> +static inline void freezer_exempt(struct task_struct *p,
> + unsigned long freeze_event_mask)
> +{
> + atomic_set_mask(freeze_event_mask, &p->freezer_flags);
> +}
> +
> +/* Returns the mask of the events for which this process is freezeable */
> +static inline unsigned long freezeable_event_mask(struct task_struct *p)
> {
> - set_bit(TFF_NOFREEZE, &p->freezer_flags);
> + return ~p->freezer_flags & FE_ALL;
> }
>
> /*
> @@ -96,8 +116,8 @@ static inline int thaw_process(struct ta
> }
>
> extern void refrigerator(void);
> -extern int freeze_processes(void);
> -extern void thaw_processes(void);
> +extern int freeze_processes(unsigned long freeze_event);
> +extern void thaw_processes(unsigned long freeze_event);
>
> static inline int try_to_freeze(void)
> {
> @@ -160,11 +180,15 @@ static inline int freezing(struct task_s
> static inline void freeze(struct task_struct *p) { BUG(); }
> static inline int freezer_should_exempt(struct task_struct *p) { return 0; }
> static inline void freezer_exempt(struct task_struct *p) {}
> +static inline unsigned long freezeable_event_mask(struct task_struct *p)
> +{
> + return 0;
> +}
> static inline int thaw_process(struct task_struct *p) { return 1; }
>
> static inline void refrigerator(void) {}
> -static inline int freeze_processes(void) { BUG(); return 0; }
> -static inline void thaw_processes(void) {}
> +static inline int freeze_processes(unsigned long) { BUG(); return 0; }
> +static inline void thaw_processes(unsigned long) {}
>
> static inline int try_to_freeze(void) { return 0; }
>
> Index: linux-2.6.21-rc7/kernel/freezer.c
> ===================================================================
> --- linux-2.6.21-rc7.orig/kernel/freezer.c
> +++ linux-2.6.21-rc7/kernel/freezer.c
> @@ -23,21 +23,44 @@
> #define FREEZER_KERNEL_THREADS 0
> #define FREEZER_USER_SPACE 1
>
> +static DEFINE_MUTEX(freezer_mutex);
> +/* Mask of the events for which the system is currently frozen */
> +unsigned long system_frozen_event_mask;
> +/* The event for which the freeze request has been raised */
> +unsigned long current_freezer_event;
> +
> static inline int freezeable(struct task_struct * p)
> {
> if ((p == current) ||
> - freezer_should_exempt(p) ||
> + freezer_should_exempt(p, current_freezer_event) ||
> (p->exit_state != 0))
> return 0;
> return 1;
> }
>
> +/* Returns the mask of events for which p is currently frozen */
> +static inline unsigned long process_frozen_event_mask(struct task_struct *p)
> +{
> + return (freezeable_event_mask(p) & system_frozen_event_mask);
> +}
> +
> +static inline int thawable(struct task_struct *p)
> +{
> + if (!freezeable(p))
> + return 0;
> +
> + /* Thaw p iff it is frozen for current_freezer_event alone */
> + if (process_frozen_event_mask(p) & ~current_freezer_event)
> + return 0;
> +
> + return 1;

I would do

return !(process_frozen_event_mask(p) & ~current_freezer_event);

> +}
> /*
> * freezing is complete, mark current process as frozen
> */
> static inline void frozen_process(void)
> {
> - if (!unlikely(freezer_should_exempt(current))) {
> + if (!unlikely(freezer_should_exempt(current, current_freezer_event))) {
> set_frozen_flag(current);
> wmb();
> }
> @@ -185,26 +208,39 @@ static unsigned int try_to_freeze_tasks(
> /**
> * freeze_processes - tell processes to enter the refrigerator
> *
> + * @freeze_event : Event that's requesting the services
> + * of the process freezer to freeze the system
> + *
> * Returns 0 on success, or the number of processes that didn't freeze,
> * although they were told to.
> */
> -int freeze_processes(void)
> +int freeze_processes(unsigned long freeze_event)
> {
> - unsigned int nr_unfrozen;
> + unsigned int nr_unfrozen = 0;
> +
> + mutex_lock(&freezer_mutex);
> + if (system_frozen_event_mask & freeze_event)
> + goto out;
> +
> + current_freezer_event = freeze_event;
>
> printk("Stopping tasks ... ");
> nr_unfrozen = try_to_freeze_tasks(FREEZER_USER_SPACE);
> if (nr_unfrozen)
> - return nr_unfrozen;
> + goto out;
>
> sys_sync();
> nr_unfrozen = try_to_freeze_tasks(FREEZER_KERNEL_THREADS);
> if (nr_unfrozen)
> - return nr_unfrozen;
> + goto out;
>
> + system_frozen_event_mask |= current_freezer_event;
> printk("done.\n");
> BUG_ON(in_atomic());

The BUG_ON() is still valid if tasks are already frozen for this event.

> - return 0;
> +out:
> + current_freezer_event = 0;
> + mutex_unlock(&freezer_mutex);
> + return nr_unfrozen;
> }
>
> static void thaw_tasks(int thaw_user_space)
> @@ -213,7 +249,7 @@ static void thaw_tasks(int thaw_user_spa
>
> read_lock(&tasklist_lock);
> do_each_thread(g, p) {
> - if (!freezeable(p))
> + if (!thawable(p))
> continue;
>
> if (is_user_space(p) == !thaw_user_space)
> @@ -224,13 +260,23 @@ static void thaw_tasks(int thaw_user_spa
> read_unlock(&tasklist_lock);
> }
>
> -void thaw_processes(void)
> +void thaw_processes(unsigned long thaw_event)
> {
> + mutex_lock(&freezer_mutex);
> + if (!(system_frozen_event_mask & thaw_event)) {
> + WARN_ON(1);

Hmm, I wouldn't use the WARN_ON() here. There's nothing wrong in calling
this twice in a row as long as we do the sanity checking. There's even one
case in which that may be convenient, actually.

> + goto out;
> + }
> + current_freezer_event = thaw_event;
> printk("Restarting tasks ... ");
> thaw_tasks(FREEZER_KERNEL_THREADS);
> thaw_tasks(FREEZER_USER_SPACE);
> + system_frozen_event_mask &= ~current_freezer_event;
> schedule();
> printk("done.\n");
> +out:
> + current_freezer_event = 0;
> + mutex_unlock(&freezer_mutex);
> }
>
> EXPORT_SYMBOL(refrigerator);
> Index: linux-2.6.21-rc7/arch/i386/kernel/apm.c
> ===================================================================
> --- linux-2.6.21-rc7.orig/arch/i386/kernel/apm.c
> +++ linux-2.6.21-rc7/arch/i386/kernel/apm.c
> @@ -2313,7 +2313,7 @@ static int __init apm_init(void)
> remove_proc_entry("apm", NULL);
> return err;
> }
> - freezer_exempt(kapmd_task);
> + freezer_exempt(kapmd_task, FE_ALL);
> wake_up_process(kapmd_task);
>
> if (num_online_cpus() > 1 && !smp ) {
> Index: linux-2.6.21-rc7/drivers/block/loop.c
> ===================================================================
> --- linux-2.6.21-rc7.orig/drivers/block/loop.c
> +++ linux-2.6.21-rc7/drivers/block/loop.c
> @@ -582,7 +582,7 @@ static int loop_thread(void *data)
> * hence, it mustn't be stopped at all
> * because it could be indirectly used during suspension
> */
> - freezer_exempt(current);
> + freezer_exempt(current, FE_ALL);
>
> set_user_nice(current, -20);
>
> Index: linux-2.6.21-rc7/drivers/char/apm-emulation.c
> ===================================================================
> --- linux-2.6.21-rc7.orig/drivers/char/apm-emulation.c
> +++ linux-2.6.21-rc7/drivers/char/apm-emulation.c
> @@ -336,7 +336,7 @@ apm_ioctl(struct inode * inode, struct f
> * threads.
> */
> flags = current->flags;
> - freezer_exempt(current);
> + freezer_exempt(current, FE_ALL);
>
> wait_event(apm_suspend_waitqueue,
> as->suspend_state == SUSPEND_DONE);
> @@ -372,7 +372,7 @@ apm_ioctl(struct inode * inode, struct f
> * threads.
> */
> flags = current->flags;
> - freezer_exempt(current);
> + freezer_exempt(current, FE_ALL);
>
> wait_event_interruptible(apm_suspend_waitqueue,
> as->suspend_state == SUSPEND_DONE);
> @@ -601,7 +601,7 @@ static int __init apm_init(void)
> kapmd_tsk = NULL;
> return ret;
> }
> - freezer_exempt(kapmd_tsk);
> + freezer_exempt(kapmd_tsk, FE_ALL);
> wake_up_process(kapmd_tsk);
>
> #ifdef CONFIG_PROC_FS
> Index: linux-2.6.21-rc7/drivers/ieee1394/ieee1394_core.c
> ===================================================================
> --- linux-2.6.21-rc7.orig/drivers/ieee1394/ieee1394_core.c
> +++ linux-2.6.21-rc7/drivers/ieee1394/ieee1394_core.c
> @@ -1134,7 +1134,7 @@ static int hpsbpkt_thread(void *__hi)
> struct list_head tmp;
> int may_schedule;
>
> - freezer_exempt(current);
> + freezer_exempt(current, FE_ALL);
>
> while (!kthread_should_stop()) {
>
> Index: linux-2.6.21-rc7/drivers/md/md.c
> ===================================================================
> --- linux-2.6.21-rc7.orig/drivers/md/md.c
> +++ linux-2.6.21-rc7/drivers/md/md.c
> @@ -4541,7 +4541,7 @@ static int md_thread(void * arg)
> * many dirty RAID5 blocks.
> */
>
> - freezer_exempt(current);
> + freezer_exempt(current, FE_ALL);
> while (!kthread_should_stop()) {
>
> /* We need to wait INTERRUPTIBLE so that
> Index: linux-2.6.21-rc7/drivers/mmc/card/queue.c
> ===================================================================
> --- linux-2.6.21-rc7.orig/drivers/mmc/card/queue.c
> +++ linux-2.6.21-rc7/drivers/mmc/card/queue.c
> @@ -67,7 +67,7 @@ static int mmc_queue_thread(void *d)
> * the process freezing. We handle suspension ourselves.
> */
> current->flags |= PF_MEMALLOC;
> - freezer_exempt(current);
> + freezer_exempt(current, FE_ALL);
>
> down(&mq->thread_sem);
> do {
> Index: linux-2.6.21-rc7/drivers/mtd/mtd_blkdevs.c
> ===================================================================
> --- linux-2.6.21-rc7.orig/drivers/mtd/mtd_blkdevs.c
> +++ linux-2.6.21-rc7/drivers/mtd/mtd_blkdevs.c
> @@ -82,7 +82,7 @@ static int mtd_blktrans_thread(void *arg
>
> /* we might get involved when memory gets low, so use PF_MEMALLOC */
> current->flags |= PF_MEMALLOC;
> - freezer_exempt(current);
> + freezer_exempt(current, FE_ALL);
>
> spin_lock_irq(rq->queue_lock);
> while (!kthread_should_stop()) {
> Index: linux-2.6.21-rc7/drivers/scsi/libsas/sas_scsi_host.c
> ===================================================================
> --- linux-2.6.21-rc7.orig/drivers/scsi/libsas/sas_scsi_host.c
> +++ linux-2.6.21-rc7/drivers/scsi/libsas/sas_scsi_host.c
> @@ -871,7 +871,7 @@ static int sas_queue_thread(void *_sas_h
> struct sas_ha_struct *sas_ha = _sas_ha;
> struct scsi_core *core = &sas_ha->core;
>
> - freezer_exempt(current);
> + freezer_exempt(current, FE_ALL);
>
> complete(&queue_th_comp);
>
> Index: linux-2.6.21-rc7/drivers/scsi/scsi_error.c
> ===================================================================
> --- linux-2.6.21-rc7.orig/drivers/scsi/scsi_error.c
> +++ linux-2.6.21-rc7/drivers/scsi/scsi_error.c
> @@ -1536,7 +1536,7 @@ int scsi_error_handler(void *data)
> {
> struct Scsi_Host *shost = data;
>
> - freezer_exempt(current);
> + freezer_exempt(current, FE_ALL);
>
> /*
> * We use TASK_INTERRUPTIBLE so that the thread is not
> Index: linux-2.6.21-rc7/drivers/usb/storage/usb.c
> ===================================================================
> --- linux-2.6.21-rc7.orig/drivers/usb/storage/usb.c
> +++ linux-2.6.21-rc7/drivers/usb/storage/usb.c
> @@ -301,7 +301,7 @@ static int usb_stor_control_thread(void
> struct us_data *us = (struct us_data *)__us;
> struct Scsi_Host *host = us_to_host(us);
>
> - freezer_exempt(current);
> + freezer_exempt(current, FE_ALL);
>
> for(;;) {
> try_to_freeze();
> Index: linux-2.6.21-rc7/kernel/kthread.c
> ===================================================================
> --- linux-2.6.21-rc7.orig/kernel/kthread.c
> +++ linux-2.6.21-rc7/kernel/kthread.c
> @@ -233,7 +233,7 @@ int kthreadd(void *unused)
> /* Setup a clean context for our children to inherit. */
> kthreadd_setup();
>
> - freezer_exempt(current);
> + freezer_exempt(current, FE_ALL);
>
> for (;;) {
> set_current_state(TASK_INTERRUPTIBLE);
> Index: linux-2.6.21-rc7/kernel/rcutorture.c
> ===================================================================
> --- linux-2.6.21-rc7.orig/kernel/rcutorture.c
> +++ linux-2.6.21-rc7/kernel/rcutorture.c
> @@ -559,7 +559,7 @@ rcu_torture_fakewriter(void *arg)
>
> VERBOSE_PRINTK_STRING("rcu_torture_fakewriter task started");
> set_user_nice(current, 19);
> - freezer_exempt(current);
> + freezer_exempt(current, FE_ALL);
>
> do {
> schedule_timeout_uninterruptible(1 + rcu_random(&rand)%10);
> @@ -590,7 +590,7 @@ rcu_torture_reader(void *arg)
>
> VERBOSE_PRINTK_STRING("rcu_torture_reader task started");
> set_user_nice(current, 19);
> - freezer_exempt(current);
> + freezer_exempt(current, FE_ALL);
>
> do {
> idx = cur_ops->readlock();
> Index: linux-2.6.21-rc7/kernel/sched.c
> ===================================================================
> --- linux-2.6.21-rc7.orig/kernel/sched.c
> +++ linux-2.6.21-rc7/kernel/sched.c
> @@ -5478,7 +5478,7 @@ migration_call(struct notifier_block *nf
> p = kthread_create(migration_thread, hcpu, "migration/%d",cpu);
> if (IS_ERR(p))
> return NOTIFY_BAD;
> - freezer_exempt(p);
> + freezer_exempt(p, FE_ALL);
> kthread_bind(p, cpu);
> /* Must be high prio: stop_machine expects to yield to it. */
> rq = task_rq_lock(p, &flags);
> Index: linux-2.6.21-rc7/kernel/softirq.c
> ===================================================================
> --- linux-2.6.21-rc7.orig/kernel/softirq.c
> +++ linux-2.6.21-rc7/kernel/softirq.c
> @@ -490,7 +490,7 @@ void __init softirq_init(void)
> static int ksoftirqd(void * __bind_cpu)
> {
> set_user_nice(current, 15);
> - freezer_exempt(current);
> + freezer_exempt(current, FE_ALL);
>
> set_current_state(TASK_INTERRUPTIBLE);
>
> Index: linux-2.6.21-rc7/kernel/softlockup.c
> ===================================================================
> --- linux-2.6.21-rc7.orig/kernel/softlockup.c
> +++ linux-2.6.21-rc7/kernel/softlockup.c
> @@ -117,7 +117,7 @@ static int watchdog(void * __bind_cpu)
> struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
>
> sched_setscheduler(current, SCHED_FIFO, &param);
> - freezer_exempt(current);
> + freezer_exempt(current, FE_ALL);
>
> /* initialize timestamp */
> touch_softlockup_watchdog();
> Index: linux-2.6.21-rc7/kernel/workqueue.c
> ===================================================================
> --- linux-2.6.21-rc7.orig/kernel/workqueue.c
> +++ linux-2.6.21-rc7/kernel/workqueue.c
> @@ -291,7 +291,7 @@ static int worker_thread(void *__cwq)
> DEFINE_WAIT(wait);
>
> if (!cwq->wq->freezeable)
> - freezer_exempt(current);
> + freezer_exempt(current, FE_ALL);
>
> for (;;) {
> prepare_to_wait(&cwq->more_work, &wait, TASK_INTERRUPTIBLE);
> Index: linux-2.6.21-rc7/kernel/kprobes.c
> ===================================================================
> --- linux-2.6.21-rc7.orig/kernel/kprobes.c
> +++ linux-2.6.21-rc7/kernel/kprobes.c
> @@ -109,7 +109,7 @@ static int __kprobes check_safety(void)
> {
> int ret = 0;
> #ifdef CONFIG_PREEMPT
> - ret = freeze_processes();
> + ret = freeze_processes(FE_KPROBES);
> if (ret == 0) {
> struct task_struct *p, *q;
> do_each_thread(p, q) {
> @@ -122,7 +122,7 @@ static int __kprobes check_safety(void)
> } while_each_thread(p, q);
> }
> loop_end:
> - thaw_processes();
> + thaw_processes(FE_KPROBES);
> #else
> synchronize_sched();
> #endif
> Index: linux-2.6.21-rc7/kernel/power/disk.c
> ===================================================================
> --- linux-2.6.21-rc7.orig/kernel/power/disk.c
> +++ linux-2.6.21-rc7/kernel/power/disk.c
> @@ -103,7 +103,7 @@ static inline void platform_finish(void)
>
> static void unprepare_processes(void)
> {
> - thaw_processes();
> + thaw_processes(FE_SUSPEND);
> pm_restore_console();
> }
>
> @@ -112,7 +112,7 @@ static int prepare_processes(void)
> int error = 0;
>
> pm_prepare_console();
> - if (freeze_processes()) {
> + if (freeze_processes(FE_SUSPEND)) {
> error = -EBUSY;
> unprepare_processes();
> }
> Index: linux-2.6.21-rc7/kernel/power/main.c
> ===================================================================
> --- linux-2.6.21-rc7.orig/kernel/power/main.c
> +++ linux-2.6.21-rc7/kernel/power/main.c
> @@ -90,9 +90,9 @@ static int suspend_prepare(suspend_state
> if (error)
> goto Finish;
>
> - if (freeze_processes()) {
> + if (freeze_processes(FE_SUSPEND)) {
> error = -EAGAIN;
> - thaw_processes();
> + thaw_processes(FE_SUSPEND);
> goto Finish;
> }
>
> @@ -133,7 +133,7 @@ static int suspend_prepare(suspend_state
> resume_console();
> Thaw:
> suspend_notifier_call_chain(SUSPEND_THAW_PREPARE);
> - thaw_processes();
> + thaw_processes(FE_SUSPEND);
> Finish:
> pm_restore_console();
> suspend_notifier_call_chain(SUSPEND_FINISHED);
> @@ -185,7 +185,7 @@ static void suspend_finish(suspend_state
> device_resume();
> resume_console();
> suspend_notifier_call_chain(SUSPEND_THAW_PREPARE);
> - thaw_processes();
> + thaw_processes(FE_SUSPEND);
> pm_restore_console();
> suspend_notifier_call_chain(SUSPEND_FINISHED);
> }
> Index: linux-2.6.21-rc7/kernel/power/user.c
> ===================================================================
> --- linux-2.6.21-rc7.orig/kernel/power/user.c
> +++ linux-2.6.21-rc7/kernel/power/user.c
> @@ -81,7 +81,7 @@ static void snapshot_unfreeze(struct sna
> return;
>
> mutex_lock(&pm_mutex);
> - thaw_processes();
> + thaw_processes(FE_SUSPEND);
> suspend_notifier_call_chain(SUSPEND_FINISHED);
> mutex_unlock(&pm_mutex);
> data->frozen = 0;
> @@ -257,8 +257,8 @@ static int snapshot_ioctl(struct inode *
> if (error)
> break;
>
> - if (freeze_processes()) {
> - thaw_processes();
> + if (freeze_processes(FE_SUSPEND)) {
> + thaw_processes(FE_SUSPEND);
> suspend_notifier_call_chain(SUSPEND_FINISHED);
> error = -EBUSY;
> }
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/