|
@@ -4920,6 +4920,13 @@ static int perf_event_set_output(struct perf_event *event, int output_fd)
|
|
int fput_needed = 0;
|
|
int fput_needed = 0;
|
|
int ret = -EINVAL;
|
|
int ret = -EINVAL;
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Don't allow output of inherited per-task events. This would
|
|
|
|
+ * create performance issues due to cross cpu access.
|
|
|
|
+ */
|
|
|
|
+ if (event->cpu == -1 && event->attr.inherit)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+
|
|
if (!output_fd)
|
|
if (!output_fd)
|
|
goto set;
|
|
goto set;
|
|
|
|
|
|
@@ -4940,6 +4947,18 @@ static int perf_event_set_output(struct perf_event *event, int output_fd)
|
|
if (event->data)
|
|
if (event->data)
|
|
goto out;
|
|
goto out;
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Don't allow cross-cpu buffers
|
|
|
|
+ */
|
|
|
|
+ if (output_event->cpu != event->cpu)
|
|
|
|
+ goto out;
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * If its not a per-cpu buffer, it must be the same task.
|
|
|
|
+ */
|
|
|
|
+ if (output_event->cpu == -1 && output_event->ctx != event->ctx)
|
|
|
|
+ goto out;
|
|
|
|
+
|
|
atomic_long_inc(&output_file->f_count);
|
|
atomic_long_inc(&output_file->f_count);
|
|
|
|
|
|
set:
|
|
set:
|