|
@@ -907,6 +907,15 @@ list_add_event(struct perf_event *event, struct perf_event_context *ctx)
|
|
|
ctx->nr_stat++;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Initialize event state based on the perf_event_attr::disabled.
|
|
|
+ */
|
|
|
+static inline void perf_event__state_init(struct perf_event *event)
|
|
|
+{
|
|
|
+ event->state = event->attr.disabled ? PERF_EVENT_STATE_OFF :
|
|
|
+ PERF_EVENT_STATE_INACTIVE;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Called at perf_event creation and when events are attached/detached from a
|
|
|
* group.
|
|
@@ -6179,8 +6188,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
|
|
|
event->overflow_handler = overflow_handler;
|
|
|
event->overflow_handler_context = context;
|
|
|
|
|
|
- if (attr->disabled)
|
|
|
- event->state = PERF_EVENT_STATE_OFF;
|
|
|
+ perf_event__state_init(event);
|
|
|
|
|
|
pmu = NULL;
|
|
|
|
|
@@ -6609,9 +6617,17 @@ SYSCALL_DEFINE5(perf_event_open,
|
|
|
|
|
|
mutex_lock(&gctx->mutex);
|
|
|
perf_remove_from_context(group_leader);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Removing from the context ends up with disabled
|
|
|
+ * event. What we want here is event in the initial
|
|
|
+ * startup state, ready to be add into new context.
|
|
|
+ */
|
|
|
+ perf_event__state_init(group_leader);
|
|
|
list_for_each_entry(sibling, &group_leader->sibling_list,
|
|
|
group_entry) {
|
|
|
perf_remove_from_context(sibling);
|
|
|
+ perf_event__state_init(sibling);
|
|
|
put_ctx(gctx);
|
|
|
}
|
|
|
mutex_unlock(&gctx->mutex);
|