diff options
author | Stephane Eranian <eranian@google.com> | 2011-02-14 04:20:01 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-02-16 07:30:48 -0500 |
commit | e5d1367f17ba6a6fed5fd8b74e4d5720923e0c25 (patch) | |
tree | 5862b4cddb7c88e0513e503cb3f46c60da2eeb6f /include | |
parent | d41d5a01631af821d3a3447e6613a316f5ee6c25 (diff) |
perf: Add cgroup support
This kernel patch adds the ability to filter monitoring based on
container groups (cgroups). This is for use in per-cpu mode only.
The cgroup to monitor is passed as a file descriptor in the pid
argument to the syscall. The file descriptor must be opened to
the cgroup name in the cgroup filesystem. For instance, if the
cgroup name is foo and cgroupfs is mounted in /cgroup, then the
file descriptor is opened to /cgroup/foo. Cgroup mode is
activated by passing PERF_FLAG_PID_CGROUP in the flags argument
to the syscall.
For instance to measure in cgroup foo on CPU1 assuming
cgroupfs is mounted under /cgroup:
struct perf_event_attr attr;
int cgroup_fd, fd;
cgroup_fd = open("/cgroup/foo", O_RDONLY);
fd = perf_event_open(&attr, cgroup_fd, 1, -1, PERF_FLAG_PID_CGROUP);
close(cgroup_fd);
Signed-off-by: Stephane Eranian <eranian@google.com>
[ added perf_cgroup_{exit,attach} ]
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <4d590250.114ddf0a.689e.4482@mx.google.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/cgroup.h | 1 | ||||
-rw-r--r-- | include/linux/cgroup_subsys.h | 4 | ||||
-rw-r--r-- | include/linux/perf_event.h | 33 |
3 files changed, 35 insertions, 3 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 38117d937332..e654fa239916 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h | |||
@@ -627,6 +627,7 @@ bool css_is_ancestor(struct cgroup_subsys_state *cg, | |||
627 | /* Get id and depth of css */ | 627 | /* Get id and depth of css */ |
628 | unsigned short css_id(struct cgroup_subsys_state *css); | 628 | unsigned short css_id(struct cgroup_subsys_state *css); |
629 | unsigned short css_depth(struct cgroup_subsys_state *css); | 629 | unsigned short css_depth(struct cgroup_subsys_state *css); |
630 | struct cgroup_subsys_state *cgroup_css_from_dir(struct file *f, int id); | ||
630 | 631 | ||
631 | #else /* !CONFIG_CGROUPS */ | 632 | #else /* !CONFIG_CGROUPS */ |
632 | 633 | ||
diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h index ccefff02b6cb..cdbfcb8780ec 100644 --- a/include/linux/cgroup_subsys.h +++ b/include/linux/cgroup_subsys.h | |||
@@ -65,4 +65,8 @@ SUBSYS(net_cls) | |||
65 | SUBSYS(blkio) | 65 | SUBSYS(blkio) |
66 | #endif | 66 | #endif |
67 | 67 | ||
68 | #ifdef CONFIG_CGROUP_PERF | ||
69 | SUBSYS(perf) | ||
70 | #endif | ||
71 | |||
68 | /* */ | 72 | /* */ |
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index dda5b0a3ff60..38c8b2554842 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
@@ -464,6 +464,7 @@ enum perf_callchain_context { | |||
464 | 464 | ||
465 | #define PERF_FLAG_FD_NO_GROUP (1U << 0) | 465 | #define PERF_FLAG_FD_NO_GROUP (1U << 0) |
466 | #define PERF_FLAG_FD_OUTPUT (1U << 1) | 466 | #define PERF_FLAG_FD_OUTPUT (1U << 1) |
467 | #define PERF_FLAG_PID_CGROUP (1U << 2) /* pid=cgroup id, per-cpu mode only */ | ||
467 | 468 | ||
468 | #ifdef __KERNEL__ | 469 | #ifdef __KERNEL__ |
469 | /* | 470 | /* |
@@ -471,6 +472,7 @@ enum perf_callchain_context { | |||
471 | */ | 472 | */ |
472 | 473 | ||
473 | #ifdef CONFIG_PERF_EVENTS | 474 | #ifdef CONFIG_PERF_EVENTS |
475 | # include <linux/cgroup.h> | ||
474 | # include <asm/perf_event.h> | 476 | # include <asm/perf_event.h> |
475 | # include <asm/local64.h> | 477 | # include <asm/local64.h> |
476 | #endif | 478 | #endif |
@@ -716,6 +718,22 @@ struct swevent_hlist { | |||
716 | #define PERF_ATTACH_GROUP 0x02 | 718 | #define PERF_ATTACH_GROUP 0x02 |
717 | #define PERF_ATTACH_TASK 0x04 | 719 | #define PERF_ATTACH_TASK 0x04 |
718 | 720 | ||
721 | #ifdef CONFIG_CGROUP_PERF | ||
722 | /* | ||
723 | * perf_cgroup_info keeps track of time_enabled for a cgroup. | ||
724 | * This is a per-cpu dynamically allocated data structure. | ||
725 | */ | ||
726 | struct perf_cgroup_info { | ||
727 | u64 time; | ||
728 | u64 timestamp; | ||
729 | }; | ||
730 | |||
731 | struct perf_cgroup { | ||
732 | struct cgroup_subsys_state css; | ||
733 | struct perf_cgroup_info *info; /* timing info, one per cpu */ | ||
734 | }; | ||
735 | #endif | ||
736 | |||
719 | /** | 737 | /** |
720 | * struct perf_event - performance event kernel representation: | 738 | * struct perf_event - performance event kernel representation: |
721 | */ | 739 | */ |
@@ -832,6 +850,11 @@ struct perf_event { | |||
832 | struct event_filter *filter; | 850 | struct event_filter *filter; |
833 | #endif | 851 | #endif |
834 | 852 | ||
853 | #ifdef CONFIG_CGROUP_PERF | ||
854 | struct perf_cgroup *cgrp; /* cgroup event is attach to */ | ||
855 | int cgrp_defer_enabled; | ||
856 | #endif | ||
857 | |||
835 | #endif /* CONFIG_PERF_EVENTS */ | 858 | #endif /* CONFIG_PERF_EVENTS */ |
836 | }; | 859 | }; |
837 | 860 | ||
@@ -886,6 +909,7 @@ struct perf_event_context { | |||
886 | u64 generation; | 909 | u64 generation; |
887 | int pin_count; | 910 | int pin_count; |
888 | struct rcu_head rcu_head; | 911 | struct rcu_head rcu_head; |
912 | int nr_cgroups; /* cgroup events present */ | ||
889 | }; | 913 | }; |
890 | 914 | ||
891 | /* | 915 | /* |
@@ -905,6 +929,9 @@ struct perf_cpu_context { | |||
905 | struct list_head rotation_list; | 929 | struct list_head rotation_list; |
906 | int jiffies_interval; | 930 | int jiffies_interval; |
907 | struct pmu *active_pmu; | 931 | struct pmu *active_pmu; |
932 | #ifdef CONFIG_CGROUP_PERF | ||
933 | struct perf_cgroup *cgrp; | ||
934 | #endif | ||
908 | }; | 935 | }; |
909 | 936 | ||
910 | struct perf_output_handle { | 937 | struct perf_output_handle { |
@@ -1040,11 +1067,11 @@ have_event: | |||
1040 | __perf_sw_event(event_id, nr, nmi, regs, addr); | 1067 | __perf_sw_event(event_id, nr, nmi, regs, addr); |
1041 | } | 1068 | } |
1042 | 1069 | ||
1043 | extern atomic_t perf_task_events; | 1070 | extern atomic_t perf_sched_events; |
1044 | 1071 | ||
1045 | static inline void perf_event_task_sched_in(struct task_struct *task) | 1072 | static inline void perf_event_task_sched_in(struct task_struct *task) |
1046 | { | 1073 | { |
1047 | COND_STMT(&perf_task_events, __perf_event_task_sched_in(task)); | 1074 | COND_STMT(&perf_sched_events, __perf_event_task_sched_in(task)); |
1048 | } | 1075 | } |
1049 | 1076 | ||
1050 | static inline | 1077 | static inline |
@@ -1052,7 +1079,7 @@ void perf_event_task_sched_out(struct task_struct *task, struct task_struct *nex | |||
1052 | { | 1079 | { |
1053 | perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0); | 1080 | perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0); |
1054 | 1081 | ||
1055 | COND_STMT(&perf_task_events, __perf_event_task_sched_out(task, next)); | 1082 | COND_STMT(&perf_sched_events, __perf_event_task_sched_out(task, next)); |
1056 | } | 1083 | } |
1057 | 1084 | ||
1058 | extern void perf_event_mmap(struct vm_area_struct *vma); | 1085 | extern void perf_event_mmap(struct vm_area_struct *vma); |