[RFC,3/5] perf: Add namespaces to the sideband ioctl
Commit Message
Support the case of output to an active event, and return an error if
output is not possible in that case. Set PERF_RECORD_MISC_STATUS_ONLY to
differentiate the ioctl status-only sideband event from a "real" sideband
event.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
kernel/events/core.c | 26 ++++++++++++++++----------
1 file changed, 16 insertions(+), 10 deletions(-)
@@ -8364,8 +8364,7 @@ static int perf_event_namespaces_match(struct perf_event *event)
return event->attr.namespaces;
}
-static void perf_event_namespaces_output(struct perf_event *event,
- void *data)
+static int perf_event_namespaces_output(struct perf_event *event, void *data)
{
struct perf_namespaces_event *namespaces_event = data;
struct perf_output_handle handle;
@@ -8374,7 +8373,7 @@ static void perf_event_namespaces_output(struct perf_event *event,
int ret;
if (!perf_event_namespaces_match(event))
- return;
+ return -ENOENT;
perf_event_header__init_id(&namespaces_event->event_id.header,
&sample, event);
@@ -8395,6 +8394,7 @@ static void perf_event_namespaces_output(struct perf_event *event,
perf_output_end(&handle);
out:
namespaces_event->event_id.header.size = header_size;
+ return ret;
}
static void perf_fill_ns_link_info(struct perf_ns_link_info *ns_link_info,
@@ -8414,20 +8414,20 @@ static void perf_fill_ns_link_info(struct perf_ns_link_info *ns_link_info,
}
}
-void perf_event_namespaces(struct task_struct *task)
+static int __perf_event_namespaces(struct task_struct *task, struct perf_event *event)
{
struct perf_namespaces_event namespaces_event;
struct perf_ns_link_info *ns_link_info;
if (!atomic_read(&nr_namespaces_events))
- return;
+ return -ENOENT;
namespaces_event = (struct perf_namespaces_event){
.task = task,
.event_id = {
.header = {
.type = PERF_RECORD_NAMESPACES,
- .misc = 0,
+ .misc = event ? PERF_RECORD_MISC_STATUS_ONLY : 0,
.size = sizeof(namespaces_event.event_id),
},
/* .pid */
@@ -8467,9 +8467,12 @@ void perf_event_namespaces(struct task_struct *task)
task, &cgroupns_operations);
#endif
- perf_iterate_sb(perf_event_namespaces_output,
- &namespaces_event,
- NULL);
+ return perf_output_sb(perf_event_namespaces_output, &namespaces_event, NULL, event);
+}
+
+void perf_event_namespaces(struct task_struct *task)
+{
+ __perf_event_namespaces(task, NULL);
}
/*
@@ -12880,7 +12883,10 @@ static int perf_event_emit_fork(struct perf_event *event, struct task_struct *ta
static int perf_event_emit_namespaces(struct perf_event *event, struct task_struct *task)
{
- return -EINVAL;
+ if (!event->attr.namespaces)
+ return -EINVAL;
+
+ return __perf_event_namespaces(task, event);
}
static int perf_event_emit_comm(struct perf_event *event, struct task_struct *task)