Commit f9f3f02d authored by John Ogness's avatar John Ogness Committed by Petr Mladek
Browse files

printk: introduce a kmsg_dump iterator



Rather than storing the iterator information in the registered
kmsg_dumper structure, create a separate iterator structure. The
kmsg_dump_iter structure can reside on the stack of the caller, thus
allowing lockless use of the kmsg_dump functions.

Update code that accesses the kernel logs using the kmsg_dumper
structure to use the new kmsg_dump_iter structure. For kmsg_dumpers,
this also means adding a call to kmsg_dump_rewind() to initialize
the iterator.

All this is in preparation for removal of @logbuf_lock.

Signed-off-by: default avatarJohn Ogness <john.ogness@linutronix.de>
Reviewed-by: Kees Cook <keescook@chromium.org> # pstore
Reviewed-by: default avatarPetr Mladek <pmladek@suse.com>
Signed-off-by: default avatarPetr Mladek <pmladek@suse.com>
Link: https://lore.kernel.org/r/20210303101528.29901-13-john.ogness@linutronix.de
parent 5f6c7648
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -647,6 +647,7 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
{
	struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf;
	static unsigned int oops_count = 0;
	static struct kmsg_dump_iter iter;
	static bool panicking = false;
	static DEFINE_SPINLOCK(lock);
	unsigned long flags;
@@ -681,13 +682,14 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
		return;

	if (big_oops_buf) {
		kmsg_dump_get_buffer(dumper, false,
		kmsg_dump_rewind(&iter);
		kmsg_dump_get_buffer(&iter, false,
				     big_oops_buf, big_oops_buf_sz, &text_len);
		rc = zip_oops(text_len);
	}
	if (rc != 0) {
		kmsg_dump_rewind(dumper);
		kmsg_dump_get_buffer(dumper, false,
		kmsg_dump_rewind(&iter);
		kmsg_dump_get_buffer(&iter, false,
				     oops_data, oops_data_sz, &text_len);
		err_type = ERR_TYPE_KERNEL_PANIC;
		oops_hdr->version = cpu_to_be16(OOPS_HDR_VERSION);
+3 −3
Original line number Diff line number Diff line
@@ -3005,7 +3005,7 @@ print_address(unsigned long addr)
static void
dump_log_buf(void)
{
	struct kmsg_dumper dumper;
	struct kmsg_dump_iter iter;
	unsigned char buf[128];
	size_t len;

@@ -3017,9 +3017,9 @@ dump_log_buf(void)
	catch_memory_errors = 1;
	sync();

	kmsg_dump_rewind_nolock(&dumper);
	kmsg_dump_rewind_nolock(&iter);
	xmon_start_pagination();
	while (kmsg_dump_get_line_nolock(&dumper, false, buf, sizeof(buf), &len)) {
	while (kmsg_dump_get_line_nolock(&iter, false, buf, sizeof(buf), &len)) {
		buf[len] = '\0';
		printf("%s", buf);
	}
+4 −1
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
static void kmsg_dumper_stdout(struct kmsg_dumper *dumper,
				enum kmsg_dump_reason reason)
{
	static struct kmsg_dump_iter iter;
	static DEFINE_SPINLOCK(lock);
	static char line[1024];
	struct console *con;
@@ -35,8 +36,10 @@ static void kmsg_dumper_stdout(struct kmsg_dumper *dumper,
	if (!spin_trylock_irqsave(&lock, flags))
		return;

	kmsg_dump_rewind(&iter);

	printf("kmsg_dump:\n");
	while (kmsg_dump_get_line(dumper, true, line, sizeof(line), &len)) {
	while (kmsg_dump_get_line(&iter, true, line, sizeof(line), &len)) {
		line[len] = '\0';
		printf("%s", line);
	}
+3 −1
Original line number Diff line number Diff line
@@ -1391,6 +1391,7 @@ static void vmbus_isr(void)
static void hv_kmsg_dump(struct kmsg_dumper *dumper,
			 enum kmsg_dump_reason reason)
{
	struct kmsg_dump_iter iter;
	size_t bytes_written;
	phys_addr_t panic_pa;

@@ -1404,7 +1405,8 @@ static void hv_kmsg_dump(struct kmsg_dumper *dumper,
	 * Write dump contents to the page. No need to synchronize; panic should
	 * be single-threaded.
	 */
	kmsg_dump_get_buffer(dumper, false, hv_panic_page, HV_HYP_PAGE_SIZE,
	kmsg_dump_rewind(&iter);
	kmsg_dump_get_buffer(&iter, false, hv_panic_page, HV_HYP_PAGE_SIZE,
			     &bytes_written);
	if (bytes_written)
		hyperv_report_panic_msg(panic_pa, bytes_written);
+4 −1
Original line number Diff line number Diff line
@@ -277,14 +277,17 @@ static void mtdoops_do_dump(struct kmsg_dumper *dumper,
{
	struct mtdoops_context *cxt = container_of(dumper,
			struct mtdoops_context, dump);
	struct kmsg_dump_iter iter;

	/* Only dump oopses if dump_oops is set */
	if (reason == KMSG_DUMP_OOPS && !dump_oops)
		return;

	kmsg_dump_rewind(&iter);

	if (test_and_set_bit(0, &cxt->oops_buf_busy))
		return;
	kmsg_dump_get_buffer(dumper, true, cxt->oops_buf + MTDOOPS_HEADER_SIZE,
	kmsg_dump_get_buffer(&iter, true, cxt->oops_buf + MTDOOPS_HEADER_SIZE,
			     record_size - MTDOOPS_HEADER_SIZE, NULL);
	clear_bit(0, &cxt->oops_buf_busy);

Loading