Messages in this thread | | | From | John Ogness <> | Subject | Re: [patch RFC 28/29] printk: Provide functions for atomic write enforcement | Date | Tue, 27 Sep 2022 16:01:32 +0206 |
| |
Below is a fix that was used for the LPC2022 demo so that atomic printing occurs in NMI context.
On 2022-09-11, Thomas Gleixner <tglx@linutronix.de> wrote: > --- a/kernel/printk/printk.c > +++ b/kernel/printk/printk.c > @@ -1072,6 +1072,8 @@ static inline void log_buf_add_cpu(void) > #endif /* CONFIG_SMP */ > > static void cons_alloc_percpu_data(struct console *con); > +static void cons_atomic_flush(void); > +static void cons_wake_threads(void); > > static void __init set_percpu_data_ready(void) > { > @@ -2270,17 +2272,21 @@ asmlinkage int vprintk_emit(int facility > > printed_len = vprintk_store(facility, level, dev_info, fmt, args); > > + /* > + * The caller may be holding system-critical or > + * timing-sensitive locks. Disable preemption during > + * printing of all remaining records to all consoles so that > + * this context can return as soon as possible. Hopefully > + * another printk() caller will take over the printing. > + */ > + preempt_disable(); > + > + /* Flush the non-BKL consoles if required */ > + cons_atomic_flush(); > + > /* If called from the scheduler, we can not call up(). */ > if (!in_sched) { > /* > - * The caller may be holding system-critical or > - * timing-sensitive locks. Disable preemption during > - * printing of all remaining records to all consoles so that > - * this context can return as soon as possible. Hopefully > - * another printk() caller will take over the printing. > - */ > - preempt_disable(); > - /* > * Try to acquire and then immediately release the console > * semaphore. The release will print out buffers. With the > * spinning variant, this context tries to take over the > @@ -2288,9 +2294,11 @@ asmlinkage int vprintk_emit(int facility > */ > if (console_trylock_spinning()) > console_unlock(); > - preempt_enable(); > } > > + preempt_enable(); > + > + cons_wake_threads(); > wake_up_klogd(); > return printed_len; > }
Atomic flushing also needs to occur for the cases where deferred printing is used (NMI or explicit defer). The following hunk will take care of that.
@@ -3648,6 +3658,8 @@ void wake_up_klogd(void)
void defer_console_output(void) { + cons_atomic_flush(); + /* * New messages may have been added directly to the ringbuffer * using vprintk_store(), so wake any waiters as well.
John Ogness
| |