diff options
author | Balbir Singh <balbir@linux.vnet.ibm.com> | 2007-10-19 02:39:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-19 14:53:36 -0400 |
commit | 846c7bb055747989891f5cd2bb6e8d56243ba1e7 (patch) | |
tree | e044041366efa8298157c4ae86615d68d30dd6d2 /include/linux | |
parent | c2e2c7fa1cb2cf2b114a6c9bc132b6601db5a7c8 (diff) |
Add cgroupstats
This patch is inspired by the discussion at
http://lkml.org/lkml/2007/4/11/187 and implements per cgroup statistics
as suggested by Andrew Morton in http://lkml.org/lkml/2007/4/11/263. The
patch is on top of 2.6.21-mm1 with Paul's cgroups v9 patches (forward
ported)
This patch implements per cgroup statistics infrastructure and re-uses
code from the taskstats interface. A new set of cgroup operations are
registered with commands and attributes. It should be very easy to
*extend* per cgroup statistics, by adding members to the cgroupstats
structure.
The current model for cgroupstats is a pull, a push model (to post
statistics on interesting events), should be very easy to add. Currently
user space requests for statistics by passing the cgroup file
descriptor. Statistics about the state of all the tasks in the cgroup
is returned to user space.
TODO's/NOTE:
This patch provides an infrastructure for implementing cgroup statistics.
Based on the needs of each controller, we can incrementally add more statistics,
event based support for notification of statistics, accumulation of taskstats
into cgroup statistics in the future.
Sample output
# ./cgroupstats -C /cgroup/a
sleeping 2, blocked 0, running 1, stopped 0, uninterruptible 0
# ./cgroupstats -C /cgroup/
sleeping 154, blocked 0, running 0, stopped 0, uninterruptible 0
If the approach looks good, I'll enhance and post the user space utility for
the same
Feedback, comments, test results are always welcome!
[akpm@linux-foundation.org: build fix]
Signed-off-by: Balbir Singh <balbir@linux.vnet.ibm.com>
Cc: Paul Menage <menage@google.com>
Cc: Jay Lan <jlan@engr.sgi.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/Kbuild | 1 | ||||
-rw-r--r-- | include/linux/cgroup.h | 8 | ||||
-rw-r--r-- | include/linux/cgroupstats.h | 70 | ||||
-rw-r--r-- | include/linux/delayacct.h | 13 |
4 files changed, 92 insertions, 0 deletions
diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 7ac8303c8471..e3ffd14a3f0b 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild | |||
@@ -47,6 +47,7 @@ header-y += coda_psdev.h | |||
47 | header-y += coff.h | 47 | header-y += coff.h |
48 | header-y += comstats.h | 48 | header-y += comstats.h |
49 | header-y += const.h | 49 | header-y += const.h |
50 | header-y += cgroupstats.h | ||
50 | header-y += cycx_cfm.h | 51 | header-y += cycx_cfm.h |
51 | header-y += dlm_device.h | 52 | header-y += dlm_device.h |
52 | header-y += dlm_netlink.h | 53 | header-y += dlm_netlink.h |
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 9e9b7efa180b..87479328d46d 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/cpumask.h> | 13 | #include <linux/cpumask.h> |
14 | #include <linux/nodemask.h> | 14 | #include <linux/nodemask.h> |
15 | #include <linux/rcupdate.h> | 15 | #include <linux/rcupdate.h> |
16 | #include <linux/cgroupstats.h> | ||
16 | 17 | ||
17 | #ifdef CONFIG_CGROUPS | 18 | #ifdef CONFIG_CGROUPS |
18 | 19 | ||
@@ -29,6 +30,8 @@ extern void cgroup_fork(struct task_struct *p); | |||
29 | extern void cgroup_fork_callbacks(struct task_struct *p); | 30 | extern void cgroup_fork_callbacks(struct task_struct *p); |
30 | extern void cgroup_post_fork(struct task_struct *p); | 31 | extern void cgroup_post_fork(struct task_struct *p); |
31 | extern void cgroup_exit(struct task_struct *p, int run_callbacks); | 32 | extern void cgroup_exit(struct task_struct *p, int run_callbacks); |
33 | extern int cgroupstats_build(struct cgroupstats *stats, | ||
34 | struct dentry *dentry); | ||
32 | 35 | ||
33 | extern struct file_operations proc_cgroup_operations; | 36 | extern struct file_operations proc_cgroup_operations; |
34 | 37 | ||
@@ -313,6 +316,11 @@ static inline void cgroup_exit(struct task_struct *p, int callbacks) {} | |||
313 | 316 | ||
314 | static inline void cgroup_lock(void) {} | 317 | static inline void cgroup_lock(void) {} |
315 | static inline void cgroup_unlock(void) {} | 318 | static inline void cgroup_unlock(void) {} |
319 | static inline int cgroupstats_build(struct cgroupstats *stats, | ||
320 | struct dentry *dentry) | ||
321 | { | ||
322 | return -EINVAL; | ||
323 | } | ||
316 | 324 | ||
317 | #endif /* !CONFIG_CGROUPS */ | 325 | #endif /* !CONFIG_CGROUPS */ |
318 | 326 | ||
diff --git a/include/linux/cgroupstats.h b/include/linux/cgroupstats.h new file mode 100644 index 000000000000..4f53abf6855d --- /dev/null +++ b/include/linux/cgroupstats.h | |||
@@ -0,0 +1,70 @@ | |||
1 | /* cgroupstats.h - exporting per-cgroup statistics | ||
2 | * | ||
3 | * Copyright IBM Corporation, 2007 | ||
4 | * Author Balbir Singh <balbir@linux.vnet.ibm.com> | ||
5 | * | ||
6 | * 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 | * as published by the Free Software Foundation. | ||
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. | ||
13 | */ | ||
14 | |||
15 | #ifndef _LINUX_CGROUPSTATS_H | ||
16 | #define _LINUX_CGROUPSTATS_H | ||
17 | |||
18 | #include <linux/taskstats.h> | ||
19 | |||
20 | /* | ||
21 | * Data shared between user space and kernel space on a per cgroup | ||
22 | * basis. This data is shared using taskstats. | ||
23 | * | ||
24 | * Most of these states are derived by looking at the task->state value | ||
25 | * For the nr_io_wait state, a flag in the delay accounting structure | ||
26 | * indicates that the task is waiting on IO | ||
27 | * | ||
28 | * Each member is aligned to a 8 byte boundary. | ||
29 | */ | ||
30 | struct cgroupstats { | ||
31 | __u64 nr_sleeping; /* Number of tasks sleeping */ | ||
32 | __u64 nr_running; /* Number of tasks running */ | ||
33 | __u64 nr_stopped; /* Number of tasks in stopped state */ | ||
34 | __u64 nr_uninterruptible; /* Number of tasks in uninterruptible */ | ||
35 | /* state */ | ||
36 | __u64 nr_io_wait; /* Number of tasks waiting on IO */ | ||
37 | }; | ||
38 | |||
39 | /* | ||
40 | * Commands sent from userspace | ||
41 | * Not versioned. New commands should only be inserted at the enum's end | ||
42 | * prior to __CGROUPSTATS_CMD_MAX | ||
43 | */ | ||
44 | |||
45 | enum { | ||
46 | CGROUPSTATS_CMD_UNSPEC = __TASKSTATS_CMD_MAX, /* Reserved */ | ||
47 | CGROUPSTATS_CMD_GET, /* user->kernel request/get-response */ | ||
48 | CGROUPSTATS_CMD_NEW, /* kernel->user event */ | ||
49 | __CGROUPSTATS_CMD_MAX, | ||
50 | }; | ||
51 | |||
52 | #define CGROUPSTATS_CMD_MAX (__CGROUPSTATS_CMD_MAX - 1) | ||
53 | |||
54 | enum { | ||
55 | CGROUPSTATS_TYPE_UNSPEC = 0, /* Reserved */ | ||
56 | CGROUPSTATS_TYPE_CGROUP_STATS, /* contains name + stats */ | ||
57 | __CGROUPSTATS_TYPE_MAX, | ||
58 | }; | ||
59 | |||
60 | #define CGROUPSTATS_TYPE_MAX (__CGROUPSTATS_TYPE_MAX - 1) | ||
61 | |||
62 | enum { | ||
63 | CGROUPSTATS_CMD_ATTR_UNSPEC = 0, | ||
64 | CGROUPSTATS_CMD_ATTR_FD, | ||
65 | __CGROUPSTATS_CMD_ATTR_MAX, | ||
66 | }; | ||
67 | |||
68 | #define CGROUPSTATS_CMD_ATTR_MAX (__CGROUPSTATS_CMD_ATTR_MAX - 1) | ||
69 | |||
70 | #endif /* _LINUX_CGROUPSTATS_H */ | ||
diff --git a/include/linux/delayacct.h b/include/linux/delayacct.h index 55d1ca5e60f5..ab94bc083558 100644 --- a/include/linux/delayacct.h +++ b/include/linux/delayacct.h | |||
@@ -26,6 +26,7 @@ | |||
26 | * Used to set current->delays->flags | 26 | * Used to set current->delays->flags |
27 | */ | 27 | */ |
28 | #define DELAYACCT_PF_SWAPIN 0x00000001 /* I am doing a swapin */ | 28 | #define DELAYACCT_PF_SWAPIN 0x00000001 /* I am doing a swapin */ |
29 | #define DELAYACCT_PF_BLKIO 0x00000002 /* I am waiting on IO */ | ||
29 | 30 | ||
30 | #ifdef CONFIG_TASK_DELAY_ACCT | 31 | #ifdef CONFIG_TASK_DELAY_ACCT |
31 | 32 | ||
@@ -39,6 +40,14 @@ extern void __delayacct_blkio_end(void); | |||
39 | extern int __delayacct_add_tsk(struct taskstats *, struct task_struct *); | 40 | extern int __delayacct_add_tsk(struct taskstats *, struct task_struct *); |
40 | extern __u64 __delayacct_blkio_ticks(struct task_struct *); | 41 | extern __u64 __delayacct_blkio_ticks(struct task_struct *); |
41 | 42 | ||
43 | static inline int delayacct_is_task_waiting_on_io(struct task_struct *p) | ||
44 | { | ||
45 | if (p->delays) | ||
46 | return (p->delays->flags & DELAYACCT_PF_BLKIO); | ||
47 | else | ||
48 | return 0; | ||
49 | } | ||
50 | |||
42 | static inline void delayacct_set_flag(int flag) | 51 | static inline void delayacct_set_flag(int flag) |
43 | { | 52 | { |
44 | if (current->delays) | 53 | if (current->delays) |
@@ -71,6 +80,7 @@ static inline void delayacct_tsk_free(struct task_struct *tsk) | |||
71 | 80 | ||
72 | static inline void delayacct_blkio_start(void) | 81 | static inline void delayacct_blkio_start(void) |
73 | { | 82 | { |
83 | delayacct_set_flag(DELAYACCT_PF_BLKIO); | ||
74 | if (current->delays) | 84 | if (current->delays) |
75 | __delayacct_blkio_start(); | 85 | __delayacct_blkio_start(); |
76 | } | 86 | } |
@@ -79,6 +89,7 @@ static inline void delayacct_blkio_end(void) | |||
79 | { | 89 | { |
80 | if (current->delays) | 90 | if (current->delays) |
81 | __delayacct_blkio_end(); | 91 | __delayacct_blkio_end(); |
92 | delayacct_clear_flag(DELAYACCT_PF_BLKIO); | ||
82 | } | 93 | } |
83 | 94 | ||
84 | static inline int delayacct_add_tsk(struct taskstats *d, | 95 | static inline int delayacct_add_tsk(struct taskstats *d, |
@@ -116,6 +127,8 @@ static inline int delayacct_add_tsk(struct taskstats *d, | |||
116 | { return 0; } | 127 | { return 0; } |
117 | static inline __u64 delayacct_blkio_ticks(struct task_struct *tsk) | 128 | static inline __u64 delayacct_blkio_ticks(struct task_struct *tsk) |
118 | { return 0; } | 129 | { return 0; } |
130 | static inline int delayacct_is_task_waiting_on_io(struct task_struct *p) | ||
131 | { return 0; } | ||
119 | #endif /* CONFIG_TASK_DELAY_ACCT */ | 132 | #endif /* CONFIG_TASK_DELAY_ACCT */ |
120 | 133 | ||
121 | #endif | 134 | #endif |