diff options
author | Peter Zijlstra <peterz@infradead.org> | 2009-06-08 12:18:39 -0400 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2009-06-08 18:50:20 -0400 |
commit | 1f8a6a10fb9437eac3f516ea4324a19087872f30 (patch) | |
tree | 944f73519ef205c3baccd130d93ed70f7e7bc790 /include/linux | |
parent | 918143e8b7d6153d7a83a3f854323407939f4a7e (diff) |
ring-buffer: pass in lockdep class key for reader_lock
On Sun, 7 Jun 2009, Ingo Molnar wrote:
> Testing tracer sched_switch: <6>Starting ring buffer hammer
> PASSED
> Testing tracer sysprof: PASSED
> Testing tracer function: PASSED
> Testing tracer irqsoff:
> =============================================
> PASSED
> Testing tracer preemptoff: PASSED
> Testing tracer preemptirqsoff: [ INFO: possible recursive locking detected ]
> PASSED
> Testing tracer branch: 2.6.30-rc8-tip-01972-ge5b9078-dirty #5760
> ---------------------------------------------
> rb_consumer/431 is trying to acquire lock:
> (&cpu_buffer->reader_lock){......}, at: [<c109eef7>] ring_buffer_reset_cpu+0x37/0x70
>
> but task is already holding lock:
> (&cpu_buffer->reader_lock){......}, at: [<c10a019e>] ring_buffer_consume+0x7e/0xc0
>
> other info that might help us debug this:
> 1 lock held by rb_consumer/431:
> #0: (&cpu_buffer->reader_lock){......}, at: [<c10a019e>] ring_buffer_consume+0x7e/0xc0
The ring buffer is a generic structure, and can be used outside of
ftrace. If ftrace traces within the use of the ring buffer, it can produce
false positives with lockdep.
This patch passes in a static lock key into the allocation of the ring
buffer, so that different ring buffers will have their own lock class.
Reported-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <1244477919.13761.9042.camel@twins>
[ store key in ring buffer descriptor ]
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/ring_buffer.h | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index f1345828c7c5..8670f1575fe1 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h | |||
@@ -105,7 +105,19 @@ void ring_buffer_discard_commit(struct ring_buffer *buffer, | |||
105 | * size is in bytes for each per CPU buffer. | 105 | * size is in bytes for each per CPU buffer. |
106 | */ | 106 | */ |
107 | struct ring_buffer * | 107 | struct ring_buffer * |
108 | ring_buffer_alloc(unsigned long size, unsigned flags); | 108 | __ring_buffer_alloc(unsigned long size, unsigned flags, struct lock_class_key *key); |
109 | |||
110 | /* | ||
111 | * Because the ring buffer is generic, if other users of the ring buffer get | ||
112 | * traced by ftrace, it can produce lockdep warnings. We need to keep each | ||
113 | * ring buffer's lock class separate. | ||
114 | */ | ||
115 | #define ring_buffer_alloc(size, flags) \ | ||
116 | ({ \ | ||
117 | static struct lock_class_key __key; \ | ||
118 | __ring_buffer_alloc((size), (flags), &__key); \ | ||
119 | }) | ||
120 | |||
109 | void ring_buffer_free(struct ring_buffer *buffer); | 121 | void ring_buffer_free(struct ring_buffer *buffer); |
110 | 122 | ||
111 | int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size); | 123 | int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size); |