Skip to content

Commit

Permalink
printk: add clear_idx symbol to vmcoreinfo
Browse files Browse the repository at this point in the history
This allows us to extract from the vmcore only the messages emitted
since the last time the ring buffer was cleared.  We just have to make
sure its value is always up-to-date, when old messages are discarded to
free space in log_make_free_space() for example.

Signed-off-by: Zeyu Zhao <zzy8200@gmail.com>
Signed-off-by: Ivan Delalande <colona@arista.com>
Cc: Kay Sievers <kay@vrfy.org>
Cc: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Ivan Delalande authored and Linus Torvalds committed Mar 17, 2016
1 parent adaf659 commit f468908
Showing 1 changed file with 9 additions and 10 deletions.
19 changes: 9 additions & 10 deletions kernel/printk/printk.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,16 +367,20 @@ static int logbuf_has_space(u32 msg_size, bool empty)

static int log_make_free_space(u32 msg_size)
{
while (log_first_seq < log_next_seq) {
if (logbuf_has_space(msg_size, false))
return 0;
while (log_first_seq < log_next_seq &&
!logbuf_has_space(msg_size, false)) {
/* drop old messages until we have enough contiguous space */
log_first_idx = log_next(log_first_idx);
log_first_seq++;
}

if (clear_seq < log_first_seq) {
clear_seq = log_first_seq;
clear_idx = log_first_idx;
}

/* sequence numbers are equal, so the log buffer is empty */
if (logbuf_has_space(msg_size, true))
if (logbuf_has_space(msg_size, log_first_seq == log_next_seq))
return 0;

return -ENOMEM;
Expand Down Expand Up @@ -854,6 +858,7 @@ void log_buf_kexec_setup(void)
VMCOREINFO_SYMBOL(log_buf);
VMCOREINFO_SYMBOL(log_buf_len);
VMCOREINFO_SYMBOL(log_first_idx);
VMCOREINFO_SYMBOL(clear_idx);
VMCOREINFO_SYMBOL(log_next_idx);
/*
* Export struct printk_log size and field offsets. User space tools can
Expand Down Expand Up @@ -1216,12 +1221,6 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
u32 idx;
enum log_flags prev;

if (clear_seq < log_first_seq) {
/* messages are gone, move to first available one */
clear_seq = log_first_seq;
clear_idx = log_first_idx;
}

/*
* Find first record that fits, including all following records,
* into the user-provided buffer for this dump.
Expand Down

0 comments on commit f468908

Please sign in to comment.