diff options
| -rw-r--r-- | kernel/events/core.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c index 301079d06f24..7b6646a8c067 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
| @@ -908,6 +908,15 @@ list_add_event(struct perf_event *event, struct perf_event_context *ctx) | |||
| 908 | } | 908 | } |
| 909 | 909 | ||
| 910 | /* | 910 | /* |
| 911 | * Initialize event state based on the perf_event_attr::disabled. | ||
| 912 | */ | ||
| 913 | static inline void perf_event__state_init(struct perf_event *event) | ||
| 914 | { | ||
| 915 | event->state = event->attr.disabled ? PERF_EVENT_STATE_OFF : | ||
| 916 | PERF_EVENT_STATE_INACTIVE; | ||
| 917 | } | ||
| 918 | |||
| 919 | /* | ||
| 911 | * Called at perf_event creation and when events are attached/detached from a | 920 | * Called at perf_event creation and when events are attached/detached from a |
| 912 | * group. | 921 | * group. |
| 913 | */ | 922 | */ |
| @@ -6179,8 +6188,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, | |||
| 6179 | event->overflow_handler = overflow_handler; | 6188 | event->overflow_handler = overflow_handler; |
| 6180 | event->overflow_handler_context = context; | 6189 | event->overflow_handler_context = context; |
| 6181 | 6190 | ||
| 6182 | if (attr->disabled) | 6191 | perf_event__state_init(event); |
| 6183 | event->state = PERF_EVENT_STATE_OFF; | ||
| 6184 | 6192 | ||
| 6185 | pmu = NULL; | 6193 | pmu = NULL; |
| 6186 | 6194 | ||
| @@ -6609,9 +6617,17 @@ SYSCALL_DEFINE5(perf_event_open, | |||
| 6609 | 6617 | ||
| 6610 | mutex_lock(&gctx->mutex); | 6618 | mutex_lock(&gctx->mutex); |
| 6611 | perf_remove_from_context(group_leader); | 6619 | perf_remove_from_context(group_leader); |
| 6620 | |||
| 6621 | /* | ||
| 6622 | * Removing from the context ends up with disabled | ||
| 6623 | * event. What we want here is event in the initial | ||
| 6624 | * startup state, ready to be add into new context. | ||
| 6625 | */ | ||
| 6626 | perf_event__state_init(group_leader); | ||
| 6612 | list_for_each_entry(sibling, &group_leader->sibling_list, | 6627 | list_for_each_entry(sibling, &group_leader->sibling_list, |
| 6613 | group_entry) { | 6628 | group_entry) { |
| 6614 | perf_remove_from_context(sibling); | 6629 | perf_remove_from_context(sibling); |
| 6630 | perf_event__state_init(sibling); | ||
| 6615 | put_ctx(gctx); | 6631 | put_ctx(gctx); |
| 6616 | } | 6632 | } |
| 6617 | mutex_unlock(&gctx->mutex); | 6633 | mutex_unlock(&gctx->mutex); |
