diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/Makefile | 1 | ||||
-rw-r--r-- | kernel/delayacct.c | 87 | ||||
-rw-r--r-- | kernel/exit.c | 2 | ||||
-rw-r--r-- | kernel/fork.c | 2 |
4 files changed, 92 insertions, 0 deletions
diff --git a/kernel/Makefile b/kernel/Makefile index 47dbcd570cd..87bb34cc893 100644 --- a/kernel/Makefile +++ b/kernel/Makefile | |||
@@ -48,6 +48,7 @@ obj-$(CONFIG_GENERIC_HARDIRQS) += irq/ | |||
48 | obj-$(CONFIG_SECCOMP) += seccomp.o | 48 | obj-$(CONFIG_SECCOMP) += seccomp.o |
49 | obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o | 49 | obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o |
50 | obj-$(CONFIG_RELAY) += relay.o | 50 | obj-$(CONFIG_RELAY) += relay.o |
51 | obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o | ||
51 | 52 | ||
52 | ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y) | 53 | ifneq ($(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 00000000000..fbf7f228495 --- /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 | |||
22 | int delayacct_on __read_mostly; /* Delay accounting turned on/off */ | ||
23 | kmem_cache_t *delayacct_cache; | ||
24 | |||
25 | static int __init delayacct_setup_enable(char *str) | ||
26 | { | ||
27 | delayacct_on = 1; | ||
28 | return 1; | ||
29 | } | ||
30 | __setup("delayacct", delayacct_setup_enable); | ||
31 | |||
32 | void 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 | |||
42 | void __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 | |||
49 | void __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 | |||
60 | static 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 | |||
70 | static 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(¤t->delays->lock); | ||
83 | *total += ns; | ||
84 | (*count)++; | ||
85 | spin_unlock(¤t->delays->lock); | ||
86 | } | ||
87 | |||
diff --git a/kernel/exit.c b/kernel/exit.c index 6664c084783..3c2cf91defa 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 926e5a68ea9..451cfd35bf2 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; |