• Steven Rostedt (VMware)'s avatar
    ring-buffer: Check if memory is available before allocation · 2a872fa4
    Steven Rostedt (VMware) authored
    The ring buffer is made up of a link list of pages. When making the ring
    buffer bigger, it will allocate all the pages it needs before adding to the
    ring buffer, and if it fails, it frees them and returns an error. This makes
    increasing the ring buffer size an all or nothing action. When this was
    first created, the pages were allocated with "NORETRY". This was to not
    cause any Out-Of-Memory (OOM) actions from allocating the ring buffer. But
    NORETRY was too strict, as the ring buffer would fail to expand even when
    there's memory available, but was taken up in the page cache.
    
    Commit 84861885 ("tracing/ring_buffer: Try harder to allocate") changed
    the allocating from NORETRY to RETRY_MAYFAIL. The RETRY_MAYFAIL would
    allocate from the page cache, but if there was no memory available, it would
    simple fail the allocation and not trigger an OOM.
    
    This worked fine, but had one problem. As the ring buffer would allocate one
    page at a time, it could take up all memory in the system before it failed
    to allocate and free that memory. If the allocation is happening and the
    ring buffer allocates all memory and then tries to take more than available,
    its allocation will not trigger an OOM, but if there's any allocation that
    happens someplace else, that could trigger an OOM, even though once the ring
    buffer's allocation fails, it would free up all the previous memory it tried
    to allocate, and allow other memory allocations to succeed.
    
    Commit d02bd27b ("mm/page_alloc.c: calculate 'available' memory in a
    separate function") separated out si_mem_availble() as a separate function
    that could be used to see how much memory is available in the system. Using
    this function to make sure that the ring buffer could be allocated before it
    tries to allocate pages we can avoid allocating all memory in the system and
    making it vulnerable to OOMs if other allocations are taking place.
    
    Link: http://lkml.kernel.org/r/1522320104-6573-1-git-send-email-zhaoyang.huang@spreadtrum.com
    
    CC: stable@vger.kernel.org
    Cc: linux-mm@kvack.org
    Fixes: 84861885 ("tracing/ring_buffer: Try harder to allocate")
    Requires: d02bd27b ("mm/page_alloc.c: calculate 'available' memory in a separate function")
    Reported-by: default avatarZhaoyang Huang <huangzhaoyang@gmail.com>
    Tested-by: default avatarJoel Fernandes <joelaf@google.com>
    Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
    2a872fa4
ring_buffer.c 134 KB