+#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(4,10,0))
+
+int lttng_cpuhp_perf_counter_online(unsigned int cpu,
+ struct lttng_cpuhp_node *node)
+{
+ struct lttng_perf_counter_field *perf_field =
+ container_of(node, struct lttng_perf_counter_field,
+ cpuhp_online);
+ struct perf_event **events = perf_field->e;
+ struct perf_event_attr *attr = perf_field->attr;
+ struct perf_event *pevent;
+
+ pevent = wrapper_perf_event_create_kernel_counter(attr,
+ cpu, NULL, overflow_callback);
+ if (!pevent || IS_ERR(pevent))
+ return -EINVAL;
+ if (pevent->state == PERF_EVENT_STATE_ERROR) {
+ perf_event_release_kernel(pevent);
+ return -EINVAL;
+ }
+ barrier(); /* Create perf counter before setting event */
+ events[cpu] = pevent;
+ return 0;
+}
+
+int lttng_cpuhp_perf_counter_dead(unsigned int cpu,
+ struct lttng_cpuhp_node *node)
+{
+ struct lttng_perf_counter_field *perf_field =
+ container_of(node, struct lttng_perf_counter_field,
+ cpuhp_prepare);
+ struct perf_event **events = perf_field->e;
+ struct perf_event *pevent;
+
+ pevent = events[cpu];
+ events[cpu] = NULL;
+ barrier(); /* NULLify event before perf counter teardown */
+ perf_event_release_kernel(pevent);
+ return 0;
+}
+
+#else /* #if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(4,10,0)) */
+