|
@@ -7645,16 +7645,9 @@ SYSCALL_DEFINE5(perf_event_open,
|
|
|
|
|
|
perf_remove_from_context(group_leader, false);
|
|
|
|
|
|
- /*
|
|
|
- * 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, false);
|
|
|
- perf_event__state_init(sibling);
|
|
|
put_ctx(gctx);
|
|
|
}
|
|
|
} else {
|
|
@@ -7670,13 +7663,31 @@ SYSCALL_DEFINE5(perf_event_open,
|
|
|
*/
|
|
|
synchronize_rcu();
|
|
|
|
|
|
- perf_install_in_context(ctx, group_leader, group_leader->cpu);
|
|
|
- get_ctx(ctx);
|
|
|
+ /*
|
|
|
+ * Install the group siblings before the group leader.
|
|
|
+ *
|
|
|
+ * Because a group leader will try and install the entire group
|
|
|
+ * (through the sibling list, which is still in-tact), we can
|
|
|
+ * end up with siblings installed in the wrong context.
|
|
|
+ *
|
|
|
+ * By installing siblings first we NO-OP because they're not
|
|
|
+ * reachable through the group lists.
|
|
|
+ */
|
|
|
list_for_each_entry(sibling, &group_leader->sibling_list,
|
|
|
group_entry) {
|
|
|
+ perf_event__state_init(sibling);
|
|
|
perf_install_in_context(ctx, sibling, sibling->cpu);
|
|
|
get_ctx(ctx);
|
|
|
}
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 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);
|
|
|
+ perf_install_in_context(ctx, group_leader, group_leader->cpu);
|
|
|
+ get_ctx(ctx);
|
|
|
}
|
|
|
|
|
|
perf_install_in_context(ctx, event, event->cpu);
|
|
@@ -7806,8 +7817,35 @@ void perf_pmu_migrate_context(struct pmu *pmu, int src_cpu, int dst_cpu)
|
|
|
list_add(&event->migrate_entry, &events);
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * Wait for the events to quiesce before re-instating them.
|
|
|
+ */
|
|
|
synchronize_rcu();
|
|
|
|
|
|
+ /*
|
|
|
+ * Re-instate events in 2 passes.
|
|
|
+ *
|
|
|
+ * Skip over group leaders and only install siblings on this first
|
|
|
+ * pass, siblings will not get enabled without a leader, however a
|
|
|
+ * leader will enable its siblings, even if those are still on the old
|
|
|
+ * context.
|
|
|
+ */
|
|
|
+ list_for_each_entry_safe(event, tmp, &events, migrate_entry) {
|
|
|
+ if (event->group_leader == event)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ list_del(&event->migrate_entry);
|
|
|
+ if (event->state >= PERF_EVENT_STATE_OFF)
|
|
|
+ event->state = PERF_EVENT_STATE_INACTIVE;
|
|
|
+ account_event_cpu(event, dst_cpu);
|
|
|
+ perf_install_in_context(dst_ctx, event, dst_cpu);
|
|
|
+ get_ctx(dst_ctx);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Once all the siblings are setup properly, install the group leaders
|
|
|
+ * to make it go.
|
|
|
+ */
|
|
|
list_for_each_entry_safe(event, tmp, &events, migrate_entry) {
|
|
|
list_del(&event->migrate_entry);
|
|
|
if (event->state >= PERF_EVENT_STATE_OFF)
|