perf: Make perf_event_output() propagate the output() return
For the original mode of operation it isn't needed, since we report back errors via PERF_RECORD_LOST records in the ring buffer, but for use in bpf_perf_event_output() it is convenient to return the errors, basically -ENOSPC. Currently bpf_perf_event_output() returns an error indication, the last thing it does, which is to push it to the ring buffer is that can fail and if so, this failure won't be reported back to its users, fix it. Reported-by: Jamal Hadi Salim <jhs@mojatatu.com> Tested-by: Jamal Hadi Salim <jhs@mojatatu.com> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexei Starovoitov <alexei.starovoitov@gmail.com> Cc: Daniel Borkmann <daniel@iogearbox.net> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Link: https://lkml.kernel.org/r/20190118150938.GN5823@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
@@ -6489,7 +6489,7 @@ void perf_prepare_sample(struct perf_event_header *header,
|
||||
data->phys_addr = perf_virt_to_phys(data->addr);
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
static __always_inline int
|
||||
__perf_event_output(struct perf_event *event,
|
||||
struct perf_sample_data *data,
|
||||
struct pt_regs *regs,
|
||||
@@ -6499,13 +6499,15 @@ __perf_event_output(struct perf_event *event,
|
||||
{
|
||||
struct perf_output_handle handle;
|
||||
struct perf_event_header header;
|
||||
int err;
|
||||
|
||||
/* protect the callchain buffers */
|
||||
rcu_read_lock();
|
||||
|
||||
perf_prepare_sample(&header, data, event, regs);
|
||||
|
||||
if (output_begin(&handle, event, header.size))
|
||||
err = output_begin(&handle, event, header.size);
|
||||
if (err)
|
||||
goto exit;
|
||||
|
||||
perf_output_sample(&handle, &header, data, event);
|
||||
@@ -6514,6 +6516,7 @@ __perf_event_output(struct perf_event *event,
|
||||
|
||||
exit:
|
||||
rcu_read_unlock();
|
||||
return err;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -6532,12 +6535,12 @@ perf_event_output_backward(struct perf_event *event,
|
||||
__perf_event_output(event, data, regs, perf_output_begin_backward);
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
perf_event_output(struct perf_event *event,
|
||||
struct perf_sample_data *data,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
__perf_event_output(event, data, regs, perf_output_begin);
|
||||
return __perf_event_output(event, data, regs, perf_output_begin);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -431,8 +431,7 @@ __bpf_perf_event_output(struct pt_regs *regs, struct bpf_map *map,
|
||||
if (unlikely(event->oncpu != cpu))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
perf_event_output(event, sd, regs);
|
||||
return 0;
|
||||
return perf_event_output(event, sd, regs);
|
||||
}
|
||||
|
||||
BPF_CALL_5(bpf_perf_event_output, struct pt_regs *, regs, struct bpf_map *, map,
|
||||
|
Reference in New Issue
Block a user