diff options
| author | Stephane Eranian <eranian@google.com> | 2011-03-23 11:03:06 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2011-03-23 11:07:22 -0400 |
| commit | 68cacd29167b1926d237bd1b153aa2a990201729 (patch) | |
| tree | d4359e9e0a1fa88b569e0c8a20aede435d916fee /kernel | |
| parent | ce2d17ca7f85dcade62cd608601a0d52ccdaf0e6 (diff) | |
perf_events: Fix stale ->cgrp pointer in update_cgrp_time_from_cpuctx()
This patch solves a stale pointer problem in
update_cgrp_time_from_cpuctx(). The cpuctx->cgrp
was not cleared on all possible event exit paths,
including:
close()
perf_release()
perf_release_kernel()
list_del_event()
This patch fixes list_del_event() to clear cpuctx->cgrp
when there are no cgroup events left in the context.
[ This second version makes the code compile when
CONFIG_CGROUP_PERF is not enabled. We unconditionally define
perf_cpu_context->cgrp. ]
Signed-off-by: Stephane Eranian <eranian@google.com>
Cc: peterz@infradead.org
Cc: perfmon2-devel@lists.sf.net
Cc: paulus@samba.org
Cc: davem@davemloft.net
LKML-Reference: <20110323150306.GA1580@quad>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/perf_event.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 3472bb1a070c..0c714226ae0c 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c | |||
| @@ -941,6 +941,7 @@ static void perf_group_attach(struct perf_event *event) | |||
| 941 | static void | 941 | static void |
| 942 | list_del_event(struct perf_event *event, struct perf_event_context *ctx) | 942 | list_del_event(struct perf_event *event, struct perf_event_context *ctx) |
| 943 | { | 943 | { |
| 944 | struct perf_cpu_context *cpuctx; | ||
| 944 | /* | 945 | /* |
| 945 | * We can have double detach due to exit/hot-unplug + close. | 946 | * We can have double detach due to exit/hot-unplug + close. |
| 946 | */ | 947 | */ |
| @@ -949,8 +950,17 @@ list_del_event(struct perf_event *event, struct perf_event_context *ctx) | |||
| 949 | 950 | ||
| 950 | event->attach_state &= ~PERF_ATTACH_CONTEXT; | 951 | event->attach_state &= ~PERF_ATTACH_CONTEXT; |
| 951 | 952 | ||
| 952 | if (is_cgroup_event(event)) | 953 | if (is_cgroup_event(event)) { |
| 953 | ctx->nr_cgroups--; | 954 | ctx->nr_cgroups--; |
| 955 | cpuctx = __get_cpu_context(ctx); | ||
| 956 | /* | ||
| 957 | * if there are no more cgroup events | ||
| 958 | * then cler cgrp to avoid stale pointer | ||
| 959 | * in update_cgrp_time_from_cpuctx() | ||
| 960 | */ | ||
| 961 | if (!ctx->nr_cgroups) | ||
| 962 | cpuctx->cgrp = NULL; | ||
| 963 | } | ||
| 954 | 964 | ||
| 955 | ctx->nr_events--; | 965 | ctx->nr_events--; |
| 956 | if (event->attr.inherit_stat) | 966 | if (event->attr.inherit_stat) |
