Commit 38335cc5 authored by Petr Mladek's avatar Petr Mladek
Browse files

Merge branch 'rework/kthreads' into for-linus

parents 12831f64 b87f0230
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -173,6 +173,7 @@ extern void printk_prefer_direct_enter(void);
extern void printk_prefer_direct_exit(void);

extern bool pr_flush(int timeout_ms, bool reset_on_progress);
extern void try_block_console_kthreads(int timeout_ms);

/*
 * Please don't use printk_ratelimit(), because it shares ratelimiting state
@@ -237,6 +238,10 @@ static inline bool pr_flush(int timeout_ms, bool reset_on_progress)
	return true;
}

static inline void try_block_console_kthreads(int timeout_ms)
{
}

static inline int printk_ratelimit(void)
{
	return 0;
+2 −0
Original line number Diff line number Diff line
@@ -297,6 +297,7 @@ void panic(const char *fmt, ...)
		 * unfortunately means it may not be hardened to work in a
		 * panic situation.
		 */
		try_block_console_kthreads(10000);
		smp_send_stop();
	} else {
		/*
@@ -304,6 +305,7 @@ void panic(const char *fmt, ...)
		 * kmsg_dump, we will need architecture dependent extra
		 * works in addition to stopping other CPUs.
		 */
		try_block_console_kthreads(10000);
		crash_smp_send_stop();
	}

+2 −0
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ enum printk_info_flags {
	LOG_CONT	= 8,	/* text is a fragment of a continuation line */
};

extern bool block_console_kthreads;

__printf(4, 0)
int vprintk_store(int facility, int level,
		  const struct dev_printk_info *dev_info,
+7 −1
Original line number Diff line number Diff line
@@ -250,6 +250,9 @@ static atomic_t console_kthreads_active = ATOMIC_INIT(0);
#define console_kthread_printing_exit() \
	atomic_dec(&console_kthreads_active)

/* Block console kthreads to avoid processing new messages. */
bool block_console_kthreads;

/*
 * Helper macros to handle lockdep when locking/unlocking console_sem. We use
 * macros instead of functions so that _RET_IP_ contains useful information.
@@ -3729,7 +3732,10 @@ static bool printer_should_wake(struct console *con, u64 seq)
		return true;

	if (con->blocked ||
	    console_kthreads_atomically_blocked()) {
	    console_kthreads_atomically_blocked() ||
	    block_console_kthreads ||
	    system_state > SYSTEM_RUNNING ||
	    oops_in_progress) {
		return false;
	}

+32 −0
Original line number Diff line number Diff line
@@ -8,7 +8,9 @@
#include <linux/smp.h>
#include <linux/cpumask.h>
#include <linux/printk.h>
#include <linux/console.h>
#include <linux/kprobes.h>
#include <linux/delay.h>

#include "internal.h"

@@ -50,3 +52,33 @@ asmlinkage int vprintk(const char *fmt, va_list args)
	return vprintk_default(fmt, args);
}
EXPORT_SYMBOL(vprintk);

/**
 * try_block_console_kthreads() - Try to block console kthreads and
 *	make the global console_lock() avaialble
 *
 * @timeout_ms:        The maximum time (in ms) to wait.
 *
 * Prevent console kthreads from starting processing new messages. Wait
 * until the global console_lock() become available.
 *
 * Context: Can be called in any context.
 */
void try_block_console_kthreads(int timeout_ms)
{
	block_console_kthreads = true;

	/* Do not wait when the console lock could not be safely taken. */
	if (this_cpu_read(printk_context) || in_nmi())
		return;

	while (timeout_ms > 0) {
		if (console_trylock()) {
			console_unlock();
			return;
		}

		udelay(1000);
		timeout_ms -= 1;
	}
}
Loading