perf: Fix ring_buffer perf_output_space() boundary calculation
authorStephane Eranian <eranian@google.com>
Mon, 18 Mar 2013 13:33:28 +0000 (14:33 +0100)
committerIngo Molnar <mingo@kernel.org>
Thu, 21 Mar 2013 11:04:35 +0000 (12:04 +0100)
commitdd9c086d9f507d02d5ba4d7c5eef4bb9518088b8
tree581aba3f0c5417f9b6c25824e4364da82f731431
parent0e48026ae7abf871e51eaa9183c81ab5bef4c267
perf: Fix ring_buffer perf_output_space() boundary calculation

This patch fixes a flaw in perf_output_space(). In case the size
of the space needed is bigger than the actual buffer size, there
may be situations where the function would return true (i.e.,
there is space) when it should not. head > offset due to
rounding of the masking logic.

The problem can be tested by activating BTS on Intel processors.
A BTS record can be as big as 16 pages. The following command
fails:

  $ perf record -m 4 -c 1 -e branches:u my_test_program

You will get a buffer corruption with this. Perf report won't be
able to parse the perf.data.

The fix is to first check that the requested space is smaller
than the buffer size. If so, then the masking logic will work
fine. If not, then there is no chance the record can be saved
and it will be gracefully handled by upper code layers.

[ In v2, we also make the logic for the writable more explicit by
  renaming it to rb->overwrite because it tells whether or not the
  buffer can overwrite its tail (suggested by PeterZ). ]

Signed-off-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: peterz@infradead.org
Cc: jolsa@redhat.com
Cc: fweisbec@gmail.com
Link: http://lkml.kernel.org/r/20130318133327.GA3056@quad
Signed-off-by: Ingo Molnar <mingo@kernel.org>
kernel/events/internal.h
kernel/events/ring_buffer.c