[PATCH 2/4] Task notifier: Implement todo list in task_struct

From: Christoph Lameter
Date: Thu Jul 28 2005 - 15:02:28 EST


Introduce a todo notifier in the task_struct so that a task can be told to do
certain things. Abuse the suspend hooks try_to_freeze, freezing and refrigerator
to establish checkpoints where the todo list is processed. This will break software
suspend (next patch fixes and cleans up software suspend).

Signed-off-by: Christoph Lameter <christoph@xxxxxxxxxxx>

Index: linux-2.6.13-rc3/include/linux/sched.h
===================================================================
--- linux-2.6.13-rc3.orig/include/linux/sched.h 2005-07-12 21:46:46.000000000 -0700
+++ linux-2.6.13-rc3/include/linux/sched.h 2005-07-28 11:54:40.000000000 -0700
@@ -34,6 +34,7 @@
#include <linux/percpu.h>
#include <linux/topology.h>
#include <linux/seccomp.h>
+#include <linux/notifier.h>

struct exec_domain;

@@ -720,7 +721,10 @@
int (*notifier)(void *priv);
void *notifier_data;
sigset_t *notifier_mask;
-
+
+ /* todo list to be executed in the context of this thread */
+ struct notifier_block *todo;
+
void *security;
struct audit_context *audit_context;
seccomp_t seccomp;
@@ -1273,79 +1275,37 @@

#endif

-#ifdef CONFIG_PM
/*
- * Check if a process has been frozen
+ * Check if there is a todo list request
*/
-static inline int frozen(struct task_struct *p)
+static inline int todo_list_active(void)
{
- return p->flags & PF_FROZEN;
+ return current->todo != NULL;
}

-/*
- * Check if there is a request to freeze a process
- */
-static inline int freezing(struct task_struct *p)
+static inline void run_todo_list(void)
{
- return p->flags & PF_FREEZE;
+ notifier_call_chain(&current->todo, 0, current);
}

-/*
- * Request that a process be frozen
- * FIXME: SMP problem. We may not modify other process' flags!
- */
-static inline void freeze(struct task_struct *p)
+static inline int try_todo_list(void)
{
- 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 void thaw_processes(void);
-
-static inline int try_to_freeze(void)
-{
- if (freezing(current)) {
- refrigerator();
+ if (todo_list_active()) {
+ run_todo_list();
return 1;
} else
return 0;
}
-#else
-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 void thaw_processes(void) {}

-static inline int try_to_freeze(void) { return 0; }
+/*
+ * Compatibility definitions to use the suspend checkpoints for the task todo list.
+ * These may be removed once all uses of try_to_free, refrigerator and freezing
+ * have been removed.
+ */
+#define try_to_freeze try_todo_list
+#define refrigerator run_todo_list
+#define freezing(p) todo_list_active()

-#endif /* CONFIG_PM */
#endif /* __KERNEL__ */

#endif
Index: linux-2.6.13-rc3/kernel/signal.c
===================================================================
--- linux-2.6.13-rc3.orig/kernel/signal.c 2005-07-12 21:46:46.000000000 -0700
+++ linux-2.6.13-rc3/kernel/signal.c 2005-07-28 10:46:49.000000000 -0700
@@ -213,7 +213,7 @@
fastcall void recalc_sigpending_tsk(struct task_struct *t)
{
if (t->signal->group_stop_count > 0 ||
- (freezing(t)) ||
+ (t->todo) ||
PENDING(&t->pending, &t->blocked) ||
PENDING(&t->signal->shared_pending, &t->blocked))
set_tsk_thread_flag(t, TIF_SIGPENDING);
@@ -2231,7 +2231,7 @@
current->state = TASK_INTERRUPTIBLE;
timeout = schedule_timeout(timeout);

- try_to_freeze();
+ try_todo_list();
spin_lock_irq(&current->sighand->siglock);
sig = dequeue_signal(current, &these, &info);
current->blocked = current->real_blocked;
Index: linux-2.6.13-rc3/arch/frv/kernel/signal.c
===================================================================
--- linux-2.6.13-rc3.orig/arch/frv/kernel/signal.c 2005-07-12 21:46:46.000000000 -0700
+++ linux-2.6.13-rc3/arch/frv/kernel/signal.c 2005-07-28 10:46:49.000000000 -0700
@@ -536,7 +536,7 @@
if (!user_mode(regs))
return 1;

- if (try_to_freeze())
+ if (try_todo_list())
goto no_signal;

if (!oldset)
Index: linux-2.6.13-rc3/arch/h8300/kernel/signal.c
===================================================================
--- linux-2.6.13-rc3.orig/arch/h8300/kernel/signal.c 2005-07-12 21:46:46.000000000 -0700
+++ linux-2.6.13-rc3/arch/h8300/kernel/signal.c 2005-07-28 10:46:49.000000000 -0700
@@ -517,7 +517,7 @@
if ((regs->ccr & 0x10))
return 1;

- if (try_to_freeze())
+ if (try_todo_list())
goto no_signal;

current->thread.esp0 = (unsigned long) regs;
Index: linux-2.6.13-rc3/arch/i386/kernel/io_apic.c
===================================================================
--- linux-2.6.13-rc3.orig/arch/i386/kernel/io_apic.c 2005-07-12 21:46:46.000000000 -0700
+++ linux-2.6.13-rc3/arch/i386/kernel/io_apic.c 2005-07-28 10:46:49.000000000 -0700
@@ -574,7 +574,7 @@
for ( ; ; ) {
set_current_state(TASK_INTERRUPTIBLE);
time_remaining = schedule_timeout(time_remaining);
- try_to_freeze();
+ try_todo_list();
if (time_after(jiffies,
prev_balance_time+balanced_irq_interval)) {
preempt_disable();
Index: linux-2.6.13-rc3/arch/i386/kernel/signal.c
===================================================================
--- linux-2.6.13-rc3.orig/arch/i386/kernel/signal.c 2005-07-12 21:46:46.000000000 -0700
+++ linux-2.6.13-rc3/arch/i386/kernel/signal.c 2005-07-28 10:46:49.000000000 -0700
@@ -608,7 +608,7 @@
if (!user_mode(regs))
return 1;

- if (try_to_freeze())
+ if (try_todo_list())
goto no_signal;

if (!oldset)
Index: linux-2.6.13-rc3/arch/m32r/kernel/signal.c
===================================================================
--- linux-2.6.13-rc3.orig/arch/m32r/kernel/signal.c 2005-07-12 21:46:46.000000000 -0700
+++ linux-2.6.13-rc3/arch/m32r/kernel/signal.c 2005-07-28 10:46:49.000000000 -0700
@@ -371,7 +371,7 @@
if (!user_mode(regs))
return 1;

- if (try_to_freeze())
+ if (try_todo_list())
goto no_signal;

if (!oldset)
Index: linux-2.6.13-rc3/arch/ppc/kernel/signal.c
===================================================================
--- linux-2.6.13-rc3.orig/arch/ppc/kernel/signal.c 2005-07-12 21:46:46.000000000 -0700
+++ linux-2.6.13-rc3/arch/ppc/kernel/signal.c 2005-07-28 10:46:49.000000000 -0700
@@ -705,7 +705,7 @@
unsigned long frame, newsp;
int signr, ret;

- if (try_to_freeze()) {
+ if (try_todo_list()) {
signr = 0;
if (!signal_pending(current))
goto no_signal;
Index: linux-2.6.13-rc3/arch/x86_64/kernel/signal.c
===================================================================
--- linux-2.6.13-rc3.orig/arch/x86_64/kernel/signal.c 2005-07-12 21:46:46.000000000 -0700
+++ linux-2.6.13-rc3/arch/x86_64/kernel/signal.c 2005-07-28 10:46:49.000000000 -0700
@@ -425,7 +425,7 @@
if (!user_mode(regs))
return 1;

- if (try_to_freeze())
+ if (try_todo_list())
goto no_signal;

if (!oldset)


-
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/