Commit 1c6fd599 authored by Petr Mladek's avatar Petr Mladek
Browse files

Merge branch 'rework/kthreads' into for-linus

parents a5c7a39f 701850dc
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -578,6 +578,7 @@ void __handle_sysrq(int key, bool check_mask)

	rcu_sysrq_start();
	rcu_read_lock();
	printk_prefer_direct_enter();
	/*
	 * Raise the apparent loglevel to maximum so that the sysrq header
	 * is shown to provide the user with positive feedback.  We do not
@@ -619,6 +620,7 @@ void __handle_sysrq(int key, bool check_mask)
		pr_cont("\n");
		console_loglevel = orig_log_level;
	}
	printk_prefer_direct_exit();
	rcu_read_unlock();
	rcu_sysrq_end();

+19 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

#include <linux/atomic.h>
#include <linux/types.h>
#include <linux/mutex.h>

struct vc_data;
struct console_font_op;
@@ -151,6 +152,24 @@ struct console {
	int	cflag;
	uint	ispeed;
	uint	ospeed;
	u64	seq;
	unsigned long dropped;
	struct task_struct *thread;
	bool	blocked;

	/*
	 * The per-console lock is used by printing kthreads to synchronize
	 * this console with callers of console_lock(). This is necessary in
	 * order to allow printing kthreads to run in parallel to each other,
	 * while each safely accessing the @blocked field and synchronizing
	 * against direct printing via console_lock/console_unlock.
	 *
	 * Note: For synchronizing against direct printing via
	 *       console_trylock/console_unlock, see the static global
	 *       variable @console_kthreads_active.
	 */
	struct mutex lock;

	void	*data;
	struct	 console *next;
};
+56 −26
Original line number Diff line number Diff line
@@ -170,6 +170,11 @@ extern void __printk_safe_exit(void);
#define printk_deferred_enter __printk_safe_enter
#define printk_deferred_exit __printk_safe_exit

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);

/*
 * Please don't use printk_ratelimit(), because it shares ratelimiting state
 * with all other unrelated printk_ratelimit() callsites.  Instead use
@@ -220,6 +225,19 @@ static inline void printk_deferred_exit(void)
{
}

static inline void printk_prefer_direct_enter(void)
{
}

static inline void printk_prefer_direct_exit(void)
{
}

static inline bool pr_flush(int timeout_ms, bool reset_on_progress)
{
	return true;
}

static inline int printk_ratelimit(void)
{
	return 0;
@@ -277,45 +295,57 @@ static inline void printk_trigger_flush(void)
#endif

#ifdef CONFIG_SMP
extern int __printk_cpu_trylock(void);
extern void __printk_wait_on_cpu_lock(void);
extern void __printk_cpu_unlock(void);
extern int __printk_cpu_sync_try_get(void);
extern void __printk_cpu_sync_wait(void);
extern void __printk_cpu_sync_put(void);

#else

#define __printk_cpu_sync_try_get() true
#define __printk_cpu_sync_wait()
#define __printk_cpu_sync_put()
#endif /* CONFIG_SMP */

/**
 * printk_cpu_lock_irqsave() - Acquire the printk cpu-reentrant spinning
 *                             lock and disable interrupts.
 * printk_cpu_sync_get_irqsave() - Disable interrupts and acquire the printk
 *                                 cpu-reentrant spinning lock.
 * @flags: Stack-allocated storage for saving local interrupt state,
 *         to be passed to printk_cpu_unlock_irqrestore().
 *         to be passed to printk_cpu_sync_put_irqrestore().
 *
 * If the lock is owned by another CPU, spin until it becomes available.
 * Interrupts are restored while spinning.
 *
 * CAUTION: This function must be used carefully. It does not behave like a
 * typical lock. Here are important things to watch out for...
 *
 *     * This function is reentrant on the same CPU. Therefore the calling
 *       code must not assume exclusive access to data if code accessing the
 *       data can run reentrant or within NMI context on the same CPU.
 *
 *     * If there exists usage of this function from NMI context, it becomes
 *       unsafe to perform any type of locking or spinning to wait for other
 *       CPUs after calling this function from any context. This includes
 *       using spinlocks or any other busy-waiting synchronization methods.
 */
#define printk_cpu_lock_irqsave(flags)		\
#define printk_cpu_sync_get_irqsave(flags)		\
	for (;;) {					\
		local_irq_save(flags);			\
		if (__printk_cpu_trylock())	\
		if (__printk_cpu_sync_try_get())	\
			break;				\
		local_irq_restore(flags);		\
		__printk_wait_on_cpu_lock();	\
		__printk_cpu_sync_wait();		\
	}

/**
 * printk_cpu_unlock_irqrestore() - Release the printk cpu-reentrant spinning
 * printk_cpu_sync_put_irqrestore() - Release the printk cpu-reentrant spinning
 *                                    lock and restore interrupts.
 * @flags: Caller's saved interrupt state, from printk_cpu_lock_irqsave().
 * @flags: Caller's saved interrupt state, from printk_cpu_sync_get_irqsave().
 */
#define printk_cpu_unlock_irqrestore(flags)	\
#define printk_cpu_sync_put_irqrestore(flags)	\
	do {					\
		__printk_cpu_unlock();		\
		__printk_cpu_sync_put();	\
		local_irq_restore(flags);	\
	} while (0)				\

#else

#define printk_cpu_lock_irqsave(flags) ((void)flags)
#define printk_cpu_unlock_irqrestore(flags) ((void)flags)

#endif /* CONFIG_SMP */
	} while (0)

extern int kptr_restrict;

+10 −1
Original line number Diff line number Diff line
@@ -127,6 +127,8 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout)
	 * complain:
	 */
	if (sysctl_hung_task_warnings) {
		printk_prefer_direct_enter();

		if (sysctl_hung_task_warnings > 0)
			sysctl_hung_task_warnings--;
		pr_err("INFO: task %s:%d blocked for more than %ld seconds.\n",
@@ -142,6 +144,8 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout)

		if (sysctl_hung_task_all_cpu_backtrace)
			hung_task_show_all_bt = true;

		printk_prefer_direct_exit();
	}

	touch_nmi_watchdog();
@@ -204,12 +208,17 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout)
	}
 unlock:
	rcu_read_unlock();
	if (hung_task_show_lock)
	if (hung_task_show_lock) {
		printk_prefer_direct_enter();
		debug_show_all_locks();
		printk_prefer_direct_exit();
	}

	if (hung_task_show_all_bt) {
		hung_task_show_all_bt = false;
		printk_prefer_direct_enter();
		trigger_all_cpu_backtrace();
		printk_prefer_direct_exit();
	}

	if (hung_task_call_panic)
+4 −0
Original line number Diff line number Diff line
@@ -560,6 +560,8 @@ void __warn(const char *file, int line, void *caller, unsigned taint,
{
	disable_trace_on_warning();

	printk_prefer_direct_enter();

	if (file)
		pr_warn("WARNING: CPU: %d PID: %d at %s:%d %pS\n",
			raw_smp_processor_id(), current->pid, file, line,
@@ -597,6 +599,8 @@ void __warn(const char *file, int line, void *caller, unsigned taint,

	/* Just a warning, don't kill lockdep. */
	add_taint(taint, LOCKDEP_STILL_OK);

	printk_prefer_direct_exit();
}

#ifndef __WARN_FLAGS
Loading