Skip to content
  • Luis R. Rodriguez's avatar
    printk: allow increasing the ring buffer depending on the number of CPUs · 23b2899f
    Luis R. Rodriguez authored
    
    
    The default size of the ring buffer is too small for machines with a
    large amount of CPUs under heavy load.  What ends up happening when
    debugging is the ring buffer overlaps and chews up old messages making
    debugging impossible unless the size is passed as a kernel parameter.
    An idle system upon boot up will on average spew out only about one or
    two extra lines but where this really matters is on heavy load and that
    will vary widely depending on the system and environment.
    
    There are mechanisms to help increase the kernel ring buffer for tracing
    through debugfs, and those interfaces even allow growing the kernel ring
    buffer per CPU.  We also have a static value which can be passed upon
    boot.  Relying on debugfs however is not ideal for production, and
    relying on the value passed upon bootup is can only used *after* an
    issue has creeped up.  Instead of being reactive this adds a proactive
    measure which lets you scale the amount of contributions you'd expect to
    the kernel ring buffer under load by each CPU in the worst case
    scenario.
    
    We use num_possible_cpus() to avoid complexities which could be
    introduced by dynamically changing the ring buffer size at run time,
    num_possible_cpus() lets us use the upper limit on possible number of
    CPUs therefore avoiding having to deal with hotplugging CPUs on and off.
    This introduces the kernel configuration option LOG_CPU_MAX_BUF_SHIFT
    which is used to specify the maximum amount of contributions to the
    kernel ring buffer in the worst case before the kernel ring buffer flips
    over, the size is specified as a power of 2.  The total amount of
    contributions made by each CPU must be greater than half of the default
    kernel ring buffer size (1 << LOG_BUF_SHIFT bytes) in order to trigger
    an increase upon bootup.  The kernel ring buffer is increased to the
    next power of two that would fit the required minimum kernel ring buffer
    size plus the additional CPU contribution.  For example if LOG_BUF_SHIFT
    is 18 (256 KB) you'd require at least 128 KB contributions by other CPUs
    in order to trigger an increase of the kernel ring buffer.  With a
    LOG_CPU_BUF_SHIFT of 12 (4 KB) you'd require at least anything over > 64
    possible CPUs to trigger an increase.  If you had 128 possible CPUs the
    amount of minimum required kernel ring buffer bumps to:
    
       ((1 << 18) + ((128 - 1) * (1 << 12))) / 1024 = 764 KB
    
    Since we require the ring buffer to be a power of two the new required
    size would be 1024 KB.
    
    This CPU contributions are ignored when the "log_buf_len" kernel
    parameter is used as it forces the exact size of the ring buffer to an
    expected power of two value.
    
    [pmladek@suse.cz: fix build]
    Signed-off-by: default avatarLuis R. Rodriguez <mcgrof@suse.com>
    Signed-off-by: default avatarPetr Mladek <pmladek@suse.cz>
    Tested-by: default avatarDavidlohr Bueso <davidlohr@hp.com>
    Tested-by: default avatarPetr Mladek <pmladek@suse.cz>
    Reviewed-by: default avatarDavidlohr Bueso <davidlohr@hp.com>
    Cc: Andrew Lunn <andrew@lunn.ch>
    Cc: Stephen Warren <swarren@wwwdotorg.org>
    Cc: Michal Hocko <mhocko@suse.cz>
    Cc: Petr Mladek <pmladek@suse.cz>
    Cc: Joe Perches <joe@perches.com>
    Cc: Arun KS <arunks.linux@gmail.com>
    Cc: Kees Cook <keescook@chromium.org>
    Cc: Davidlohr Bueso <davidlohr@hp.com>
    Cc: Chris Metcalf <cmetcalf@tilera.com>
    Cc: Jan Kara <jack@suse.cz>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    23b2899f