• Steven Rostedt (Red Hat)'s avatar
    ring-buffer: Do not wake up a splice waiter when page is not full · 1e0d6714
    Steven Rostedt (Red Hat) authored
    When an application connects to the ring buffer via splice, it can only
    read full pages. Splice does not work with partial pages. If there is
    not enough data to fill a page, the splice command will either block
    or return -EAGAIN (if set to nonblock).
    
    Code was added where if the page is not full, to just sleep again.
    The problem is, it will get woken up again on the next event. That
    is, when something is written into the ring buffer, if there is a waiter
    it will wake it up. The waiter would then check the buffer, see that
    it still does not have enough data to fill a page and go back to sleep.
    To make matters worse, when the waiter goes back to sleep, it could
    cause another event, which would wake it back up again to see it
    doesn't have enough data and sleep again. This produces a tremendous
    overhead and fills the ring buffer with noise.
    
    For example, recording sched_switch on an idle system for 10 seconds
    produces 25,350,475 events!!!
    
    Create another wait queue for those waiters wanting full pages.
    When an event is written, it only wakes up waiters if there's a full
    page of data. It does not wake up the waiter if the page is not yet
    full.
    
    After this change, recording sched_switch on an idle system for 10
    seconds produces only 800 events. Getting rid of 25,349,675 useless
    events (99.9969% of events!!), is something to take seriously.
    
    Cc: stable@vger.kernel.org # 3.16+
    Cc: Rabin Vincent <rabin@rab.in>
    Fixes: e30f53aa "tracing: Do not busy wait in buffer splice"
    Signed-off-by: default avatarSteven Rostedt <rostedt@goodmis.org>
    1e0d6714
ring_buffer.c 130 KB