Merge branch 'for-5.8' into for-linus
This commit is contained in:
@@ -23,6 +23,9 @@ __printf(1, 0) int vprintk_func(const char *fmt, va_list args);
|
||||
void __printk_safe_enter(void);
|
||||
void __printk_safe_exit(void);
|
||||
|
||||
void printk_safe_init(void);
|
||||
bool printk_percpu_data_ready(void);
|
||||
|
||||
#define printk_safe_enter_irqsave(flags) \
|
||||
do { \
|
||||
local_irq_save(flags); \
|
||||
@@ -64,4 +67,6 @@ __printf(1, 0) int vprintk_func(const char *fmt, va_list args) { return 0; }
|
||||
#define printk_safe_enter_irq() local_irq_disable()
|
||||
#define printk_safe_exit_irq() local_irq_enable()
|
||||
|
||||
static inline void printk_safe_init(void) { }
|
||||
static inline bool printk_percpu_data_ready(void) { return false; }
|
||||
#endif /* CONFIG_PRINTK */
|
||||
|
@@ -461,6 +461,18 @@ static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN);
|
||||
static char *log_buf = __log_buf;
|
||||
static u32 log_buf_len = __LOG_BUF_LEN;
|
||||
|
||||
/*
|
||||
* We cannot access per-CPU data (e.g. per-CPU flush irq_work) before
|
||||
* per_cpu_areas are initialised. This variable is set to true when
|
||||
* it's safe to access per-CPU data.
|
||||
*/
|
||||
static bool __printk_percpu_data_ready __read_mostly;
|
||||
|
||||
bool printk_percpu_data_ready(void)
|
||||
{
|
||||
return __printk_percpu_data_ready;
|
||||
}
|
||||
|
||||
/* Return log buffer address */
|
||||
char *log_buf_addr_get(void)
|
||||
{
|
||||
@@ -963,6 +975,16 @@ static loff_t devkmsg_llseek(struct file *file, loff_t offset, int whence)
|
||||
user->idx = log_next_idx;
|
||||
user->seq = log_next_seq;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
/*
|
||||
* It isn't supported due to the record nature of this
|
||||
* interface: _SET _DATA and _END point to very specific
|
||||
* record positions, while _CUR would be more useful in case
|
||||
* of a byte-based log. Because of that, return the default
|
||||
* errno value for invalid seek operation.
|
||||
*/
|
||||
ret = -ESPIPE;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
@@ -1147,12 +1169,28 @@ static void __init log_buf_add_cpu(void)
|
||||
static inline void log_buf_add_cpu(void) {}
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
static void __init set_percpu_data_ready(void)
|
||||
{
|
||||
printk_safe_init();
|
||||
/* Make sure we set this flag only after printk_safe() init is done */
|
||||
barrier();
|
||||
__printk_percpu_data_ready = true;
|
||||
}
|
||||
|
||||
void __init setup_log_buf(int early)
|
||||
{
|
||||
unsigned long flags;
|
||||
char *new_log_buf;
|
||||
unsigned int free;
|
||||
|
||||
/*
|
||||
* Some archs call setup_log_buf() multiple times - first is very
|
||||
* early, e.g. from setup_arch(), and second - when percpu_areas
|
||||
* are initialised.
|
||||
*/
|
||||
if (!early)
|
||||
set_percpu_data_ready();
|
||||
|
||||
if (log_buf != __log_buf)
|
||||
return;
|
||||
|
||||
@@ -1773,9 +1811,6 @@ static void call_console_drivers(const char *ext_text, size_t ext_len,
|
||||
|
||||
trace_console_rcuidle(text, len);
|
||||
|
||||
if (!console_drivers)
|
||||
return;
|
||||
|
||||
for_each_console(con) {
|
||||
if (exclusive_console && con != exclusive_console)
|
||||
continue;
|
||||
@@ -2169,6 +2204,9 @@ static int __init console_setup(char *str)
|
||||
char *s, *options, *brl_options = NULL;
|
||||
int idx;
|
||||
|
||||
if (str[0] == 0)
|
||||
return 1;
|
||||
|
||||
if (_braille_console_setup(&str, &brl_options))
|
||||
return 1;
|
||||
|
||||
@@ -2712,19 +2750,17 @@ void register_console(struct console *newcon)
|
||||
struct console *bcon = NULL;
|
||||
int err;
|
||||
|
||||
if (console_drivers)
|
||||
for_each_console(bcon)
|
||||
if (WARN(bcon == newcon,
|
||||
"console '%s%d' already registered\n",
|
||||
bcon->name, bcon->index))
|
||||
return;
|
||||
for_each_console(bcon) {
|
||||
if (WARN(bcon == newcon, "console '%s%d' already registered\n",
|
||||
bcon->name, bcon->index))
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* before we register a new CON_BOOT console, make sure we don't
|
||||
* already have a valid console
|
||||
*/
|
||||
if (console_drivers && newcon->flags & CON_BOOT) {
|
||||
/* find the last or real console */
|
||||
if (newcon->flags & CON_BOOT) {
|
||||
for_each_console(bcon) {
|
||||
if (!(bcon->flags & CON_BOOT)) {
|
||||
pr_info("Too late to register bootconsole %s%d\n",
|
||||
@@ -2847,7 +2883,7 @@ EXPORT_SYMBOL(register_console);
|
||||
|
||||
int unregister_console(struct console *console)
|
||||
{
|
||||
struct console *a, *b;
|
||||
struct console *con;
|
||||
int res;
|
||||
|
||||
pr_info("%sconsole [%s%d] disabled\n",
|
||||
@@ -2855,26 +2891,30 @@ int unregister_console(struct console *console)
|
||||
console->name, console->index);
|
||||
|
||||
res = _braille_unregister_console(console);
|
||||
if (res)
|
||||
if (res < 0)
|
||||
return res;
|
||||
if (res > 0)
|
||||
return 0;
|
||||
|
||||
res = 1;
|
||||
res = -ENODEV;
|
||||
console_lock();
|
||||
if (console_drivers == console) {
|
||||
console_drivers=console->next;
|
||||
res = 0;
|
||||
} else if (console_drivers) {
|
||||
for (a=console_drivers->next, b=console_drivers ;
|
||||
a; b=a, a=b->next) {
|
||||
if (a == console) {
|
||||
b->next = a->next;
|
||||
} else {
|
||||
for_each_console(con) {
|
||||
if (con->next == console) {
|
||||
con->next = console->next;
|
||||
res = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!res && (console->flags & CON_EXTENDED))
|
||||
if (res)
|
||||
goto out_disable_unlock;
|
||||
|
||||
if (console->flags & CON_EXTENDED)
|
||||
nr_ext_console_drivers--;
|
||||
|
||||
/*
|
||||
@@ -2887,6 +2927,16 @@ int unregister_console(struct console *console)
|
||||
console->flags &= ~CON_ENABLED;
|
||||
console_unlock();
|
||||
console_sysfs_notify();
|
||||
|
||||
if (console->exit)
|
||||
res = console->exit(console);
|
||||
|
||||
return res;
|
||||
|
||||
out_disable_unlock:
|
||||
console->flags &= ~CON_ENABLED;
|
||||
console_unlock();
|
||||
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL(unregister_console);
|
||||
@@ -3000,6 +3050,9 @@ static DEFINE_PER_CPU(struct irq_work, wake_up_klogd_work) = {
|
||||
|
||||
void wake_up_klogd(void)
|
||||
{
|
||||
if (!printk_percpu_data_ready())
|
||||
return;
|
||||
|
||||
preempt_disable();
|
||||
if (waitqueue_active(&log_wait)) {
|
||||
this_cpu_or(printk_pending, PRINTK_PENDING_WAKEUP);
|
||||
@@ -3010,6 +3063,9 @@ void wake_up_klogd(void)
|
||||
|
||||
void defer_console_output(void)
|
||||
{
|
||||
if (!printk_percpu_data_ready())
|
||||
return;
|
||||
|
||||
preempt_disable();
|
||||
__this_cpu_or(printk_pending, PRINTK_PENDING_OUTPUT);
|
||||
irq_work_queue(this_cpu_ptr(&wake_up_klogd_work));
|
||||
@@ -3351,7 +3407,7 @@ out:
|
||||
EXPORT_SYMBOL_GPL(kmsg_dump_get_buffer);
|
||||
|
||||
/**
|
||||
* kmsg_dump_rewind_nolock - reset the interator (unlocked version)
|
||||
* kmsg_dump_rewind_nolock - reset the iterator (unlocked version)
|
||||
* @dumper: registered kmsg dumper
|
||||
*
|
||||
* Reset the dumper's iterator so that kmsg_dump_get_line() and
|
||||
@@ -3369,7 +3425,7 @@ void kmsg_dump_rewind_nolock(struct kmsg_dumper *dumper)
|
||||
}
|
||||
|
||||
/**
|
||||
* kmsg_dump_rewind - reset the interator
|
||||
* kmsg_dump_rewind - reset the iterator
|
||||
* @dumper: registered kmsg dumper
|
||||
*
|
||||
* Reset the dumper's iterator so that kmsg_dump_get_line() and
|
||||
|
@@ -27,7 +27,6 @@
|
||||
* There are situations when we want to make sure that all buffers
|
||||
* were handled or when IRQs are blocked.
|
||||
*/
|
||||
static int printk_safe_irq_ready __read_mostly;
|
||||
|
||||
#define SAFE_LOG_BUF_LEN ((1 << CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT) - \
|
||||
sizeof(atomic_t) - \
|
||||
@@ -51,7 +50,7 @@ static DEFINE_PER_CPU(struct printk_safe_seq_buf, nmi_print_seq);
|
||||
/* Get flushed in a more safe context. */
|
||||
static void queue_flush_work(struct printk_safe_seq_buf *s)
|
||||
{
|
||||
if (printk_safe_irq_ready)
|
||||
if (printk_percpu_data_ready())
|
||||
irq_work_queue(&s->work);
|
||||
}
|
||||
|
||||
@@ -402,14 +401,6 @@ void __init printk_safe_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* In the highly unlikely event that a NMI were to trigger at
|
||||
* this moment. Make sure IRQ work is set up before this
|
||||
* variable is set.
|
||||
*/
|
||||
barrier();
|
||||
printk_safe_irq_ready = 1;
|
||||
|
||||
/* Flush pending messages that did not have scheduled IRQ works. */
|
||||
printk_safe_flush();
|
||||
}
|
||||
|
مرجع در شماره جدید
Block a user