diff options
Diffstat (limited to 'kernel/events')
-rw-r--r-- | kernel/events/core.c | 217 | ||||
-rw-r--r-- | kernel/events/hw_breakpoint.c | 6 |
2 files changed, 205 insertions, 18 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c index 94afe5b91c6a..a6a9ec4cd8f5 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -118,6 +118,13 @@ static int cpu_function_call(int cpu, int (*func) (void *info), void *info) | |||
118 | PERF_FLAG_FD_OUTPUT |\ | 118 | PERF_FLAG_FD_OUTPUT |\ |
119 | PERF_FLAG_PID_CGROUP) | 119 | PERF_FLAG_PID_CGROUP) |
120 | 120 | ||
121 | /* | ||
122 | * branch priv levels that need permission checks | ||
123 | */ | ||
124 | #define PERF_SAMPLE_BRANCH_PERM_PLM \ | ||
125 | (PERF_SAMPLE_BRANCH_KERNEL |\ | ||
126 | PERF_SAMPLE_BRANCH_HV) | ||
127 | |||
121 | enum event_type_t { | 128 | enum event_type_t { |
122 | EVENT_FLEXIBLE = 0x1, | 129 | EVENT_FLEXIBLE = 0x1, |
123 | EVENT_PINNED = 0x2, | 130 | EVENT_PINNED = 0x2, |
@@ -128,8 +135,9 @@ enum event_type_t { | |||
128 | * perf_sched_events : >0 events exist | 135 | * perf_sched_events : >0 events exist |
129 | * perf_cgroup_events: >0 per-cpu cgroup events exist on this cpu | 136 | * perf_cgroup_events: >0 per-cpu cgroup events exist on this cpu |
130 | */ | 137 | */ |
131 | struct jump_label_key_deferred perf_sched_events __read_mostly; | 138 | struct static_key_deferred perf_sched_events __read_mostly; |
132 | static DEFINE_PER_CPU(atomic_t, perf_cgroup_events); | 139 | static DEFINE_PER_CPU(atomic_t, perf_cgroup_events); |
140 | static DEFINE_PER_CPU(atomic_t, perf_branch_stack_events); | ||
133 | 141 | ||
134 | static atomic_t nr_mmap_events __read_mostly; | 142 | static atomic_t nr_mmap_events __read_mostly; |
135 | static atomic_t nr_comm_events __read_mostly; | 143 | static atomic_t nr_comm_events __read_mostly; |
@@ -881,6 +889,9 @@ list_add_event(struct perf_event *event, struct perf_event_context *ctx) | |||
881 | if (is_cgroup_event(event)) | 889 | if (is_cgroup_event(event)) |
882 | ctx->nr_cgroups++; | 890 | ctx->nr_cgroups++; |
883 | 891 | ||
892 | if (has_branch_stack(event)) | ||
893 | ctx->nr_branch_stack++; | ||
894 | |||
884 | list_add_rcu(&event->event_entry, &ctx->event_list); | 895 | list_add_rcu(&event->event_entry, &ctx->event_list); |
885 | if (!ctx->nr_events) | 896 | if (!ctx->nr_events) |
886 | perf_pmu_rotate_start(ctx->pmu); | 897 | perf_pmu_rotate_start(ctx->pmu); |
@@ -1020,6 +1031,9 @@ list_del_event(struct perf_event *event, struct perf_event_context *ctx) | |||
1020 | cpuctx->cgrp = NULL; | 1031 | cpuctx->cgrp = NULL; |
1021 | } | 1032 | } |
1022 | 1033 | ||
1034 | if (has_branch_stack(event)) | ||
1035 | ctx->nr_branch_stack--; | ||
1036 | |||
1023 | ctx->nr_events--; | 1037 | ctx->nr_events--; |
1024 | if (event->attr.inherit_stat) | 1038 | if (event->attr.inherit_stat) |
1025 | ctx->nr_stat--; | 1039 | ctx->nr_stat--; |
@@ -2195,6 +2209,66 @@ static void perf_event_context_sched_in(struct perf_event_context *ctx, | |||
2195 | } | 2209 | } |
2196 | 2210 | ||
2197 | /* | 2211 | /* |
2212 | * When sampling the branck stack in system-wide, it may be necessary | ||
2213 | * to flush the stack on context switch. This happens when the branch | ||
2214 | * stack does not tag its entries with the pid of the current task. | ||
2215 | * Otherwise it becomes impossible to associate a branch entry with a | ||
2216 | * task. This ambiguity is more likely to appear when the branch stack | ||
2217 | * supports priv level filtering and the user sets it to monitor only | ||
2218 | * at the user level (which could be a useful measurement in system-wide | ||
2219 | * mode). In that case, the risk is high of having a branch stack with | ||
2220 | * branch from multiple tasks. Flushing may mean dropping the existing | ||
2221 | * entries or stashing them somewhere in the PMU specific code layer. | ||
2222 | * | ||
2223 | * This function provides the context switch callback to the lower code | ||
2224 | * layer. It is invoked ONLY when there is at least one system-wide context | ||
2225 | * with at least one active event using taken branch sampling. | ||
2226 | */ | ||
2227 | static void perf_branch_stack_sched_in(struct task_struct *prev, | ||
2228 | struct task_struct *task) | ||
2229 | { | ||
2230 | struct perf_cpu_context *cpuctx; | ||
2231 | struct pmu *pmu; | ||
2232 | unsigned long flags; | ||
2233 | |||
2234 | /* no need to flush branch stack if not changing task */ | ||
2235 | if (prev == task) | ||
2236 | return; | ||
2237 | |||
2238 | local_irq_save(flags); | ||
2239 | |||
2240 | rcu_read_lock(); | ||
2241 | |||
2242 | list_for_each_entry_rcu(pmu, &pmus, entry) { | ||
2243 | cpuctx = this_cpu_ptr(pmu->pmu_cpu_context); | ||
2244 | |||
2245 | /* | ||
2246 | * check if the context has at least one | ||
2247 | * event using PERF_SAMPLE_BRANCH_STACK | ||
2248 | */ | ||
2249 | if (cpuctx->ctx.nr_branch_stack > 0 | ||
2250 | && pmu->flush_branch_stack) { | ||
2251 | |||
2252 | pmu = cpuctx->ctx.pmu; | ||
2253 | |||
2254 | perf_ctx_lock(cpuctx, cpuctx->task_ctx); | ||
2255 | |||
2256 | perf_pmu_disable(pmu); | ||
2257 | |||
2258 | pmu->flush_branch_stack(); | ||
2259 | |||
2260 | perf_pmu_enable(pmu); | ||
2261 | |||
2262 | perf_ctx_unlock(cpuctx, cpuctx->task_ctx); | ||
2263 | } | ||
2264 | } | ||
2265 | |||
2266 | rcu_read_unlock(); | ||
2267 | |||
2268 | local_irq_restore(flags); | ||
2269 | } | ||
2270 | |||
2271 | /* | ||
2198 | * Called from scheduler to add the events of the current task | 2272 | * Called from scheduler to add the events of the current task |
2199 | * with interrupts disabled. | 2273 | * with interrupts disabled. |
2200 | * | 2274 | * |
@@ -2225,6 +2299,10 @@ void __perf_event_task_sched_in(struct task_struct *prev, | |||
2225 | */ | 2299 | */ |
2226 | if (atomic_read(&__get_cpu_var(perf_cgroup_events))) | 2300 | if (atomic_read(&__get_cpu_var(perf_cgroup_events))) |
2227 | perf_cgroup_sched_in(prev, task); | 2301 | perf_cgroup_sched_in(prev, task); |
2302 | |||
2303 | /* check for system-wide branch_stack events */ | ||
2304 | if (atomic_read(&__get_cpu_var(perf_branch_stack_events))) | ||
2305 | perf_branch_stack_sched_in(prev, task); | ||
2228 | } | 2306 | } |
2229 | 2307 | ||
2230 | static u64 perf_calculate_period(struct perf_event *event, u64 nsec, u64 count) | 2308 | static u64 perf_calculate_period(struct perf_event *event, u64 nsec, u64 count) |
@@ -2778,7 +2856,7 @@ static void free_event(struct perf_event *event) | |||
2778 | 2856 | ||
2779 | if (!event->parent) { | 2857 | if (!event->parent) { |
2780 | if (event->attach_state & PERF_ATTACH_TASK) | 2858 | if (event->attach_state & PERF_ATTACH_TASK) |
2781 | jump_label_dec_deferred(&perf_sched_events); | 2859 | static_key_slow_dec_deferred(&perf_sched_events); |
2782 | if (event->attr.mmap || event->attr.mmap_data) | 2860 | if (event->attr.mmap || event->attr.mmap_data) |
2783 | atomic_dec(&nr_mmap_events); | 2861 | atomic_dec(&nr_mmap_events); |
2784 | if (event->attr.comm) | 2862 | if (event->attr.comm) |
@@ -2789,7 +2867,15 @@ static void free_event(struct perf_event *event) | |||
2789 | put_callchain_buffers(); | 2867 | put_callchain_buffers(); |
2790 | if (is_cgroup_event(event)) { | 2868 | if (is_cgroup_event(event)) { |
2791 | atomic_dec(&per_cpu(perf_cgroup_events, event->cpu)); | 2869 | atomic_dec(&per_cpu(perf_cgroup_events, event->cpu)); |
2792 | jump_label_dec_deferred(&perf_sched_events); | 2870 | static_key_slow_dec_deferred(&perf_sched_events); |
2871 | } | ||
2872 | |||
2873 | if (has_branch_stack(event)) { | ||
2874 | static_key_slow_dec_deferred(&perf_sched_events); | ||
2875 | /* is system-wide event */ | ||
2876 | if (!(event->attach_state & PERF_ATTACH_TASK)) | ||
2877 | atomic_dec(&per_cpu(perf_branch_stack_events, | ||
2878 | event->cpu)); | ||
2793 | } | 2879 | } |
2794 | } | 2880 | } |
2795 | 2881 | ||
@@ -3262,7 +3348,7 @@ static void calc_timer_values(struct perf_event *event, | |||
3262 | *running = ctx_time - event->tstamp_running; | 3348 | *running = ctx_time - event->tstamp_running; |
3263 | } | 3349 | } |
3264 | 3350 | ||
3265 | void __weak perf_update_user_clock(struct perf_event_mmap_page *userpg, u64 now) | 3351 | void __weak arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now) |
3266 | { | 3352 | { |
3267 | } | 3353 | } |
3268 | 3354 | ||
@@ -3312,7 +3398,7 @@ void perf_event_update_userpage(struct perf_event *event) | |||
3312 | userpg->time_running = running + | 3398 | userpg->time_running = running + |
3313 | atomic64_read(&event->child_total_time_running); | 3399 | atomic64_read(&event->child_total_time_running); |
3314 | 3400 | ||
3315 | perf_update_user_clock(userpg, now); | 3401 | arch_perf_update_userpage(userpg, now); |
3316 | 3402 | ||
3317 | barrier(); | 3403 | barrier(); |
3318 | ++userpg->lock; | 3404 | ++userpg->lock; |
@@ -3907,6 +3993,24 @@ void perf_output_sample(struct perf_output_handle *handle, | |||
3907 | } | 3993 | } |
3908 | } | 3994 | } |
3909 | } | 3995 | } |
3996 | |||
3997 | if (sample_type & PERF_SAMPLE_BRANCH_STACK) { | ||
3998 | if (data->br_stack) { | ||
3999 | size_t size; | ||
4000 | |||
4001 | size = data->br_stack->nr | ||
4002 | * sizeof(struct perf_branch_entry); | ||
4003 | |||
4004 | perf_output_put(handle, data->br_stack->nr); | ||
4005 | perf_output_copy(handle, data->br_stack->entries, size); | ||
4006 | } else { | ||
4007 | /* | ||
4008 | * we always store at least the value of nr | ||
4009 | */ | ||
4010 | u64 nr = 0; | ||
4011 | perf_output_put(handle, nr); | ||
4012 | } | ||
4013 | } | ||
3910 | } | 4014 | } |
3911 | 4015 | ||
3912 | void perf_prepare_sample(struct perf_event_header *header, | 4016 | void perf_prepare_sample(struct perf_event_header *header, |
@@ -3949,6 +4053,15 @@ void perf_prepare_sample(struct perf_event_header *header, | |||
3949 | WARN_ON_ONCE(size & (sizeof(u64)-1)); | 4053 | WARN_ON_ONCE(size & (sizeof(u64)-1)); |
3950 | header->size += size; | 4054 | header->size += size; |
3951 | } | 4055 | } |
4056 | |||
4057 | if (sample_type & PERF_SAMPLE_BRANCH_STACK) { | ||
4058 | int size = sizeof(u64); /* nr */ | ||
4059 | if (data->br_stack) { | ||
4060 | size += data->br_stack->nr | ||
4061 | * sizeof(struct perf_branch_entry); | ||
4062 | } | ||
4063 | header->size += size; | ||
4064 | } | ||
3952 | } | 4065 | } |
3953 | 4066 | ||
3954 | static void perf_event_output(struct perf_event *event, | 4067 | static void perf_event_output(struct perf_event *event, |
@@ -4991,7 +5104,7 @@ fail: | |||
4991 | return err; | 5104 | return err; |
4992 | } | 5105 | } |
4993 | 5106 | ||
4994 | struct jump_label_key perf_swevent_enabled[PERF_COUNT_SW_MAX]; | 5107 | struct static_key perf_swevent_enabled[PERF_COUNT_SW_MAX]; |
4995 | 5108 | ||
4996 | static void sw_perf_event_destroy(struct perf_event *event) | 5109 | static void sw_perf_event_destroy(struct perf_event *event) |
4997 | { | 5110 | { |
@@ -4999,7 +5112,7 @@ static void sw_perf_event_destroy(struct perf_event *event) | |||
4999 | 5112 | ||
5000 | WARN_ON(event->parent); | 5113 | WARN_ON(event->parent); |
5001 | 5114 | ||
5002 | jump_label_dec(&perf_swevent_enabled[event_id]); | 5115 | static_key_slow_dec(&perf_swevent_enabled[event_id]); |
5003 | swevent_hlist_put(event); | 5116 | swevent_hlist_put(event); |
5004 | } | 5117 | } |
5005 | 5118 | ||
@@ -5010,6 +5123,12 @@ static int perf_swevent_init(struct perf_event *event) | |||
5010 | if (event->attr.type != PERF_TYPE_SOFTWARE) | 5123 | if (event->attr.type != PERF_TYPE_SOFTWARE) |
5011 | return -ENOENT; | 5124 | return -ENOENT; |
5012 | 5125 | ||
5126 | /* | ||
5127 | * no branch sampling for software events | ||
5128 | */ | ||
5129 | if (has_branch_stack(event)) | ||
5130 | return -EOPNOTSUPP; | ||
5131 | |||
5013 | switch (event_id) { | 5132 | switch (event_id) { |
5014 | case PERF_COUNT_SW_CPU_CLOCK: | 5133 | case PERF_COUNT_SW_CPU_CLOCK: |
5015 | case PERF_COUNT_SW_TASK_CLOCK: | 5134 | case PERF_COUNT_SW_TASK_CLOCK: |
@@ -5029,7 +5148,7 @@ static int perf_swevent_init(struct perf_event *event) | |||
5029 | if (err) | 5148 | if (err) |
5030 | return err; | 5149 | return err; |
5031 | 5150 | ||
5032 | jump_label_inc(&perf_swevent_enabled[event_id]); | 5151 | static_key_slow_inc(&perf_swevent_enabled[event_id]); |
5033 | event->destroy = sw_perf_event_destroy; | 5152 | event->destroy = sw_perf_event_destroy; |
5034 | } | 5153 | } |
5035 | 5154 | ||
@@ -5120,6 +5239,12 @@ static int perf_tp_event_init(struct perf_event *event) | |||
5120 | if (event->attr.type != PERF_TYPE_TRACEPOINT) | 5239 | if (event->attr.type != PERF_TYPE_TRACEPOINT) |
5121 | return -ENOENT; | 5240 | return -ENOENT; |
5122 | 5241 | ||
5242 | /* | ||
5243 | * no branch sampling for tracepoint events | ||
5244 | */ | ||
5245 | if (has_branch_stack(event)) | ||
5246 | return -EOPNOTSUPP; | ||
5247 | |||
5123 | err = perf_trace_init(event); | 5248 | err = perf_trace_init(event); |
5124 | if (err) | 5249 | if (err) |
5125 | return err; | 5250 | return err; |
@@ -5345,6 +5470,12 @@ static int cpu_clock_event_init(struct perf_event *event) | |||
5345 | if (event->attr.config != PERF_COUNT_SW_CPU_CLOCK) | 5470 | if (event->attr.config != PERF_COUNT_SW_CPU_CLOCK) |
5346 | return -ENOENT; | 5471 | return -ENOENT; |
5347 | 5472 | ||
5473 | /* | ||
5474 | * no branch sampling for software events | ||
5475 | */ | ||
5476 | if (has_branch_stack(event)) | ||
5477 | return -EOPNOTSUPP; | ||
5478 | |||
5348 | perf_swevent_init_hrtimer(event); | 5479 | perf_swevent_init_hrtimer(event); |
5349 | 5480 | ||
5350 | return 0; | 5481 | return 0; |
@@ -5419,6 +5550,12 @@ static int task_clock_event_init(struct perf_event *event) | |||
5419 | if (event->attr.config != PERF_COUNT_SW_TASK_CLOCK) | 5550 | if (event->attr.config != PERF_COUNT_SW_TASK_CLOCK) |
5420 | return -ENOENT; | 5551 | return -ENOENT; |
5421 | 5552 | ||
5553 | /* | ||
5554 | * no branch sampling for software events | ||
5555 | */ | ||
5556 | if (has_branch_stack(event)) | ||
5557 | return -EOPNOTSUPP; | ||
5558 | |||
5422 | perf_swevent_init_hrtimer(event); | 5559 | perf_swevent_init_hrtimer(event); |
5423 | 5560 | ||
5424 | return 0; | 5561 | return 0; |
@@ -5852,7 +5989,7 @@ done: | |||
5852 | 5989 | ||
5853 | if (!event->parent) { | 5990 | if (!event->parent) { |
5854 | if (event->attach_state & PERF_ATTACH_TASK) | 5991 | if (event->attach_state & PERF_ATTACH_TASK) |
5855 | jump_label_inc(&perf_sched_events.key); | 5992 | static_key_slow_inc(&perf_sched_events.key); |
5856 | if (event->attr.mmap || event->attr.mmap_data) | 5993 | if (event->attr.mmap || event->attr.mmap_data) |
5857 | atomic_inc(&nr_mmap_events); | 5994 | atomic_inc(&nr_mmap_events); |
5858 | if (event->attr.comm) | 5995 | if (event->attr.comm) |
@@ -5866,6 +6003,12 @@ done: | |||
5866 | return ERR_PTR(err); | 6003 | return ERR_PTR(err); |
5867 | } | 6004 | } |
5868 | } | 6005 | } |
6006 | if (has_branch_stack(event)) { | ||
6007 | static_key_slow_inc(&perf_sched_events.key); | ||
6008 | if (!(event->attach_state & PERF_ATTACH_TASK)) | ||
6009 | atomic_inc(&per_cpu(perf_branch_stack_events, | ||
6010 | event->cpu)); | ||
6011 | } | ||
5869 | } | 6012 | } |
5870 | 6013 | ||
5871 | return event; | 6014 | return event; |
@@ -5935,6 +6078,40 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr, | |||
5935 | if (attr->read_format & ~(PERF_FORMAT_MAX-1)) | 6078 | if (attr->read_format & ~(PERF_FORMAT_MAX-1)) |
5936 | return -EINVAL; | 6079 | return -EINVAL; |
5937 | 6080 | ||
6081 | if (attr->sample_type & PERF_SAMPLE_BRANCH_STACK) { | ||
6082 | u64 mask = attr->branch_sample_type; | ||
6083 | |||
6084 | /* only using defined bits */ | ||
6085 | if (mask & ~(PERF_SAMPLE_BRANCH_MAX-1)) | ||
6086 | return -EINVAL; | ||
6087 | |||
6088 | /* at least one branch bit must be set */ | ||
6089 | if (!(mask & ~PERF_SAMPLE_BRANCH_PLM_ALL)) | ||
6090 | return -EINVAL; | ||
6091 | |||
6092 | /* kernel level capture: check permissions */ | ||
6093 | if ((mask & PERF_SAMPLE_BRANCH_PERM_PLM) | ||
6094 | && perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN)) | ||
6095 | return -EACCES; | ||
6096 | |||
6097 | /* propagate priv level, when not set for branch */ | ||
6098 | if (!(mask & PERF_SAMPLE_BRANCH_PLM_ALL)) { | ||
6099 | |||
6100 | /* exclude_kernel checked on syscall entry */ | ||
6101 | if (!attr->exclude_kernel) | ||
6102 | mask |= PERF_SAMPLE_BRANCH_KERNEL; | ||
6103 | |||
6104 | if (!attr->exclude_user) | ||
6105 | mask |= PERF_SAMPLE_BRANCH_USER; | ||
6106 | |||
6107 | if (!attr->exclude_hv) | ||
6108 | mask |= PERF_SAMPLE_BRANCH_HV; | ||
6109 | /* | ||
6110 | * adjust user setting (for HW filter setup) | ||
6111 | */ | ||
6112 | attr->branch_sample_type = mask; | ||
6113 | } | ||
6114 | } | ||
5938 | out: | 6115 | out: |
5939 | return ret; | 6116 | return ret; |
5940 | 6117 | ||
@@ -6090,7 +6267,7 @@ SYSCALL_DEFINE5(perf_event_open, | |||
6090 | * - that may need work on context switch | 6267 | * - that may need work on context switch |
6091 | */ | 6268 | */ |
6092 | atomic_inc(&per_cpu(perf_cgroup_events, event->cpu)); | 6269 | atomic_inc(&per_cpu(perf_cgroup_events, event->cpu)); |
6093 | jump_label_inc(&perf_sched_events.key); | 6270 | static_key_slow_inc(&perf_sched_events.key); |
6094 | } | 6271 | } |
6095 | 6272 | ||
6096 | /* | 6273 | /* |
@@ -6939,6 +7116,13 @@ void __init perf_event_init(void) | |||
6939 | 7116 | ||
6940 | /* do not patch jump label more than once per second */ | 7117 | /* do not patch jump label more than once per second */ |
6941 | jump_label_rate_limit(&perf_sched_events, HZ); | 7118 | jump_label_rate_limit(&perf_sched_events, HZ); |
7119 | |||
7120 | /* | ||
7121 | * Build time assertion that we keep the data_head at the intended | ||
7122 | * location. IOW, validation we got the __reserved[] size right. | ||
7123 | */ | ||
7124 | BUILD_BUG_ON((offsetof(struct perf_event_mmap_page, data_head)) | ||
7125 | != 1024); | ||
6942 | } | 7126 | } |
6943 | 7127 | ||
6944 | static int __init perf_event_sysfs_init(void) | 7128 | static int __init perf_event_sysfs_init(void) |
@@ -6970,8 +7154,7 @@ unlock: | |||
6970 | device_initcall(perf_event_sysfs_init); | 7154 | device_initcall(perf_event_sysfs_init); |
6971 | 7155 | ||
6972 | #ifdef CONFIG_CGROUP_PERF | 7156 | #ifdef CONFIG_CGROUP_PERF |
6973 | static struct cgroup_subsys_state *perf_cgroup_create( | 7157 | static struct cgroup_subsys_state *perf_cgroup_create(struct cgroup *cont) |
6974 | struct cgroup_subsys *ss, struct cgroup *cont) | ||
6975 | { | 7158 | { |
6976 | struct perf_cgroup *jc; | 7159 | struct perf_cgroup *jc; |
6977 | 7160 | ||
@@ -6988,8 +7171,7 @@ static struct cgroup_subsys_state *perf_cgroup_create( | |||
6988 | return &jc->css; | 7171 | return &jc->css; |
6989 | } | 7172 | } |
6990 | 7173 | ||
6991 | static void perf_cgroup_destroy(struct cgroup_subsys *ss, | 7174 | static void perf_cgroup_destroy(struct cgroup *cont) |
6992 | struct cgroup *cont) | ||
6993 | { | 7175 | { |
6994 | struct perf_cgroup *jc; | 7176 | struct perf_cgroup *jc; |
6995 | jc = container_of(cgroup_subsys_state(cont, perf_subsys_id), | 7177 | jc = container_of(cgroup_subsys_state(cont, perf_subsys_id), |
@@ -7005,8 +7187,7 @@ static int __perf_cgroup_move(void *info) | |||
7005 | return 0; | 7187 | return 0; |
7006 | } | 7188 | } |
7007 | 7189 | ||
7008 | static void perf_cgroup_attach(struct cgroup_subsys *ss, struct cgroup *cgrp, | 7190 | static void perf_cgroup_attach(struct cgroup *cgrp, struct cgroup_taskset *tset) |
7009 | struct cgroup_taskset *tset) | ||
7010 | { | 7191 | { |
7011 | struct task_struct *task; | 7192 | struct task_struct *task; |
7012 | 7193 | ||
@@ -7014,8 +7195,8 @@ static void perf_cgroup_attach(struct cgroup_subsys *ss, struct cgroup *cgrp, | |||
7014 | task_function_call(task, __perf_cgroup_move, task); | 7195 | task_function_call(task, __perf_cgroup_move, task); |
7015 | } | 7196 | } |
7016 | 7197 | ||
7017 | static void perf_cgroup_exit(struct cgroup_subsys *ss, struct cgroup *cgrp, | 7198 | static void perf_cgroup_exit(struct cgroup *cgrp, struct cgroup *old_cgrp, |
7018 | struct cgroup *old_cgrp, struct task_struct *task) | 7199 | struct task_struct *task) |
7019 | { | 7200 | { |
7020 | /* | 7201 | /* |
7021 | * cgroup_exit() is called in the copy_process() failure path. | 7202 | * cgroup_exit() is called in the copy_process() failure path. |
diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c index 3330022a7ac1..bb38c4d3ee12 100644 --- a/kernel/events/hw_breakpoint.c +++ b/kernel/events/hw_breakpoint.c | |||
@@ -581,6 +581,12 @@ static int hw_breakpoint_event_init(struct perf_event *bp) | |||
581 | if (bp->attr.type != PERF_TYPE_BREAKPOINT) | 581 | if (bp->attr.type != PERF_TYPE_BREAKPOINT) |
582 | return -ENOENT; | 582 | return -ENOENT; |
583 | 583 | ||
584 | /* | ||
585 | * no branch sampling for breakpoint events | ||
586 | */ | ||
587 | if (has_branch_stack(bp)) | ||
588 | return -EOPNOTSUPP; | ||
589 | |||
584 | err = register_perf_hw_breakpoint(bp); | 590 | err = register_perf_hw_breakpoint(bp); |
585 | if (err) | 591 | if (err) |
586 | return err; | 592 | return err; |