diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-12-11 05:26:29 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-12-11 09:45:50 -0500 |
commit | ccff286d85098ba5438e22aa2ea807fc1e18cf2f (patch) | |
tree | 0e8ab0180e38ddc530cc3f3d55152a34160605cc /kernel/perf_counter.c | |
parent | 04289bb9891882202d7e961c4c04d2376930e9f9 (diff) |
perf counters: group counter, fixes
Impact: bugfix
Check that a group does not span outside the context of a CPU or a task.
Also, do not allow deep recursive hierarchies.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/perf_counter.c')
-rw-r--r-- | kernel/perf_counter.c | 39 |
1 files changed, 20 insertions, 19 deletions
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index fa59fe8c02d5..278209c547a8 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c | |||
@@ -107,9 +107,6 @@ list_del_counter(struct perf_counter *counter, struct perf_counter_context *ctx) | |||
107 | 107 | ||
108 | list_del_init(&counter->list_entry); | 108 | list_del_init(&counter->list_entry); |
109 | 109 | ||
110 | if (list_empty(&counter->sibling_list)) | ||
111 | return; | ||
112 | |||
113 | /* | 110 | /* |
114 | * If this was a group counter with sibling counters then | 111 | * If this was a group counter with sibling counters then |
115 | * upgrade the siblings to singleton counters by adding them | 112 | * upgrade the siblings to singleton counters by adding them |
@@ -395,9 +392,6 @@ counter_sched_in(struct perf_counter *counter, | |||
395 | struct perf_counter_context *ctx, | 392 | struct perf_counter_context *ctx, |
396 | int cpu) | 393 | int cpu) |
397 | { | 394 | { |
398 | if (!counter->active) | ||
399 | return; | ||
400 | |||
401 | hw_perf_counter_enable(counter); | 395 | hw_perf_counter_enable(counter); |
402 | counter->active = 1; | 396 | counter->active = 1; |
403 | counter->oncpu = cpu; /* TODO: put 'cpu' into cpuctx->cpu */ | 397 | counter->oncpu = cpu; /* TODO: put 'cpu' into cpuctx->cpu */ |
@@ -876,32 +870,39 @@ asmlinkage int sys_perf_counter_open( | |||
876 | return -EFAULT; | 870 | return -EFAULT; |
877 | 871 | ||
878 | /* | 872 | /* |
879 | * Look up the group leader: | 873 | * Get the target context (task or percpu): |
874 | */ | ||
875 | ctx = find_get_context(pid, cpu); | ||
876 | if (IS_ERR(ctx)) | ||
877 | return PTR_ERR(ctx); | ||
878 | |||
879 | /* | ||
880 | * Look up the group leader (we will attach this counter to it): | ||
880 | */ | 881 | */ |
881 | group_leader = NULL; | 882 | group_leader = NULL; |
882 | if (group_fd != -1) { | 883 | if (group_fd != -1) { |
883 | ret = -EINVAL; | 884 | ret = -EINVAL; |
884 | group_file = fget_light(group_fd, &fput_needed); | 885 | group_file = fget_light(group_fd, &fput_needed); |
885 | if (!group_file) | 886 | if (!group_file) |
886 | goto out_fput; | 887 | goto err_put_context; |
887 | if (group_file->f_op != &perf_fops) | 888 | if (group_file->f_op != &perf_fops) |
888 | goto out_fput; | 889 | goto err_put_context; |
889 | 890 | ||
890 | group_leader = group_file->private_data; | 891 | group_leader = group_file->private_data; |
891 | /* | 892 | /* |
892 | * Do not allow a recursive hierarchy: | 893 | * Do not allow a recursive hierarchy (this new sibling |
894 | * becoming part of another group-sibling): | ||
895 | */ | ||
896 | if (group_leader->group_leader != group_leader) | ||
897 | goto err_put_context; | ||
898 | /* | ||
899 | * Do not allow to attach to a group in a different | ||
900 | * task or CPU context: | ||
893 | */ | 901 | */ |
894 | if (group_leader->group_leader) | 902 | if (group_leader->ctx != ctx) |
895 | goto out_fput; | 903 | goto err_put_context; |
896 | } | 904 | } |
897 | 905 | ||
898 | /* | ||
899 | * Get the target context (task or percpu): | ||
900 | */ | ||
901 | ctx = find_get_context(pid, cpu); | ||
902 | if (IS_ERR(ctx)) | ||
903 | return PTR_ERR(ctx); | ||
904 | |||
905 | ret = -ENOMEM; | 906 | ret = -ENOMEM; |
906 | counter = perf_counter_alloc(&hw_event, cpu, group_leader); | 907 | counter = perf_counter_alloc(&hw_event, cpu, group_leader); |
907 | if (!counter) | 908 | if (!counter) |