perf/core: set cgroup in cpu contexts for new cgroup events
PATCH v2 1/1 perf/core: set cgroup in cpu contexts for new cgroup events
There is an optimization in perf_cgroup_sched_{in,out} that skips the switch of cgroup events if the old and new cgroups in a task switch are the same. This optimization interacts with the current code in two ways that cause a cpu context's cgroup (cpuctx->cgrp) to be NULL even if a cgroup event matches the current task. These are:
1. On creation of the first cgroup event in a CPU: In current code, cpuctx->cpu is only set in perf_cgroup_sched_in, but due to the aforesaid optimization, perf_cgroup_sched_in will run until the next cgroup switches in that cpu. This may happen late or never happen, depending on system's number of cgroups, cpu load, etc.
2. On deletion of the last cgroup event in a cpuctx: In list_del_event, cpuctx->cgrp is set NULL. Any new cgroup event will not be sched in because cpuctx->cgrp == NULL until a cgroup switch occurs and perf_cgroup_sched_in is executed (updating cpuctx->cgrp).
This patch fixes both problems by setting cpuctx->cgrp in list_add_event, mirroring what list_del_event does when removing a cgroup event from CPU context, as introduced in:
commit 68cacd29167b ("perf_events: Fix stale ->cgrp pointer in update_cgrp_time_from_cpuctx()")
With this patch, cpuctx->cgrp is always set/clear when installing/removing the first/last cgroup event in/from the cpu context. With cpuctx->cgrp correctly set, event_filter_match works as intended when events are sched in/out.
The problem is easy to observe in a machine with only one cgroup:
$ perf stat -e cycles -I 1000 -C 0 -G /
# time counts unit events
1.000161699 <not counted> cycles /
2.000355591 <not counted> cycles /
3.000565154 <not counted> cycles /
4.000951350 <not counted> cycles /After the fix, the output is as expected:
$ perf stat -e cycles -I 1000 -a -G /
# time counts unit events
1.004699159 627342882 cycles /
2.007397156 615272690 cycles /
3.010019057 616726074 cycles /Rebased at peterz/queue/perf/core.
Changes in v2:
- Fix build error when no CONFIG_CGROUP_PERF.
- Unify add and del cases into list_update_cgroup_event.
- Remove cgroup exclusive variables from builds without CONFIG_CGROUP_PERF.
--- include/linux/perf_event.h | 4 ++++ kernel/events/core.c | 54 ++++++++++++++++++++++++++++++---------------- 2 files changed, 40 insertions(+), 18 deletions(-)
include/linux/perf_event.h +4 -0
@@ -730,7 +730,9 @@ struct perf_event_context {u64 parent_gen;u64 generation;int pin_count; +#ifdef CONFIG_CGROUP_PERF int nr_cgroups;/* cgroup evts */ +#endif void *task_ctx_data;/* pmu specific data */ struct rcu_head rcu_head; };
@@ -756,7 +758,9 @@ struct perf_cpu_context {unsigned int hrtimer_active;struct pmu *unique_pmu; +#ifdef CONFIG_CGROUP_PERF struct perf_cgroup *cgrp; +#endif };struct perf_output_handle {
kernel/events/core.c +36 -18
90 lines not on this page · raw message
Signature · 1 line
2.8.0.rc3.226.g39d4020
Hi,
Quoted 47 lines · David Carrillo-Cisneros
There is an optimization in perf_cgroup_sched_{in,out} that skips the switch of cgroup events if the old and new cgroups in a task switch are the same. This optimization interacts with the current code in two ways that cause a cpu context's cgroup (
cpuctx->cgrp) to be NULL even if a cgroup event matches the current task. These are:1. On creation of the first cgroup event in a CPU: In current code,
cpuctx->cpuis only set inperf_cgroup_sched_in, but due to the aforesaid optimization,perf_cgroup_sched_inwill run until the next cgroup switches in that cpu. This may happen late or never happen, depending on system's number of cgroups, cpu load, etc.2. On deletion of the last cgroup event in a cpuctx: In
list_del_event,cpuctx->cgrpis set NULL. Any new cgroup event will not be sched in becausecpuctx->cgrp== NULL until a cgroup switch occurs andperf_cgroup_sched_inis executed (updatingcpuctx->cgrp).This patch fixes both problems by setting
cpuctx->cgrpinlist_add_event, mirroring whatlist_del_eventdoes when removing a cgroup event from CPU context, as introduced in:
commit68cacd29167b("perf_events: Fix stale ->cgrp pointer inupdate_cgrp_time_from_cpuctx()")With this patch,
cpuctx->cgrpis always set/clear when installing/removing the first/last cgroup event in/from the cpu context. Withcpuctx->cgrpcorrectly set,event_filter_matchworks as intended when events are sched in/out.The problem is easy to observe in a machine with only one cgroup:
$ perf stat -e cycles -I 1000 -C 0 -G / # time counts unit events 1.000161699 <not counted> cycles / 2.000355591 <not counted> cycles / 3.000565154 <not counted> cycles / 4.000951350 <not counted> cycles /After the fix, the output is as expected:
$ perf stat -e cycles -I 1000 -a -G / # time counts unit events 1.004699159 627342882 cycles / 2.007397156 615272690 cycles / 3.010019057 616726074 cycles /Rebased at peterz/queue/perf/core.
Quoted 7 lines
Changes in v2:
- Fix build error when noCONFIG_CGROUP_PERF.
- Unify add and del cases intolist_update_cgroup_event.
- Remove cgroup exclusive variables from builds withoutCONFIG_CGROUP_PERF.Signed-off-by David Carrillo-Cisneros <[email protected]>
Is this supposed to fix the bug I reported here?
https://www.mail-archive.com/[email protected]/msg1197757.html
If so, you may want to add:
1) Fixes: f2fb6bef92514 ("perf/core: Optimize side-band event delivery")
2) Reported-by: Vegard Nossum <[email protected]>
3) a link to the thread
and I can give it a test to see if it fixes the problem I was running into.
If not, please ignore :-)
Thanks,
Vegard
Hi Vegard,
I don't think this patch fixes your bug, but it touches some code that may be related.
David
Quoted 76 lines · Vegard Nossum
Hi,
Quoted 47 lines · David Carrillo-Cisneros
There is an optimization in perf_cgroup_sched_{in,out} that skips the switch of cgroup events if the old and new cgroups in a task switch are the same. This optimization interacts with the current code in two ways that cause a cpu context's cgroup (
cpuctx->cgrp) to be NULL even if a cgroup event matches the current task. These are:1. On creation of the first cgroup event in a CPU: In current code,
cpuctx->cpuis only set inperf_cgroup_sched_in, but due to the aforesaid optimization,perf_cgroup_sched_inwill run until the next cgroup switches in that cpu. This may happen late or never happen, depending on system's number of cgroups, cpu load, etc.2. On deletion of the last cgroup event in a cpuctx: In
list_del_event,cpuctx->cgrpis set NULL. Any new cgroup event will not be sched in becausecpuctx->cgrp== NULL until a cgroup switch occurs andperf_cgroup_sched_inis executed (updatingcpuctx->cgrp).This patch fixes both problems by setting
cpuctx->cgrpinlist_add_event, mirroring whatlist_del_eventdoes when removing a cgroup event from CPU context, as introduced in:
commit68cacd29167b("perf_events: Fix stale ->cgrp pointer inupdate_cgrp_time_from_cpuctx()")With this patch,
cpuctx->cgrpis always set/clear when installing/removing the first/last cgroup event in/from the cpu context. Withcpuctx->cgrpcorrectly set,event_filter_matchworks as intended when events are sched in/out.The problem is easy to observe in a machine with only one cgroup:
$ perf stat -e cycles -I 1000 -C 0 -G / # time counts unit events 1.000161699 <not counted> cycles / 2.000355591 <not counted> cycles / 3.000565154 <not counted> cycles / 4.000951350 <not counted> cycles /After the fix, the output is as expected:
$ perf stat -e cycles -I 1000 -a -G / # time counts unit events 1.004699159 627342882 cycles / 2.007397156 615272690 cycles / 3.010019057 616726074 cycles /Rebased at peterz/queue/perf/core.
Quoted 7 lines
Changes in v2:
- Fix build error when noCONFIG_CGROUP_PERF.
- Unify add and del cases intolist_update_cgroup_event.
- Remove cgroup exclusive variables from builds withoutCONFIG_CGROUP_PERF.Signed-off-by David Carrillo-Cisneros <[email protected]>Is this supposed to fix the bug I reported here?
https://www.mail-archive.com/[email protected]/msg1197757.html
If so, you may want to add:
1) Fixes:
f2fb6bef92514("perf/core: Optimize side-band event delivery")
2) Reported-by: Vegard Nossum <[email protected]>
3) a link to the threadand I can give it a test to see if it fixes the problem I was running into.
If not, please ignore :-)
Thanks,
Vegard
Peter Zijlstra
maintainerQuoted 4 lines · Vegard Nossum
Is this supposed to fix the bug I reported here?
https://www.mail-archive.com/[email protected]/msg1197757.html
Like David said, unlikely.
I only recently got back from holidays so please allow me a little time to sort through the mailbox and get going again. I'll try and sort this 'soon'.
Thanks!
tip-bot for David Carrillo-Cisneros
merge bot[tip:perf/core] perf/core: Set cgroup in CPU contexts for new cgroup events
In reply to David Carrillo-Cisnerosperf/core: Set cgroup in CPU contexts for new cgroup events
Commit-ID: db4a835601b73cf8d6cd8986381d966b8e13d2d9 Gitweb: http://git.kernel.org/tip/db4a835601b73cf8d6cd8986381d966b8e13d2d9 Author: David Carrillo-Cisneros <[email protected]> AuthorDate: Tue, 2 Aug 2016 00:48:12 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Wed, 10 Aug 2016 13:05:52 +0200
perf/core: Set cgroup in CPU contexts for new cgroup events
There's a perf stat bug easy to observer on a machine with only one cgroup:
$ perf stat -e cycles -I 1000 -C 0 -G /
# time counts unit events
1.000161699 <not counted> cycles /
2.000355591 <not counted> cycles /
3.000565154 <not counted> cycles /
4.000951350 <not counted> cycles /We'd expect some output there.
The underlying problem is that there is an optimization in perf_cgroup_sched_{in,out}() that skips the switch of cgroup events if the old and new cgroups in a task switch are the same.
This optimization interacts with the current code in two ways that cause a CPU context's cgroup (cpuctx->cgrp) to be NULL even if a cgroup event matches the current task. These are:
1. On creation of the first cgroup event in a CPU: In current code, cpuctx->cpu is only set in perf_cgroup_sched_in, but due to the aforesaid optimization, perf_cgroup_sched_in will run until the next cgroup switches in that CPU. This may happen late or never happen, depending on system's number of cgroups, CPU load, etc.
2. On deletion of the last cgroup event in a cpuctx: In list_del_event, cpuctx->cgrp is set NULL. Any new cgroup event will not be sched in because cpuctx->cgrp == NULL until a cgroup switch occurs and perf_cgroup_sched_in is executed (updating cpuctx->cgrp).
This patch fixes both problems by setting cpuctx->cgrp in list_add_event, mirroring what list_del_event does when removing a cgroup event from CPU context, as introduced in:
commit 68cacd29167b ("perf_events: Fix stale ->cgrp pointer in update_cgrp_time_from_cpuctx()")
With this patch, cpuctx->cgrp is always set/clear when installing/removing the first/last cgroup event in/from the CPU context. With cpuctx->cgrp correctly set, event_filter_match works as intended when events are sched in/out.
After the fix, the output is as expected:
$ perf stat -e cycles -I 1000 -a -G /
# time counts unit events
1.004699159 627342882 cycles /
2.007397156 615272690 cycles /
3.010019057 616726074 cycles /--- include/linux/perf_event.h | 4 ++++ kernel/events/core.c | 54 ++++++++++++++++++++++++++++++---------------- 2 files changed, 40 insertions(+), 18 deletions(-)
include/linux/perf_event.h +4 -0
@@ -743,7 +743,9 @@ struct perf_event_context {u64 parent_gen;u64 generation;int pin_count; +#ifdef CONFIG_CGROUP_PERF int nr_cgroups;/* cgroup evts */ +#endif void *task_ctx_data;/* pmu specific data */ struct rcu_head rcu_head; };
@@ -769,7 +771,9 @@ struct perf_cpu_context {unsigned int hrtimer_active;struct pmu *unique_pmu; +#ifdef CONFIG_CGROUP_PERF struct perf_cgroup *cgrp; +#endif };struct perf_output_handle {
kernel/events/core.c +36 -18
90 lines not on this page · raw message