From: Masami Hiramatsu (Google) <[email protected]> Skip invalid sub-buffers when validating the persistent ring buffer instead of discarding the entire ring buffer. Also, mark there are missed events on the discarded buffer.
If the cache data in memory fails to be synchronized during a reboot, the persistent ring buffer may become partially corrupted, but other sub-buffers may still contain readable event data. Only discard the subbuffersa that ar found to be corrupted. Signed-off-by: Masami Hiramatsu (Google) <[email protected]> --- Changes in v3: - Record missed data event on commit. --- kernel/trace/ring_buffer.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 1ef718d21796..18b0b33e1dc8 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -2058,17 +2058,18 @@ static void rb_meta_validate_events(struct ring_buffer_per_cpu *cpu_buffer) if (ret < 0) { pr_info("Ring buffer meta [%d] invalid buffer page\n", cpu_buffer->cpu); - goto invalid; - } - - /* If the buffer has content, update pages_touched */ - if (ret) - local_inc(&cpu_buffer->pages_touched); - - entries += ret; - entry_bytes += rb_page_size(head_page); - local_set(&cpu_buffer->head_page->entries, ret); + /* Instead of discard whole ring buffer, discard only this sub-buffer. */ + local_set(&head_page->entries, 0); + local_set(&head_page->page->commit, RB_MISSED_EVENTS); + } else { + /* If the buffer has content, update pages_touched */ + if (ret) + local_inc(&cpu_buffer->pages_touched); + entries += ret; + entry_bytes += rb_page_size(head_page); + local_set(&cpu_buffer->head_page->entries, ret); + } if (head_page == cpu_buffer->commit_page) break; }
