From: Matt Helsley <matthltc@us.ibm.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>,
Paul Menage <menage@google.com>, Li Zefan <lizf@cn.fujitsu.com>,
Linux-Kernel <linux-kernel@vger.kernel.org>,
Linux Containers <containers@lists.linux-foundation.org>,
linux-pm@lists.linux-foundation.org,
Cedric Le Goater <clg@fr.ibm.com>,
"Serge E. Hallyn" <serue@us.ibm.com>
Subject: [PATCH 2/6] Container Freezer: Make refrigerator always available
Date: Thu, 31 Jul 2008 22:07:01 -0700 [thread overview]
Message-ID: <20080801050700.528446138@us.ibm.com> (raw)
In-Reply-To: 20080801050659.924495279@us.ibm.com
Now that the TIF_FREEZE flag is available in all architectures,
extract the refrigerator() and freeze_task() from kernel/power/process.c
and make it available to all.
The refrigerator() can now be used in a control group subsystem
implementing a control group freezer.
Signed-off-by: Cedric Le Goater <clg@fr.ibm.com>
Signed-off-by: Matt Helsley <matthltc@us.ibm.com>
Acked-by: Serge E. Hallyn <serue@us.ibm.com>
Tested-by: Matt Helsley <matthltc@us.ibm.com>
---
include/linux/freezer.h | 24 +++++----
kernel/Makefile | 2 +-
kernel/freezer.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++
kernel/power/process.c | 116 --------------------------------------------
4 files changed, 136 insertions(+), 128 deletions(-)
create mode 100644 kernel/freezer.c
diff --git a/include/linux/freezer.h b/include/linux/freezer.h
index deddeed..4081768 100644
--- a/include/linux/freezer.h
+++ b/include/linux/freezer.h
@@ -6,7 +6,6 @@
#include <linux/sched.h>
#include <linux/wait.h>
-#ifdef CONFIG_PM_SLEEP
/*
* Check if a process has been frozen
*/
@@ -39,6 +38,11 @@ static inline void clear_freeze_flag(struct task_struct *p)
clear_tsk_thread_flag(p, TIF_FREEZE);
}
+static inline bool should_send_signal(struct task_struct *p)
+{
+ return !(p->flags & PF_FREEZER_NOSIG);
+}
+
/*
* Wake up a frozen process
*
@@ -63,8 +67,6 @@ static inline int thaw_process(struct task_struct *p)
}
extern void refrigerator(void);
-extern int freeze_processes(void);
-extern void thaw_processes(void);
static inline int try_to_freeze(void)
{
@@ -75,6 +77,14 @@ static inline int try_to_freeze(void)
return 0;
}
+extern bool freeze_task(struct task_struct *p, bool sig_only);
+extern void cancel_freezing(struct task_struct *p);
+
+#ifdef CONFIG_PM_SLEEP
+
+extern int freeze_processes(void);
+extern void thaw_processes(void);
+
/*
* The PF_FREEZER_SKIP flag should be set by a vfork parent right before it
* calls wait_for_completion(&vfork) and reset right after it returns from this
@@ -167,18 +177,10 @@ static inline void set_freezable_with_signal(void)
__retval; \
})
#else /* !CONFIG_PM_SLEEP */
-static inline int frozen(struct task_struct *p) { return 0; }
-static inline int freezing(struct task_struct *p) { return 0; }
-static inline void set_freeze_flag(struct task_struct *p) {}
-static inline void clear_freeze_flag(struct task_struct *p) {}
-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 try_to_freeze(void) { return 0; }
-
static inline void freezer_do_not_count(void) {}
static inline void freezer_count(void) {}
static inline int freezer_should_skip(struct task_struct *p) { return 0; }
diff --git a/kernel/Makefile b/kernel/Makefile
index 4e1d7df..9844f47 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -5,7 +5,7 @@
obj-y = sched.o fork.o exec_domain.o panic.o printk.o \
cpu.o exit.o itimer.o time.o softirq.o resource.o \
sysctl.o capability.o ptrace.o timer.o user.o \
- signal.o sys.o kmod.o workqueue.o pid.o \
+ signal.o sys.o kmod.o workqueue.o pid.o freezer.o \
rcupdate.o extable.o params.o posix-timers.o \
kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \
diff --git a/kernel/freezer.c b/kernel/freezer.c
new file mode 100644
index 0000000..cb0931f
--- /dev/null
+++ b/kernel/freezer.c
@@ -0,0 +1,122 @@
+/*
+ * kernel/freezer.c - Function to freeze a process
+ *
+ * Originally from kernel/power/process.c
+ */
+
+#include <linux/interrupt.h>
+#include <linux/suspend.h>
+#include <linux/module.h>
+#include <linux/syscalls.h>
+#include <linux/freezer.h>
+
+/*
+ * freezing is complete, mark current process as frozen
+ */
+static inline void frozen_process(void)
+{
+ if (!unlikely(current->flags & PF_NOFREEZE)) {
+ current->flags |= PF_FROZEN;
+ wmb();
+ }
+ clear_freeze_flag(current);
+}
+
+/* Refrigerator is place where frozen processes are stored :-). */
+void refrigerator(void)
+{
+ /* Hmm, should we be allowed to suspend when there are realtime
+ processes around? */
+ long save;
+
+ task_lock(current);
+ if (freezing(current)) {
+ frozen_process();
+ task_unlock(current);
+ } else {
+ task_unlock(current);
+ return;
+ }
+ save = current->state;
+ pr_debug("%s entered refrigerator\n", current->comm);
+
+ spin_lock_irq(¤t->sighand->siglock);
+ recalc_sigpending(); /* We sent fake signal, clean it up */
+ spin_unlock_irq(¤t->sighand->siglock);
+
+ for (;;) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ if (!frozen(current))
+ break;
+ schedule();
+ }
+ pr_debug("%s left refrigerator\n", current->comm);
+ __set_current_state(save);
+}
+EXPORT_SYMBOL(refrigerator);
+
+static void fake_signal_wake_up(struct task_struct *p)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&p->sighand->siglock, flags);
+ signal_wake_up(p, 0);
+ spin_unlock_irqrestore(&p->sighand->siglock, flags);
+}
+
+/**
+ * freeze_task - send a freeze request to given task
+ * @p: task to send the request to
+ * @sig_only: if set, the request will only be sent if the task has the
+ * PF_FREEZER_NOSIG flag unset
+ * Return value: 'false', if @sig_only is set and the task has
+ * PF_FREEZER_NOSIG set or the task is frozen, 'true', otherwise
+ *
+ * The freeze request is sent by setting the tasks's TIF_FREEZE flag and
+ * either sending a fake signal to it or waking it up, depending on whether
+ * or not it has PF_FREEZER_NOSIG set. If @sig_only is set and the task
+ * has PF_FREEZER_NOSIG set (ie. it is a typical kernel thread), its
+ * TIF_FREEZE flag will not be set.
+ */
+bool freeze_task(struct task_struct *p, bool sig_only)
+{
+ /*
+ * We first check if the task is freezing and next if it has already
+ * been frozen to avoid the race with frozen_process() which first marks
+ * the task as frozen and next clears its TIF_FREEZE.
+ */
+ if (!freezing(p)) {
+ rmb();
+ if (frozen(p))
+ return false;
+
+ if (!sig_only || should_send_signal(p))
+ set_freeze_flag(p);
+ else
+ return false;
+ }
+
+ if (should_send_signal(p)) {
+ if (!signal_pending(p))
+ fake_signal_wake_up(p);
+ } else if (sig_only) {
+ return false;
+ } else {
+ wake_up_state(p, TASK_INTERRUPTIBLE);
+ }
+
+ return true;
+}
+
+void cancel_freezing(struct task_struct *p)
+{
+ unsigned long flags;
+
+ if (freezing(p)) {
+ pr_debug(" clean up: %s\n", p->comm);
+ clear_freeze_flag(p);
+ spin_lock_irqsave(&p->sighand->siglock, flags);
+ recalc_sigpending_and_wake(p);
+ spin_unlock_irqrestore(&p->sighand->siglock, flags);
+ }
+}
diff --git a/kernel/power/process.c b/kernel/power/process.c
index 278946a..444cea8 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -28,121 +28,6 @@ static inline int freezeable(struct task_struct * p)
return 1;
}
-/*
- * freezing is complete, mark current process as frozen
- */
-static inline void frozen_process(void)
-{
- if (!unlikely(current->flags & PF_NOFREEZE)) {
- current->flags |= PF_FROZEN;
- wmb();
- }
- clear_freeze_flag(current);
-}
-
-/* Refrigerator is place where frozen processes are stored :-). */
-void refrigerator(void)
-{
- /* Hmm, should we be allowed to suspend when there are realtime
- processes around? */
- long save;
-
- task_lock(current);
- if (freezing(current)) {
- frozen_process();
- task_unlock(current);
- } else {
- task_unlock(current);
- return;
- }
- save = current->state;
- pr_debug("%s entered refrigerator\n", current->comm);
-
- spin_lock_irq(¤t->sighand->siglock);
- recalc_sigpending(); /* We sent fake signal, clean it up */
- spin_unlock_irq(¤t->sighand->siglock);
-
- for (;;) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- if (!frozen(current))
- break;
- schedule();
- }
- pr_debug("%s left refrigerator\n", current->comm);
- __set_current_state(save);
-}
-
-static void fake_signal_wake_up(struct task_struct *p)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&p->sighand->siglock, flags);
- signal_wake_up(p, 0);
- spin_unlock_irqrestore(&p->sighand->siglock, flags);
-}
-
-static inline bool should_send_signal(struct task_struct *p)
-{
- return !(p->flags & PF_FREEZER_NOSIG);
-}
-
-/**
- * freeze_task - send a freeze request to given task
- * @p: task to send the request to
- * @sig_only: if set, the request will only be sent if the task has the
- * PF_FREEZER_NOSIG flag unset
- * Return value: 'false', if @sig_only is set and the task has
- * PF_FREEZER_NOSIG set or the task is frozen, 'true', otherwise
- *
- * The freeze request is sent by setting the tasks's TIF_FREEZE flag and
- * either sending a fake signal to it or waking it up, depending on whether
- * or not it has PF_FREEZER_NOSIG set. If @sig_only is set and the task
- * has PF_FREEZER_NOSIG set (ie. it is a typical kernel thread), its
- * TIF_FREEZE flag will not be set.
- */
-static bool freeze_task(struct task_struct *p, bool sig_only)
-{
- /*
- * We first check if the task is freezing and next if it has already
- * been frozen to avoid the race with frozen_process() which first marks
- * the task as frozen and next clears its TIF_FREEZE.
- */
- if (!freezing(p)) {
- rmb();
- if (frozen(p))
- return false;
-
- if (!sig_only || should_send_signal(p))
- set_freeze_flag(p);
- else
- return false;
- }
-
- if (should_send_signal(p)) {
- if (!signal_pending(p))
- fake_signal_wake_up(p);
- } else if (sig_only) {
- return false;
- } else {
- wake_up_state(p, TASK_INTERRUPTIBLE);
- }
-
- return true;
-}
-
-static void cancel_freezing(struct task_struct *p)
-{
- unsigned long flags;
-
- if (freezing(p)) {
- pr_debug(" clean up: %s\n", p->comm);
- clear_freeze_flag(p);
- spin_lock_irqsave(&p->sighand->siglock, flags);
- recalc_sigpending_and_wake(p);
- spin_unlock_irqrestore(&p->sighand->siglock, flags);
- }
-}
-
static int try_to_freeze_tasks(bool sig_only)
{
struct task_struct *g, *p;
@@ -264,4 +149,3 @@ void thaw_processes(void)
printk("done.\n");
}
-EXPORT_SYMBOL(refrigerator);
--
1.5.3.7
--
next prev parent reply other threads:[~2008-08-01 5:09 UTC|newest]
Thread overview: 87+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-08-01 5:06 [PATCH 0/6] Container Freezer: Reuse Suspend Freezer Matt Helsley
2008-08-01 5:06 ` Matt Helsley
2008-08-01 5:07 ` [PATCH 1/6] Container Freezer: Add TIF_FREEZE flag to all architectures Matt Helsley
[not found] ` <20080801050700.261080433-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2008-08-01 10:32 ` Nigel Cunningham
2008-08-01 10:32 ` Nigel Cunningham
2008-08-01 12:32 ` Cedric Le Goater
2008-08-01 12:32 ` Cedric Le Goater
2008-08-01 12:32 ` Cedric Le Goater
2008-08-01 22:05 ` Matt Helsley
[not found] ` <1217628325.25300.270.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2008-08-01 22:54 ` Rafael J. Wysocki
2008-08-02 1:13 ` Nigel Cunningham
2008-08-01 22:54 ` Rafael J. Wysocki
2008-08-01 22:54 ` Rafael J. Wysocki
2008-08-02 1:13 ` Nigel Cunningham
2008-08-02 1:13 ` Nigel Cunningham
[not found] ` <4893025D.9090801-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
2008-08-01 22:05 ` Matt Helsley
2008-08-01 22:05 ` Matt Helsley
2008-08-01 10:32 ` Nigel Cunningham
2008-08-01 5:07 ` Matt Helsley
2008-08-01 5:07 ` Matt Helsley
2008-08-01 5:07 ` Matt Helsley [this message]
[not found] ` <20080801050700.528446138-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2008-08-01 10:33 ` [PATCH 2/6] Container Freezer: Make refrigerator always available Nigel Cunningham
2008-08-01 14:27 ` Thomas Petazzoni
2008-08-01 10:33 ` Nigel Cunningham
2008-08-01 10:33 ` Nigel Cunningham
2008-08-01 14:27 ` Thomas Petazzoni
2008-08-01 14:27 ` Thomas Petazzoni
2008-08-01 19:08 ` Matt Helsley
2008-08-01 19:08 ` Matt Helsley
2008-08-01 19:08 ` Matt Helsley
2008-08-01 22:53 ` Rafael J. Wysocki
2008-08-01 22:53 ` Rafael J. Wysocki
2008-08-01 23:24 ` Matt Helsley
2008-08-01 23:24 ` Matt Helsley
[not found] ` <1217633074.25300.281.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2008-08-02 14:34 ` Rafael J. Wysocki
2008-08-02 14:34 ` Rafael J. Wysocki
2008-08-02 14:34 ` Rafael J. Wysocki
2008-08-02 14:34 ` Rafael J. Wysocki
2008-08-01 23:24 ` Matt Helsley
2008-08-02 2:30 ` Matt Helsley
2008-08-02 2:30 ` Matt Helsley
[not found] ` <200808020053.18638.rjw-KKrjLPT3xs0@public.gmane.org>
2008-08-01 23:24 ` Matt Helsley
2008-08-02 2:30 ` Matt Helsley
2008-08-02 2:30 ` Matt Helsley
2008-08-01 22:53 ` Rafael J. Wysocki
[not found] ` <1217617689.25300.213.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2008-08-01 22:53 ` Rafael J. Wysocki
2008-08-02 10:39 ` Thomas Petazzoni
2008-08-02 10:39 ` Thomas Petazzoni
2008-08-02 10:39 ` Thomas Petazzoni
2008-08-02 10:39 ` Thomas Petazzoni
2008-08-01 19:08 ` Matt Helsley
2008-08-01 14:27 ` Thomas Petazzoni
2008-08-01 5:07 ` Matt Helsley
2008-08-01 5:07 ` Matt Helsley
2008-08-01 5:07 ` [PATCH 3/6] Container Freezer: Implement freezer cgroup subsystem Matt Helsley
2008-08-01 5:07 ` Matt Helsley
2008-08-01 22:58 ` Rafael J. Wysocki
2008-08-02 0:11 ` Matt Helsley
[not found] ` <200808020058.37407.rjw-KKrjLPT3xs0@public.gmane.org>
2008-08-02 0:11 ` Matt Helsley
2008-08-02 0:11 ` Matt Helsley
2008-08-02 7:38 ` Cedric Le Goater
2008-08-02 14:37 ` Rafael J. Wysocki
2008-08-02 14:37 ` Rafael J. Wysocki
[not found] ` <48940F0F.4050604-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
2008-08-02 14:37 ` Rafael J. Wysocki
2008-08-02 7:38 ` Cedric Le Goater
[not found] ` <1217635891.25300.292.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2008-08-02 7:38 ` Cedric Le Goater
2008-08-01 22:58 ` Rafael J. Wysocki
[not found] ` <20080801050700.797996261-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2008-08-01 22:58 ` Rafael J. Wysocki
2008-08-01 5:07 ` Matt Helsley
2008-08-01 5:07 ` [PATCH 4/6] Container Freezer: Skip frozen cgroups during power management resume Matt Helsley
[not found] ` <20080801050701.070484831-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2008-08-01 10:24 ` Nigel Cunningham
2008-08-01 10:24 ` Nigel Cunningham
2008-08-01 10:24 ` Nigel Cunningham
2008-08-01 5:07 ` Matt Helsley
2008-08-01 5:07 ` Matt Helsley
2008-08-01 5:07 ` [PATCH 5/6] Container Freezer: Prevent frozen tasks or cgroups from changing Matt Helsley
2008-08-01 5:07 ` Matt Helsley
2008-08-01 5:07 ` Matt Helsley
2008-08-01 5:07 ` [PATCH 6/6] Container Freezer: Use cgroup write_string method Matt Helsley
2008-08-01 5:07 ` Matt Helsley
2008-08-01 5:07 ` Matt Helsley
2008-08-01 5:16 ` [PATCH 0/6] Container Freezer: Reuse Suspend Freezer Matt Helsley
2008-08-01 5:16 ` Matt Helsley
[not found] ` <1217567816.25300.197.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2008-08-01 13:04 ` Rafael J. Wysocki
2008-08-01 13:04 ` Rafael J. Wysocki
2008-08-01 13:04 ` Rafael J. Wysocki
[not found] ` <20080801050659.924495279-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2008-08-01 5:16 ` Matt Helsley
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080801050700.528446138@us.ibm.com \
--to=matthltc@us.ibm.com \
--cc=akpm@linux-foundation.org \
--cc=clg@fr.ibm.com \
--cc=containers@lists.linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@lists.linux-foundation.org \
--cc=lizf@cn.fujitsu.com \
--cc=menage@google.com \
--cc=rjw@sisk.pl \
--cc=serue@us.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.