diff options
-rw-r--r-- | include/linux/taskstats.h | 29 | ||||
-rw-r--r-- | include/linux/tsacct_kern.h | 19 | ||||
-rw-r--r-- | kernel/Makefile | 2 | ||||
-rw-r--r-- | kernel/taskstats.c | 4 | ||||
-rw-r--r-- | kernel/tsacct.c | 72 |
5 files changed, 120 insertions, 6 deletions
diff --git a/include/linux/taskstats.h b/include/linux/taskstats.h index f1cb6cddd19d..af93a63a5092 100644 --- a/include/linux/taskstats.h +++ b/include/linux/taskstats.h | |||
@@ -2,6 +2,7 @@ | |||
2 | * | 2 | * |
3 | * Copyright (C) Shailabh Nagar, IBM Corp. 2006 | 3 | * Copyright (C) Shailabh Nagar, IBM Corp. 2006 |
4 | * (C) Balbir Singh, IBM Corp. 2006 | 4 | * (C) Balbir Singh, IBM Corp. 2006 |
5 | * (C) Jay Lan, SGI, 2006 | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of version 2.1 of the GNU Lesser General Public License | 8 | * under the terms of version 2.1 of the GNU Lesser General Public License |
@@ -29,16 +30,18 @@ | |||
29 | * c) add new fields after version comment; maintain 64-bit alignment | 30 | * c) add new fields after version comment; maintain 64-bit alignment |
30 | */ | 31 | */ |
31 | 32 | ||
32 | #define TASKSTATS_VERSION 1 | 33 | |
34 | #define TASKSTATS_VERSION 2 | ||
35 | #define TS_COMM_LEN 16 /* should sync up with TASK_COMM_LEN | ||
36 | * in linux/sched.h */ | ||
33 | 37 | ||
34 | struct taskstats { | 38 | struct taskstats { |
35 | 39 | ||
36 | /* Version 1 */ | 40 | /* Version 1 */ |
37 | __u16 version; | 41 | __u16 version; |
38 | __u16 padding[3]; /* Userspace should not interpret the padding | 42 | __u32 ac_exitcode; /* Exit status */ |
39 | * field which can be replaced by useful | 43 | __u8 ac_flag; /* Record flags */ |
40 | * fields if struct taskstats is extended. | 44 | __u8 ac_nice; /* task_nice */ |
41 | */ | ||
42 | 45 | ||
43 | /* Delay accounting fields start | 46 | /* Delay accounting fields start |
44 | * | 47 | * |
@@ -88,6 +91,22 @@ struct taskstats { | |||
88 | __u64 cpu_run_virtual_total; | 91 | __u64 cpu_run_virtual_total; |
89 | /* Delay accounting fields end */ | 92 | /* Delay accounting fields end */ |
90 | /* version 1 ends here */ | 93 | /* version 1 ends here */ |
94 | |||
95 | /* Basic Accounting Fields start */ | ||
96 | char ac_comm[TS_COMM_LEN]; /* Command name */ | ||
97 | __u8 ac_sched; /* Scheduling discipline */ | ||
98 | __u8 ac_pad[3]; | ||
99 | __u32 ac_uid; /* User ID */ | ||
100 | __u32 ac_gid; /* Group ID */ | ||
101 | __u32 ac_pid; /* Process ID */ | ||
102 | __u32 ac_ppid; /* Parent process ID */ | ||
103 | __u32 ac_btime; /* Begin time [sec since 1970] */ | ||
104 | __u64 ac_etime; /* Elapsed time [usec] */ | ||
105 | __u64 ac_utime; /* User CPU time [usec] */ | ||
106 | __u64 ac_stime; /* SYstem CPU time [usec] */ | ||
107 | __u64 ac_minflt; /* Minor Page Fault */ | ||
108 | __u64 ac_majflt; /* Major Page Fault */ | ||
109 | /* Basic Accounting Fields end */ | ||
91 | }; | 110 | }; |
92 | 111 | ||
93 | 112 | ||
diff --git a/include/linux/tsacct_kern.h b/include/linux/tsacct_kern.h new file mode 100644 index 000000000000..7e8196a02118 --- /dev/null +++ b/include/linux/tsacct_kern.h | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * tsacct_kern.h - kernel header for system accounting over taskstats interface | ||
3 | * | ||
4 | * Copyright (C) Jay Lan SGI | ||
5 | */ | ||
6 | |||
7 | #ifndef _LINUX_TSACCT_KERN_H | ||
8 | #define _LINUX_TSACCT_KERN_H | ||
9 | |||
10 | #include <linux/taskstats.h> | ||
11 | |||
12 | #ifdef CONFIG_TASKSTATS | ||
13 | extern void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk); | ||
14 | #else | ||
15 | static inline void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk) | ||
16 | {} | ||
17 | #endif /* CONFIG_TASKSTATS */ | ||
18 | |||
19 | #endif | ||
diff --git a/kernel/Makefile b/kernel/Makefile index e210e8cf7237..aacaafb28b9d 100644 --- a/kernel/Makefile +++ b/kernel/Makefile | |||
@@ -49,7 +49,7 @@ 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 | obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o |
52 | obj-$(CONFIG_TASKSTATS) += taskstats.o | 52 | obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o |
53 | 53 | ||
54 | ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y) | 54 | ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y) |
55 | # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is | 55 | # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is |
diff --git a/kernel/taskstats.c b/kernel/taskstats.c index c451af2ddb50..6c38dce88e8c 100644 --- a/kernel/taskstats.c +++ b/kernel/taskstats.c | |||
@@ -18,6 +18,7 @@ | |||
18 | 18 | ||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/taskstats_kern.h> | 20 | #include <linux/taskstats_kern.h> |
21 | #include <linux/tsacct_kern.h> | ||
21 | #include <linux/delayacct.h> | 22 | #include <linux/delayacct.h> |
22 | #include <linux/cpumask.h> | 23 | #include <linux/cpumask.h> |
23 | #include <linux/percpu.h> | 24 | #include <linux/percpu.h> |
@@ -198,7 +199,10 @@ static int fill_pid(pid_t pid, struct task_struct *pidtsk, | |||
198 | */ | 199 | */ |
199 | 200 | ||
200 | delayacct_add_tsk(stats, tsk); | 201 | delayacct_add_tsk(stats, tsk); |
202 | |||
203 | /* fill in basic acct fields */ | ||
201 | stats->version = TASKSTATS_VERSION; | 204 | stats->version = TASKSTATS_VERSION; |
205 | bacct_add_tsk(stats, tsk); | ||
202 | 206 | ||
203 | /* Define err: label here if needed */ | 207 | /* Define err: label here if needed */ |
204 | put_task_struct(tsk); | 208 | put_task_struct(tsk); |
diff --git a/kernel/tsacct.c b/kernel/tsacct.c new file mode 100644 index 000000000000..899067950a88 --- /dev/null +++ b/kernel/tsacct.c | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * tsacct.c - System accounting over taskstats interface | ||
3 | * | ||
4 | * Copyright (C) Jay Lan, <jlan@sgi.com> | ||
5 | * | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/sched.h> | ||
21 | #include <linux/tsacct_kern.h> | ||
22 | #include <linux/acct.h> | ||
23 | |||
24 | |||
25 | #define USEC_PER_TICK (USEC_PER_SEC/HZ) | ||
26 | /* | ||
27 | * fill in basic accounting fields | ||
28 | */ | ||
29 | void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk) | ||
30 | { | ||
31 | struct timespec uptime, ts; | ||
32 | s64 ac_etime; | ||
33 | |||
34 | BUILD_BUG_ON(TS_COMM_LEN < TASK_COMM_LEN); | ||
35 | |||
36 | /* calculate task elapsed time in timespec */ | ||
37 | do_posix_clock_monotonic_gettime(&uptime); | ||
38 | ts = timespec_sub(uptime, current->group_leader->start_time); | ||
39 | /* rebase elapsed time to usec */ | ||
40 | ac_etime = timespec_to_ns(&ts); | ||
41 | do_div(ac_etime, NSEC_PER_USEC); | ||
42 | stats->ac_etime = ac_etime; | ||
43 | stats->ac_btime = xtime.tv_sec - ts.tv_sec; | ||
44 | if (thread_group_leader(tsk)) { | ||
45 | stats->ac_exitcode = tsk->exit_code; | ||
46 | if (tsk->flags & PF_FORKNOEXEC) | ||
47 | stats->ac_flag |= AFORK; | ||
48 | } | ||
49 | if (tsk->flags & PF_SUPERPRIV) | ||
50 | stats->ac_flag |= ASU; | ||
51 | if (tsk->flags & PF_DUMPCORE) | ||
52 | stats->ac_flag |= ACORE; | ||
53 | if (tsk->flags & PF_SIGNALED) | ||
54 | stats->ac_flag |= AXSIG; | ||
55 | stats->ac_nice = task_nice(tsk); | ||
56 | stats->ac_sched = tsk->policy; | ||
57 | stats->ac_uid = tsk->uid; | ||
58 | stats->ac_gid = tsk->gid; | ||
59 | stats->ac_pid = tsk->pid; | ||
60 | stats->ac_ppid = (tsk->parent) ? tsk->parent->pid : 0; | ||
61 | stats->ac_utime = cputime_to_msecs(tsk->utime) * USEC_PER_MSEC; | ||
62 | stats->ac_stime = cputime_to_msecs(tsk->stime) * USEC_PER_MSEC; | ||
63 | stats->ac_minflt = tsk->min_flt; | ||
64 | stats->ac_majflt = tsk->maj_flt; | ||
65 | /* Each process gets a minimum of one usec cpu time */ | ||
66 | if ((stats->ac_utime == 0) && (stats->ac_stime == 0)) { | ||
67 | stats->ac_stime = 1; | ||
68 | } | ||
69 | |||
70 | strncpy(stats->ac_comm, tsk->comm, sizeof(stats->ac_comm)); | ||
71 | } | ||
72 | |||