diff options
author | Steven Rostedt <rostedt@goodmis.org> | 2008-11-12 00:01:26 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-11-12 05:25:04 -0500 |
commit | 642edba5f5c545772b89907cf96134c73d6073c7 (patch) | |
tree | fe035c062474bb3163a15e3b490e2c6c5f612407 | |
parent | d06bbd669539215405874d8fe32ab65105e6c4bb (diff) |
ring-buffer: fix deadlock from reader_lock in read_start
Impact: deadlock fix in ring_buffer_read_start
The ring_buffer_iter_reset was called from ring_buffer_read_start
where both grabbed the reader_lock.
This patch separates out the internals of ring_buffer_iter_reset
to its own function so that both APIs may grab the reader_lock.
Signed-off-by: Steven Rostedt <srostedt@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | kernel/trace/ring_buffer.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index c04c433fbc59..86dc353f89b9 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
@@ -1475,19 +1475,9 @@ unsigned long ring_buffer_overruns(struct ring_buffer *buffer) | |||
1475 | return overruns; | 1475 | return overruns; |
1476 | } | 1476 | } |
1477 | 1477 | ||
1478 | /** | 1478 | static void rb_iter_reset(struct ring_buffer_iter *iter) |
1479 | * ring_buffer_iter_reset - reset an iterator | ||
1480 | * @iter: The iterator to reset | ||
1481 | * | ||
1482 | * Resets the iterator, so that it will start from the beginning | ||
1483 | * again. | ||
1484 | */ | ||
1485 | void ring_buffer_iter_reset(struct ring_buffer_iter *iter) | ||
1486 | { | 1479 | { |
1487 | struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer; | 1480 | struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer; |
1488 | unsigned long flags; | ||
1489 | |||
1490 | spin_lock_irqsave(&cpu_buffer->reader_lock, flags); | ||
1491 | 1481 | ||
1492 | /* Iterator usage is expected to have record disabled */ | 1482 | /* Iterator usage is expected to have record disabled */ |
1493 | if (list_empty(&cpu_buffer->reader_page->list)) { | 1483 | if (list_empty(&cpu_buffer->reader_page->list)) { |
@@ -1501,7 +1491,22 @@ void ring_buffer_iter_reset(struct ring_buffer_iter *iter) | |||
1501 | iter->read_stamp = cpu_buffer->read_stamp; | 1491 | iter->read_stamp = cpu_buffer->read_stamp; |
1502 | else | 1492 | else |
1503 | iter->read_stamp = iter->head_page->time_stamp; | 1493 | iter->read_stamp = iter->head_page->time_stamp; |
1494 | } | ||
1504 | 1495 | ||
1496 | /** | ||
1497 | * ring_buffer_iter_reset - reset an iterator | ||
1498 | * @iter: The iterator to reset | ||
1499 | * | ||
1500 | * Resets the iterator, so that it will start from the beginning | ||
1501 | * again. | ||
1502 | */ | ||
1503 | void ring_buffer_iter_reset(struct ring_buffer_iter *iter) | ||
1504 | { | ||
1505 | struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer; | ||
1506 | unsigned long flags; | ||
1507 | |||
1508 | spin_lock_irqsave(&cpu_buffer->reader_lock, flags); | ||
1509 | rb_iter_reset(iter); | ||
1505 | spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); | 1510 | spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); |
1506 | } | 1511 | } |
1507 | 1512 | ||
@@ -1957,7 +1962,7 @@ ring_buffer_read_start(struct ring_buffer *buffer, int cpu) | |||
1957 | 1962 | ||
1958 | spin_lock_irqsave(&cpu_buffer->reader_lock, flags); | 1963 | spin_lock_irqsave(&cpu_buffer->reader_lock, flags); |
1959 | __raw_spin_lock(&cpu_buffer->lock); | 1964 | __raw_spin_lock(&cpu_buffer->lock); |
1960 | ring_buffer_iter_reset(iter); | 1965 | rb_iter_reset(iter); |
1961 | __raw_spin_unlock(&cpu_buffer->lock); | 1966 | __raw_spin_unlock(&cpu_buffer->lock); |
1962 | spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); | 1967 | spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); |
1963 | 1968 | ||