@@ -4828,6 +4828,11 @@ find_get_pmu_context(struct pmu *pmu, struct perf_event_context *ctx,
48284828 void * task_ctx_data = NULL ;
48294829
48304830 if (!ctx -> task ) {
4831+ /*
4832+ * perf_pmu_migrate_context() / __perf_pmu_install_event()
4833+ * relies on the fact that find_get_pmu_context() cannot fail
4834+ * for CPU contexts.
4835+ */
48314836 struct perf_cpu_pmu_context * cpc ;
48324837
48334838 cpc = per_cpu_ptr (pmu -> cpu_pmu_context , event -> cpu );
@@ -12889,6 +12894,9 @@ static void __perf_pmu_install_event(struct pmu *pmu,
1288912894 int cpu , struct perf_event * event )
1289012895{
1289112896 struct perf_event_pmu_context * epc ;
12897+ struct perf_event_context * old_ctx = event -> ctx ;
12898+
12899+ get_ctx (ctx ); /* normally find_get_context() */
1289212900
1289312901 event -> cpu = cpu ;
1289412902 epc = find_get_pmu_context (pmu , ctx , event );
@@ -12897,6 +12905,11 @@ static void __perf_pmu_install_event(struct pmu *pmu,
1289712905 if (event -> state >= PERF_EVENT_STATE_OFF )
1289812906 event -> state = PERF_EVENT_STATE_INACTIVE ;
1289912907 perf_install_in_context (ctx , event , cpu );
12908+
12909+ /*
12910+ * Now that event->ctx is updated and visible, put the old ctx.
12911+ */
12912+ put_ctx (old_ctx );
1290012913}
1290112914
1290212915static void __perf_pmu_install (struct perf_event_context * ctx ,
@@ -12935,6 +12948,10 @@ void perf_pmu_migrate_context(struct pmu *pmu, int src_cpu, int dst_cpu)
1293512948 struct perf_event_context * src_ctx , * dst_ctx ;
1293612949 LIST_HEAD (events );
1293712950
12951+ /*
12952+ * Since per-cpu context is persistent, no need to grab an extra
12953+ * reference.
12954+ */
1293812955 src_ctx = & per_cpu_ptr (& perf_cpu_context , src_cpu )-> ctx ;
1293912956 dst_ctx = & per_cpu_ptr (& perf_cpu_context , dst_cpu )-> ctx ;
1294012957
0 commit comments