aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorShailabh Nagar <nagar@watson.ibm.com>2006-07-14 03:24:36 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-07-15 00:53:56 -0400
commitca74e92b4698276b6696f15a801759f50944f387 (patch)
tree26f0de66d8207608e07ee22389bfc173e773c0c2 /kernel
parente8f4d97e1b58b50ad6449bb2d35e6632c0236abd (diff)
[PATCH] per-task-delay-accounting: setup
Initialization code related to collection of per-task "delay" statistics which measure how long it had to wait for cpu, sync block io, swapping etc. The collection of statistics and the interface are in other patches. This patch sets up the data structures and allows the statistics collection to be disabled through a kernel boot parameter. Signed-off-by: Shailabh Nagar <nagar@watson.ibm.com> Signed-off-by: Balbir Singh <balbir@in.ibm.com> Cc: Jes Sorensen <jes@sgi.com> Cc: Peter Chubb <peterc@gelato.unsw.edu.au> Cc: Erich Focht <efocht@ess.nec.de> Cc: Levent Serinol <lserinol@gmail.com> Cc: Jay Lan <jlan@engr.sgi.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/Makefile1
-rw-r--r--kernel/delayacct.c87
-rw-r--r--kernel/exit.c2
-rw-r--r--kernel/fork.c2
4 files changed, 92 insertions, 0 deletions
diff --git a/kernel/Makefile b/kernel/Makefile
index 47dbcd570cd8..87bb34cc8938 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
48obj-$(CONFIG_SECCOMP) += seccomp.o 48obj-$(CONFIG_SECCOMP) += seccomp.o
49obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o 49obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
50obj-$(CONFIG_RELAY) += relay.o 50obj-$(CONFIG_RELAY) += relay.o
51obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
51 52
52ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y) 53ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
53# According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is 54# According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
diff --git a/kernel/delayacct.c b/kernel/delayacct.c
new file mode 100644
index 000000000000..fbf7f2284952
--- /dev/null
+++ b/kernel/delayacct.c
@@ -0,0 +1,87 @@
1/* delayacct.c - per-task delay accounting
2 *
3 * Copyright (C) Shailabh Nagar, IBM Corp. 2006
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it would be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 */
15
16#include <linux/sched.h>
17#include <linux/slab.h>
18#include <linux/time.h>
19#include <linux/sysctl.h>
20#include <linux/delayacct.h>
21
22int delayacct_on __read_mostly; /* Delay accounting turned on/off */
23kmem_cache_t *delayacct_cache;
24
25static int __init delayacct_setup_enable(char *str)
26{
27 delayacct_on = 1;
28 return 1;
29}
30__setup("delayacct", delayacct_setup_enable);
31
32void delayacct_init(void)
33{
34 delayacct_cache = kmem_cache_create("delayacct_cache",
35 sizeof(struct task_delay_info),
36 0,
37 SLAB_PANIC,
38 NULL, NULL);
39 delayacct_tsk_init(&init_task);
40}
41
42void __delayacct_tsk_init(struct task_struct *tsk)
43{
44 tsk->delays = kmem_cache_zalloc(delayacct_cache, SLAB_KERNEL);
45 if (tsk->delays)
46 spin_lock_init(&tsk->delays->lock);
47}
48
49void __delayacct_tsk_exit(struct task_struct *tsk)
50{
51 kmem_cache_free(delayacct_cache, tsk->delays);
52 tsk->delays = NULL;
53}
54
55/*
56 * Start accounting for a delay statistic using
57 * its starting timestamp (@start)
58 */
59
60static inline void delayacct_start(struct timespec *start)
61{
62 do_posix_clock_monotonic_gettime(start);
63}
64
65/*
66 * Finish delay accounting for a statistic using
67 * its timestamps (@start, @end), accumalator (@total) and @count
68 */
69
70static void delayacct_end(struct timespec *start, struct timespec *end,
71 u64 *total, u32 *count)
72{
73 struct timespec ts;
74 s64 ns;
75
76 do_posix_clock_monotonic_gettime(end);
77 ts = timespec_sub(*end, *start);
78 ns = timespec_to_ns(&ts);
79 if (ns < 0)
80 return;
81
82 spin_lock(&current->delays->lock);
83 *total += ns;
84 (*count)++;
85 spin_unlock(&current->delays->lock);
86}
87
diff --git a/kernel/exit.c b/kernel/exit.c
index 6664c084783d..3c2cf91defa7 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -25,6 +25,7 @@
25#include <linux/mount.h> 25#include <linux/mount.h>
26#include <linux/proc_fs.h> 26#include <linux/proc_fs.h>
27#include <linux/mempolicy.h> 27#include <linux/mempolicy.h>
28#include <linux/delayacct.h>
28#include <linux/cpuset.h> 29#include <linux/cpuset.h>
29#include <linux/syscalls.h> 30#include <linux/syscalls.h>
30#include <linux/signal.h> 31#include <linux/signal.h>
@@ -900,6 +901,7 @@ fastcall NORET_TYPE void do_exit(long code)
900#endif 901#endif
901 if (unlikely(tsk->audit_context)) 902 if (unlikely(tsk->audit_context))
902 audit_free(tsk); 903 audit_free(tsk);
904 delayacct_tsk_exit(tsk);
903 exit_mm(tsk); 905 exit_mm(tsk);
904 906
905 if (group_dead) 907 if (group_dead)
diff --git a/kernel/fork.c b/kernel/fork.c
index 926e5a68ea9e..451cfd35bf22 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -43,6 +43,7 @@
43#include <linux/rmap.h> 43#include <linux/rmap.h>
44#include <linux/acct.h> 44#include <linux/acct.h>
45#include <linux/cn_proc.h> 45#include <linux/cn_proc.h>
46#include <linux/delayacct.h>
46 47
47#include <asm/pgtable.h> 48#include <asm/pgtable.h>
48#include <asm/pgalloc.h> 49#include <asm/pgalloc.h>
@@ -1000,6 +1001,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1000 goto bad_fork_cleanup_put_domain; 1001 goto bad_fork_cleanup_put_domain;
1001 1002
1002 p->did_exec = 0; 1003 p->did_exec = 0;
1004 delayacct_tsk_init(p); /* Must remain after dup_task_struct() */
1003 copy_flags(clone_flags, p); 1005 copy_flags(clone_flags, p);
1004 p->pid = pid; 1006 p->pid = pid;
1005 retval = -EFAULT; 1007 retval = -EFAULT;