diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-14 11:10:44 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-14 11:10:44 -0700 |
commit | ae9f4939bad09767c0532f76ccc48cec0ff3ea4e (patch) | |
tree | 7574e26436530fc3c10c848e0b740f05bb02930c /kernel/events/ring_buffer.c | |
parent | 93263e5283d5c2bc447bc42956f4fa58a3a0a63a (diff) | |
parent | c481420248c6730246d2a1b1773d5d7007ae0835 (diff) |
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf fixes from Ingo Molnar:
"Misc fixlets"
* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf: Fix error return code
ftrace: Fix strncpy() use, use strlcpy() instead of strncpy()
perf: Fix strncpy() use, use strlcpy() instead of strncpy()
perf: Fix strncpy() use, always make sure it's NUL terminated
perf: Fix ring_buffer perf_output_space() boundary calculation
perf/x86: Fix uninitialized pt_regs in intel_pmu_drain_bts_buffer()
Diffstat (limited to 'kernel/events/ring_buffer.c')
-rw-r--r-- | kernel/events/ring_buffer.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c index 23cb34ff397..97fddb09762 100644 --- a/kernel/events/ring_buffer.c +++ b/kernel/events/ring_buffer.c @@ -18,12 +18,24 @@ static bool perf_output_space(struct ring_buffer *rb, unsigned long tail, unsigned long offset, unsigned long head) { - unsigned long mask; + unsigned long sz = perf_data_size(rb); + unsigned long mask = sz - 1; - if (!rb->writable) + /* + * check if user-writable + * overwrite : over-write its own tail + * !overwrite: buffer possibly drops events. + */ + if (rb->overwrite) return true; - mask = perf_data_size(rb) - 1; + /* + * verify that payload is not bigger than buffer + * otherwise masking logic may fail to detect + * the "not enough space" condition + */ + if ((head - offset) > sz) + return false; offset = (offset - tail) & mask; head = (head - tail) & mask; @@ -212,7 +224,9 @@ ring_buffer_init(struct ring_buffer *rb, long watermark, int flags) rb->watermark = max_size / 2; if (flags & RING_BUFFER_WRITABLE) - rb->writable = 1; + rb->overwrite = 0; + else + rb->overwrite = 1; atomic_set(&rb->refcount, 1); |