| From: |
| Jes Sorensen <jes@sgi.com> |
| To: |
| LSE <lse-tech@lists.sourceforge.net> |
| Subject: |
| [patch - RFC] simple task notifier support |
| Date: |
| 27 Apr 2006 10:54:53 -0400 |
| Cc: |
| Andrew Morton <akpm@osdl.org>, Christoph Hellwig <hch@lst.de> |
| Archive-link: |
| Article,
Thread
|
Hi,
Attached is the patch for the simple task notifier support that has
been discussed on lse-tech on multiple occasions (it superceeds
pnotify/pagg/task_notify). I provides a way to hook into the fork/exit
etc. places and can be used for things like task grouping and
accounting, but also to clean up all the conditional callouts we have
in the fork/exit paths. I will be posting one example in the next
email and I will be happy to do a bunch more if we can come to
agreement on this approach.
I am using the raw notifier chain to give the clients the same
sleep/blocking rules as the parents currently have. IMHO this makes
the most sense to keep the overhead at a minimum.
Comments/oppinions/flames?
Cheers,
Jes
Simple task notifier support. This uses the raw notifier chain allowing
the users the same calls to sleeping functions as are in fork() etc.
Signed-off-by: Jes Sorensen <jes@sgi.com>
----
fs/exec.c | 3 +++
include/linux/init_task.h | 2 ++
include/linux/notifier.h | 5 +++++
include/linux/sched.h | 3 +++
kernel/exit.c | 5 +++++
kernel/fork.c | 16 ++++++++++++++++
6 files changed, 34 insertions(+)
Index: linux-2.6/fs/exec.c
===================================================================
--- linux-2.6.orig/fs/exec.c
+++ linux-2.6/fs/exec.c
@@ -49,6 +49,7 @@
#include <linux/rmap.h>
#include <linux/acct.h>
#include <linux/cn_proc.h>
+#include <linux/notifier.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
@@ -1001,6 +1002,8 @@
suid_keys(current);
exec_keys(current);
+ raw_notifier_call_chain(¤t->task_notifier, TN_EXEC, NULL);
+
task_lock(current);
unsafe = unsafe_exec(current);
security_bprm_apply_creds(bprm, unsafe);
Index: linux-2.6/include/linux/init_task.h
===================================================================
--- linux-2.6.orig/include/linux/init_task.h
+++ linux-2.6/include/linux/init_task.h
@@ -3,6 +3,7 @@
#include <linux/file.h>
#include <linux/rcupdate.h>
+#include <linux/notifier.h>
#define INIT_FDTABLE \
{ \
@@ -123,6 +124,7 @@
.journal_info = NULL, \
.cpu_timers = INIT_CPU_TIMERS(tsk.cpu_timers), \
.fs_excl = ATOMIC_INIT(0), \
+ .task_notifier = RAW_NOTIFIER_INIT(tsk.task_notifier), \
}
Index: linux-2.6/include/linux/notifier.h
===================================================================
--- linux-2.6.orig/include/linux/notifier.h
+++ linux-2.6/include/linux/notifier.h
@@ -154,5 +154,10 @@
#define CPU_DOWN_FAILED 0x0006 /* CPU (unsigned)v NOT going down */
#define CPU_DEAD 0x0007 /* CPU (unsigned)v dead */
+#define TN_FORK 0x0001 /* Task notifier - fork */
+#define TN_EXIT 0x0002 /* Task notifier - exit */
+#define TN_FREE 0x0003 /* Task notifier - free */
+#define TN_EXEC 0x0004 /* Task notifier - exec */
+
#endif /* __KERNEL__ */
#endif /* _LINUX_NOTIFIER_H */
Index: linux-2.6/include/linux/sched.h
===================================================================
--- linux-2.6.orig/include/linux/sched.h
+++ linux-2.6/include/linux/sched.h
@@ -36,6 +36,7 @@
#include <linux/seccomp.h>
#include <linux/rcupdate.h>
#include <linux/futex.h>
+#include <linux/notifier.h>
#include <linux/auxvec.h> /* For AT_VECTOR_SIZE */
@@ -888,6 +889,8 @@
* cache last used pipe for splice
*/
struct pipe_inode_info *splice_pipe;
+
+ struct raw_notifier_head task_notifier;
};
static inline pid_t process_group(struct task_struct *tsk)
Index: linux-2.6/kernel/exit.c
===================================================================
--- linux-2.6.orig/kernel/exit.c
+++ linux-2.6/kernel/exit.c
@@ -34,6 +34,7 @@
#include <linux/mutex.h>
#include <linux/futex.h>
#include <linux/compat.h>
+#include <linux/notifier.h>
#include <linux/pipe_fs_i.h>
#include <asm/uaccess.h>
@@ -910,6 +911,10 @@
if (unlikely(tsk->compat_robust_list))
compat_exit_robust_list(tsk);
#endif
+ /*
+ * Must call the exit notifier before losing the mm struct
+ */
+ raw_notifier_call_chain(&tsk->task_notifier, TN_EXIT, tsk);
exit_mm(tsk);
exit_sem(tsk);
Index: linux-2.6/kernel/fork.c
===================================================================
--- linux-2.6.orig/kernel/fork.c
+++ linux-2.6/kernel/fork.c
@@ -44,6 +44,7 @@
#include <linux/rmap.h>
#include <linux/acct.h>
#include <linux/cn_proc.h>
+#include <linux/notifier.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
@@ -114,6 +115,7 @@
WARN_ON(atomic_read(&tsk->usage));
WARN_ON(tsk == current);
+ raw_notifier_call_chain(&tsk->task_notifier, TN_FREE, tsk);
if (unlikely(tsk->audit_context))
audit_free(tsk);
security_task_free(tsk);
@@ -1043,6 +1045,11 @@
if (clone_flags & CLONE_THREAD)
p->tgid = current->tgid;
+ /*
+ * Any of the below could be trying to use this
+ */
+ RAW_INIT_NOTIFIER_HEAD(&p->task_notifier);
+
if ((retval = security_task_alloc(p)))
goto bad_fork_cleanup_policy;
if ((retval = audit_alloc(p)))
@@ -1103,6 +1110,14 @@
p->exit_state = 0;
/*
+ * Call the task notifiers for the current thread. It is their
+ * job to determine whether or not to preserve the parent's
+ * task_notifiers.
+ */
+ if (raw_notifier_call_chain(¤t->task_notifier, TN_FORK, p))
+ goto bad_fork_cleanup_namespace;
+
+ /*
* Ok, make it visible to the rest of the system.
* We dont wake it up yet.
*/
@@ -1239,6 +1254,7 @@
audit_free(p);
bad_fork_cleanup_security:
security_task_free(p);
+ raw_notifier_call_chain(&p->task_notifier, TN_EXIT, p);
bad_fork_cleanup_policy:
#ifdef CONFIG_NUMA
mpol_free(p->mempolicy);
-------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&...