summaryrefslogtreecommitdiff
path: root/Documentation/admin-guide/kdump
diff options
context:
space:
mode:
authorJohn Ogness <john.ogness@linutronix.de>2020-08-14 23:31:25 +0206
committerPetr Mladek <pmladek@suse.com>2020-09-08 09:33:15 +0200
commite60768311af854734ce2bbfc50f24cff67b54a91 (patch)
treeff1470642d64b9b5639749e7fbd8eeac4fecf1a8 /Documentation/admin-guide/kdump
parent3e0d075cb0ab3b1fbddc14855985215407f8a48b (diff)
scripts/gdb: update for lockless printk ringbuffer
With the introduction of the lockless printk ringbuffer, the data structure for the kernel log buffer was changed. Update the gdb scripts to be able to parse/print the new log buffer structure. Fixes: 896fbe20b4e2333fb55 ("printk: use the lockless ringbuffer") Signed-off-by: John Ogness <john.ogness@linutronix.de> Reported-by: Nick Desaulniers <ndesaulniers@google.com> Tested-by: Nick Desaulniers <ndesaulniers@google.com> Tested-by: Petr Mladek <pmladek@suse.com> [akpm@linux-foundation.org: A typo fix.] Signed-off-by: Petr Mladek <pmladek@suse.com> Link: https://lore.kernel.org/r/20200814212525.6118-3-john.ogness@linutronix.de
Diffstat (limited to 'Documentation/admin-guide/kdump')
-rw-r--r--Documentation/admin-guide/kdump/gdbmacros.txt153
1 files changed, 107 insertions, 46 deletions
diff --git a/Documentation/admin-guide/kdump/gdbmacros.txt b/Documentation/admin-guide/kdump/gdbmacros.txt
index 220d0a80ca2c..7adece30237e 100644
--- a/Documentation/admin-guide/kdump/gdbmacros.txt
+++ b/Documentation/admin-guide/kdump/gdbmacros.txt
@@ -170,57 +170,111 @@ document trapinfo
address the kernel panicked.
end
-define dump_log_idx
- set $idx = $arg0
+define dump_record
+ set var $desc = $arg0
if ($argc > 1)
- set $prev_flags = $arg1
+ set var $prev_flags = $arg1
else
- set $prev_flags = 0
+ set var $prev_flags = 0
end
- set $msg = ((struct printk_log *) (log_buf + $idx))
- set $prefix = 1
- set $newline = 1
- set $log = log_buf + $idx + sizeof(*$msg)
-
- # prev & LOG_CONT && !(msg->flags & LOG_PREIX)
- if (($prev_flags & 8) && !($msg->flags & 4))
- set $prefix = 0
+
+ set var $info = &$desc->info
+ set var $prefix = 1
+ set var $newline = 1
+
+ set var $begin = $desc->text_blk_lpos.begin % (1U << prb->text_data_ring.size_bits)
+ set var $next = $desc->text_blk_lpos.next % (1U << prb->text_data_ring.size_bits)
+
+ # handle data-less record
+ if ($begin & 1)
+ set var $text_len = 0
+ set var $log = ""
+ else
+ # handle wrapping data block
+ if ($begin > $next)
+ set var $begin = 0
+ end
+
+ # skip over descriptor id
+ set var $begin = $begin + sizeof(long)
+
+ # handle truncated message
+ if ($next - $begin < $info->text_len)
+ set var $text_len = $next - $begin
+ else
+ set var $text_len = $info->text_len
+ end
+
+ set var $log = &prb->text_data_ring.data[$begin]
+ end
+
+ # prev & LOG_CONT && !(info->flags & LOG_PREIX)
+ if (($prev_flags & 8) && !($info->flags & 4))
+ set var $prefix = 0
end
- # msg->flags & LOG_CONT
- if ($msg->flags & 8)
+ # info->flags & LOG_CONT
+ if ($info->flags & 8)
# (prev & LOG_CONT && !(prev & LOG_NEWLINE))
if (($prev_flags & 8) && !($prev_flags & 2))
- set $prefix = 0
+ set var $prefix = 0
end
- # (!(msg->flags & LOG_NEWLINE))
- if (!($msg->flags & 2))
- set $newline = 0
+ # (!(info->flags & LOG_NEWLINE))
+ if (!($info->flags & 2))
+ set var $newline = 0
end
end
if ($prefix)
- printf "[%5lu.%06lu] ", $msg->ts_nsec / 1000000000, $msg->ts_nsec % 1000000000
+ printf "[%5lu.%06lu] ", $info->ts_nsec / 1000000000, $info->ts_nsec % 1000000000
end
- if ($msg->text_len != 0)
- eval "printf \"%%%d.%ds\", $log", $msg->text_len, $msg->text_len
+ if ($text_len)
+ eval "printf \"%%%d.%ds\", $log", $text_len, $text_len
end
if ($newline)
printf "\n"
end
- if ($msg->dict_len > 0)
- set $dict = $log + $msg->text_len
- set $idx = 0
- set $line = 1
- while ($idx < $msg->dict_len)
+
+ # handle dictionary data
+
+ set var $begin = $desc->dict_blk_lpos.begin % (1U << prb->dict_data_ring.size_bits)
+ set var $next = $desc->dict_blk_lpos.next % (1U << prb->dict_data_ring.size_bits)
+
+ # handle data-less record
+ if ($begin & 1)
+ set var $dict_len = 0
+ set var $dict = ""
+ else
+ # handle wrapping data block
+ if ($begin > $next)
+ set var $begin = 0
+ end
+
+ # skip over descriptor id
+ set var $begin = $begin + sizeof(long)
+
+ # handle truncated message
+ if ($next - $begin < $info->dict_len)
+ set var $dict_len = $next - $begin
+ else
+ set var $dict_len = $info->dict_len
+ end
+
+ set var $dict = &prb->dict_data_ring.data[$begin]
+ end
+
+ if ($dict_len > 0)
+ set var $idx = 0
+ set var $line = 1
+ while ($idx < $dict_len)
if ($line)
printf " "
- set $line = 0
+ set var $line = 0
end
- set $c = $dict[$idx]
+ set var $c = $dict[$idx]
if ($c == '\0')
printf "\n"
- set $line = 1
+ set var $line = 1
else
if ($c < ' ' || $c >= 127 || $c == '\\')
printf "\\x%02x", $c
@@ -228,33 +282,40 @@ define dump_log_idx
printf "%c", $c
end
end
- set $idx = $idx + 1
+ set var $idx = $idx + 1
end
printf "\n"
end
end
-document dump_log_idx
- Dump a single log given its index in the log buffer. The first
- parameter is the index into log_buf, the second is optional and
- specified the previous log buffer's flags, used for properly
- formatting continued lines.
+document dump_record
+ Dump a single record. The first parameter is the descriptor
+ sequence number, the second is optional and specifies the
+ previous record's flags, used for properly formatting
+ continued lines.
end
define dmesg
- set $i = log_first_idx
- set $end_idx = log_first_idx
- set $prev_flags = 0
+ set var $desc_committed = 1UL << ((sizeof(long) * 8) - 1)
+ set var $flags_mask = 3UL << ((sizeof(long) * 8) - 2)
+ set var $id_mask = ~$flags_mask
+
+ set var $desc_count = 1U << prb->desc_ring.count_bits
+ set var $prev_flags = 0
+
+ set var $id = prb->desc_ring.tail_id.counter
+ set var $end_id = prb->desc_ring.head_id.counter
while (1)
- set $msg = ((struct printk_log *) (log_buf + $i))
- if ($msg->len == 0)
- set $i = 0
- else
- dump_log_idx $i $prev_flags
- set $i = $i + $msg->len
- set $prev_flags = $msg->flags
+ set var $desc = &prb->desc_ring.descs[$id % $desc_count]
+
+ # skip non-committed record
+ if (($desc->state_var.counter & $flags_mask) == $desc_committed)
+ dump_record $desc $prev_flags
+ set var $prev_flags = $desc->info.flags
end
- if ($i == $end_idx)
+
+ set var $id = ($id + 1) & $id_mask
+ if ($id == $end_id)
loop_break
end
end