ring_buffer: reset write when reserve buffer fail
Impact: reset struct buffer_page.write when interrupt storm if struct buffer_page.write is not reset, any succedent committing will corrupted ring_buffer: static inline void rb_set_commit_to_write(struct ring_buffer_per_cpu *cpu_buffer) { ...... cpu_buffer->commit_page->commit = cpu_buffer->commit_page->write; ...... } when "if (RB_WARN_ON(cpu_buffer, next_page == reader_page))", ring_buffer is disabled, but some reserved buffers may haven't been committed. we need reset struct buffer_page.write. when "if (unlikely(next_page == cpu_buffer->commit_page))", ring_buffer is still available, we should not corrupt it. Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> Signed-off-by: Steven Rostedt <srostedt@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
Родитель
428aee1460
Коммит
6f3b34402e
|
@ -1017,12 +1017,8 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (next_page == head_page) {
|
if (next_page == head_page) {
|
||||||
if (!(buffer->flags & RB_FL_OVERWRITE)) {
|
if (!(buffer->flags & RB_FL_OVERWRITE))
|
||||||
/* reset write */
|
|
||||||
if (tail <= BUF_PAGE_SIZE)
|
|
||||||
local_set(&tail_page->write, tail);
|
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
|
||||||
|
|
||||||
/* tail_page has not moved yet? */
|
/* tail_page has not moved yet? */
|
||||||
if (tail_page == cpu_buffer->tail_page) {
|
if (tail_page == cpu_buffer->tail_page) {
|
||||||
|
@ -1097,6 +1093,10 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
|
||||||
return event;
|
return event;
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
|
/* reset write */
|
||||||
|
if (tail <= BUF_PAGE_SIZE)
|
||||||
|
local_set(&tail_page->write, tail);
|
||||||
|
|
||||||
__raw_spin_unlock(&cpu_buffer->lock);
|
__raw_spin_unlock(&cpu_buffer->lock);
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче