• Zheng Yejian's avatar
    ring-buffer: Fix race while reader and writer are on the same page · 6455b616
    Zheng Yejian authored
    When user reads file 'trace_pipe', kernel keeps printing following logs
    that warn at "cpu_buffer->reader_page->read > rb_page_size(reader)" in
    rb_get_reader_page(). It just looks like there's an infinite loop in
    tracing_read_pipe(). This problem occurs several times on arm64 platform
    when testing v5.10 and below.
    
      Call trace:
       rb_get_reader_page+0x248/0x1300
       rb_buffer_peek+0x34/0x160
       ring_buffer_peek+0xbc/0x224
       peek_next_entry+0x98/0xbc
       __find_next_entry+0xc4/0x1c0
       trace_find_next_entry_inc+0x30/0x94
       tracing_read_pipe+0x198/0x304
       vfs_read+0xb4/0x1e0
       ksys_read+0x74/0x100
       __arm64_sys_read+0x24/0x30
       el0_svc_common.constprop.0+0x7c/0x1bc
       do_el0_svc+0x2c/0x94
       el0_svc+0x20/0x30
       el0_sync_handler+0xb0/0xb4
       el0_sync+0x160/0x180
    
    Then I dump the vmcore and look into the problematic per_cpu ring_buffer,
    I found that tail_page/commit_page/reader_page are on the same page while
    reader_page->read is obviously abnormal:
      tail_page == commit_page == reader_page == {
        .write = 0x100d20,
        .read = 0x8f9f4805,  // Far greater than 0xd20, obviously abnormal!!!
        .entries = 0x10004c,
        .real_end = 0x0,
        .page = {
          .time_stamp = 0x857257416af0,
          .commit = 0xd20,  // This page hasn't been full filled.
          // .data[0...0xd20] seems normal.
        }
     }
    
    The root cause is most likely the race that reader and writer are on the
    same page while reader saw an event that not fully committed by writer.
    
    To fix this, add memory barriers to make sure the reader can see the
    content of what is committed. Since commit a0fcaaed ("ring-buffer: Fix
    race between reset page and reading page") has added the read barrier in
    rb_get_reader_page(), here we just need to add the write barrier.
    
    Link: https://lore.kernel.org/linux-trace-kernel/20230325021247.2923907-1-zhengyejian1@huawei.com
    
    Cc: stable@vger.kernel.org
    Fixes: 77ae365e ("ring-buffer: make lockless")
    Suggested-by: default avatarSteven Rostedt (Google) <rostedt@goodmis.org>
    Signed-off-by: default avatarZheng Yejian <zhengyejian1@huawei.com>
    Signed-off-by: default avatarSteven Rostedt (Google) <rostedt@goodmis.org>
    6455b616
ring_buffer.c 165 KB