Pull printk updates from Petr Mladek:
- Make %pK behave the same as %p for kptr_restrict == 0 also with
no_hash_pointers parameter
- Ignore the default console in the device tree also when console=null
or console="" is used on the command line
- Document console=null and console="" behavior
- Prevent a deadlock and a livelock caused by console_lock in panic()
- Make console_lock available for panicking CPU
- Fast query for the next to-be-used sequence number
- Use the expected return values in printk.devkmsg __setup handler
- Use the correct atomic operations in wake_up_klogd() irq_work handler
- Avoid possible unaligned access when handling %4cc printing format
* tag 'printk-for-5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux:
printk: fix return value of printk.devkmsg __setup handler
vsprintf: Fix %pK with kptr_restrict == 0
printk: make suppress_panic_printk static
printk: Set console_set_on_cmdline=1 when __add_preferred_console() is called with user_specified == true
Docs: printk: add 'console=null|""' to admin/kernel-parameters
printk: use atomic updates for klogd work
printk: Drop console_sem during panic
printk: Avoid livelock with heavy printk during panic
printk: disable optimistic spin during panic
printk: Add panic_in_progress helper
vsprintf: Move space out of string literals in fourcc_string()
vsprintf: Fix potential unaligned access
printk: ringbuffer: Improve prb_next_seq() performance
In case of using console="" or console=null
set console_set_on_cmdline=1 to disable "stdout-path" node from DT.
We basically need to set it every time when __add_preferred_console()
is called with parameter 'user_specified' set.
Therefore we can move setting it into a helper function that is
called from __add_preferred_console().
Suggested-by: Petr Mladek <pmladek@suse.com>
Signed-off-by: Andre Kalb <andre.kalb@sma.de>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Signed-off-by: Petr Mladek <pmladek@suse.com>
Link: https://lore.kernel.org/r/YgzU4ho8l6XapyG2@pc6682
The per-cpu @printk_pending variable can be updated from
sleepable contexts, such as:
get_random_bytes()
warn_unseeded_randomness()
printk_deferred()
defer_console_output()
and can be updated from interrupt contexts, such as:
handle_irq_event_percpu()
__irq_wake_thread()
wake_up_process()
try_to_wake_up()
select_task_rq()
select_fallback_rq()
printk_deferred()
defer_console_output()
and can be updated from NMI contexts, such as:
vprintk()
if (in_nmi()) defer_console_output()
Therefore the atomic variant of the updating functions must be used.
Replace __this_cpu_xchg() with this_cpu_xchg().
Replace __this_cpu_or() with this_cpu_or().
Reported-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: John Ogness <john.ogness@linutronix.de>
Signed-off-by: Petr Mladek <pmladek@suse.com>
Link: https://lore.kernel.org/r/87iltld4ue.fsf@jogness.linutronix.de
During panic(), if another CPU is writing heavily the kernel log (e.g.
via /dev/kmsg), then the panic CPU may livelock writing out its messages
to the console. Note when too many messages are dropped during panic and
suppress further printk, except from the panic CPU. This could result in
some important messages being dropped. However, messages are already
being dropped, so this approach at least prevents a livelock.
Reviewed-by: Petr Mladek <pmladek@suse.com>
Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Signed-off-by: Petr Mladek <pmladek@suse.com>
Link: https://lore.kernel.org/r/20220202171821.179394-4-stephen.s.brennan@oracle.com
A CPU executing with console lock spinning enabled might be halted
during a panic. Before the panicking CPU calls console_flush_on_panic(),
it may call console_trylock(), which attempts to optimistically spin,
deadlocking the panic CPU:
CPU 0 (panic CPU) CPU 1
----------------- ------
printk() {
vprintk_func() {
vprintk_default() {
vprintk_emit() {
console_unlock() {
console_lock_spinning_enable();
... printing to console ...
panic() {
crash_smp_send_stop() {
NMI -------------------> HALT
}
atomic_notifier_call_chain() {
printk() {
...
console_trylock_spinnning() {
// optimistic spin infinitely
This hang during panic can be induced when a kdump kernel is loaded, and
crash_kexec_post_notifiers=1 is present on the kernel command line. The
following script which concurrently writes to /dev/kmsg, and triggers a
panic, can result in this hang:
#!/bin/bash
date
# 991 chars (based on log buffer size):
chars="$(printf 'a%.0s' {1..991})"
while :; do
echo $chars > /dev/kmsg
done &
echo c > /proc/sysrq-trigger &
date
exit
To avoid this deadlock, ensure that console_trylock_spinning() does not
allow spinning once a panic has begun.
Fixes: dbdda842fe ("printk: Add console owner and waiter logic to load balance console writes")
Suggested-by: Petr Mladek <pmladek@suse.com>
Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Signed-off-by: Petr Mladek <pmladek@suse.com>
Link: https://lore.kernel.org/r/20220202171821.179394-3-stephen.s.brennan@oracle.com
prb_next_seq() always iterates from the first known sequence number.
In the worst case, it might loop 8k times for 256kB buffer,
15k times for 512kB buffer, and 64k times for 2MB buffer.
It was reported that polling and reading using syslog interface
might occupy 50% of CPU.
Speedup the search by storing @id of the last finalized descriptor.
The loop is still needed because the @id is stored and read in the best
effort way. An atomic variable is used to keep the @id consistent.
But the stores and reads are not serialized against each other.
The descriptor could get reused in the meantime. The related sequence
number will be used only when it is still valid.
An invalid value should be read _only_ when there is a flood of messages
and the ringbuffer is rapidly reused. The performance is the least
problem in this case.
Reported-by: Chunlei Wang <chunlei.wang@mediatek.com>
Signed-off-by: Mukesh Ojha <quic_mojha@quicinc.com>
Reviewed-by: John Ogness <john.ogness@linutronix.de>
Signed-off-by: Petr Mladek <pmladek@suse.com>
Link: https://lore.kernel.org/r/1642770388-17327-1-git-send-email-quic_mojha@quicinc.com
Link: https://lore.kernel.org/lkml/YXlddJxLh77DKfIO@alley/T/#m43062e8b2a17f8dbc8c6ccdb8851fb0dbaabbb14
The variable @bcon has two meanings. It is used several times for iterating
the list of registered consoles. In the meantime, it holds the information
whether a boot console is first in @console_drivers list.
The information about the 1st console driver used to be important for
the decision whether to install the new console by default or not.
It allowed to re-evaluate the variable @need_default_console when
a real console with tty binding has been unregistered in the meantime.
The decision about the default console is not longer affected by @bcon
variable. The current code checks whether the first driver is real
and has tty binding directly.
The information about the first console is still used for two more
decisions:
1. It prevents duplicate output on non-boot consoles with
CON_CONSDEV flag set.
2. Early/boot consoles are unregistered when a real console with
CON_CONSDEV is registered and @keep_bootcon is not set.
The behavior in the real life is far from obvious. @bcon is set according
to the first console @console_drivers list. But the first position in
the list is special:
1. Consoles with CON_CONSDEV flag are put at the beginning of
the list. It is either the preferred console or any console
with tty binding registered by default.
2. Another console might become the first in the list when
the first console in the list is unregistered. It might
happen either explicitly or automatically when boot
consoles are unregistered.
There is one more important rule:
+ Boot consoles can't be registered when any real console
is already registered.
It is a puzzle. The main complication is the dependency on the first
position is the list and the complicated rules around it.
Let's try to make it easier:
1. Add variable @bootcon_enabled and set it by iterating all registered
consoles. The variable has obvious meaning and more predictable
behavior. Any speed optimization and other tricks are not worth it.
2. Use a generic name for the variable that is used to iterate
the list on registered console drivers.
Behavior change:
No, maybe surprisingly, there is _no_ behavior change!
Let's provide the proof by contradiction. Both operations, duplicate
output prevention and boot consoles removal, are done only when
the newly added console has CON_CONSDEV flag set. The behavior
would change when the new @bootcon_enabled has different value
than the original @bcon.
By other words, the behavior would change when the following conditions
are true:
+ a console with CON_CONSDEV flag is added
+ a real (non-boot) console is the first in the list
+ a boot console is later in the list
Now, a real console might be first in the list only when:
+ It was the first registered console. In this case, there can't be
any boot console because any later ones were rejected.
+ It was put at the first position because it had CON_CONSDEV flag
set. It was either the preferred console or it was a console with
tty binding registered by default. We are interested only in
a real consoles here. And real console with tty binding fulfills
conditions of the default console.
Now, there is always only one console that is either preferred
or fulfills conditions of the default console. It can't be already
in the list and being registered at the same time.
As a result, the above three conditions could newer be "true" at
the same time. Therefore the behavior can't change.
Final dilemma:
OK, the new code has the same behavior. But is the change in the right
direction? What if the handling of @console_drivers is updated in
the future?
OK, let's look at it from another angle:
1. The ordering of @console_drivers list is important only in
console_device() function. The first console driver with tty
binding gets associated with /dev/console.
2. CON_CONSDEV flag is shown in /proc/consoles. And it should be set
for the driver that is returned by console_device().
3. A boot console is removed and the duplicated output is prevented
when the real console with CON_CONSDEV flag is registered.
Now, in the ideal world:
+ The driver associated with /dev/console should be either a console
preferred via the command line, device tree, or SPCR. Or it should
be the first real console with tty binding registered by default.
+ The code should match the related boot and real console drivers.
It should unregister only the obsolete boot driver. And the duplicated
output should be prevented only on the related real driver.
It is clear that it is not guaranteed by the current code. Instead,
the current code looks like a maze of heuristics that try to achieve
the above.
It is result of adding several features over last few decades. For example,
a possibility to register more consoles, unregister consoles, boot
consoles, consoles without tty binding, device tree, SPCR, braille
consoles.
Anyway, there is no reason why the decision, about removing boot consoles
and preventing duplicated output, should depend on the first console
in the list. The current code does the decisions primary by CON_CONSDEV
flag that is used for the preferred console. It looks like a
good compromise. And the change seems to be in the right direction.
Signed-off-by: Petr Mladek <pmladek@suse.com>
Link: https://lore.kernel.org/r/20211122132649.12737-6-pmladek@suse.com
The variable @need_default_console is used to decide whether a newly
registered console should get enabled by default.
The logic is complicated. It can be modified in a register_console()
call. But it is always re-evaluated in the next call by the following
condition:
if (need_default_console || bcon || !console_drivers)
need_default_console = preferred_console < 0;
In short, the value is updated when either of the condition is valid:
+ the value is still, or again, "true"
+ boot/early console is still the first in @console_driver list
+ @console_driver list is empty
The value is updated according to @preferred_console. In particular,
it is set to "false" when a @preferred_console was set by
__add_preferred_console(). This happens when a non-braille console
was added via the command line, device tree, or SPCR.
It far from clear what this all means together. Let's look at
@need_default_console from another angle:
1. The value is "true" by default. It means that it is always set
according to @preferred_console during the first register_console()
call.
By other words, the first register_console() call will register
the console by default only when none non-braille console was defined
via the command line, device tree, or SPCR.
2. The value will always stay "false" when @preferred_console is set.
By other words, try_enable_default_console() will never get called
when a non-braille console is explicitly required.
4. The value might be set to "false" in try_enable_default_console()
when a console with tty binding (driver) gets enabled.
In this case CON_CONSDEV is set as well. It causes that the console
will be inserted as first into the list @console_driver. It might
be either real or boot/early console.
5. The value will be set _back_ to "true" in the next register_console()
call when:
+ The console added by the previous register_console() had been
a boot/early one.
+ The last console has been unregistered in the meantime and
a boot/early console became first in @console_drivers list
again. Or the list became empty.
By other words, the value will stay "false" only when the last
registered console was real, had tty binding, and was not removed
in the mean time.
The main logic looks clear:
+ Consoles are enabled by default only when no one is preferred
via the command line, device tree, or SPCR.
+ By default, any console is enabled until a real console
with tty binding gets registered.
The behavior when the real console with tty binding is later removed
is a bit unclear:
+ By default, any new console is registered again only when there
is no console or the first console in the list is a boot one.
The question is why the code is suddenly happy when a real console
without tty binding is the first in the list. It looks like an overlook
and bug.
Conclusion:
The state of @preferred_console and the first console in @console_driver
list should be enough to decide whether we need to enable the given console
by default.
The rules are simple. New consoles are _not_ enabled by default
when either of the following conditions is true:
+ @preferred_console is set. It means that a non-braille console
is explicitly configured via the command line, device tree, or SPCR.
+ A real console with tty binding is registered. Such a console will
have CON_CONSDEV flag set and will always be the first in
@console_drivers list.
Note:
The new code does not use @bcon variable. The meaning of the variable
is far from clear. The direct check of the first console in the list
makes it more clear that only real console fulfills requirements
of the default console.
Behavior change:
As already discussed above. There was one situation where the original
code worked a strange way. Let's have:
+ console A: real console without tty binding
+ console B: real console with tty binding
and do:
register_console(A); /* 1st step */
register_console(B); /* 2nd step */
unregister_console(B); /* 3rd step */
register_console(B); /* 4th step */
The original code will not register the console B in the 4th step.
@need_default_console is set to "false" in 2nd step. The real console
with tty binding (driver) is then removed in the 3rd step.
But @need_default_console will stay "false" in the 4th step because
there is no boot/early console and @registered_consoles list is not
empty.
The new code will register the console B in the 4th step because
it checks whether the first console has tty binding (->driver)
This behavior change should acceptable:
1. The scenario requires manual intervention (console removal).
The system should boot with the same consoles as before.
2. Console B is registered again probably because the user wants
to use it. The most likely scenario is that the related
module is reloaded.
3. It makes the behavior more consistent and predictable.
Signed-off-by: Petr Mladek <pmladek@suse.com>
Link: https://lore.kernel.org/r/20211122132649.12737-5-pmladek@suse.com
There is no need to clear @need_default_console when a console
preferred by the command line, device tree, or SPCR, gets enabled.
The code is called only when some non-braille console matched a console
in @console_cmdline array. It means that a non-braille console was added
in __add_preferred_console() and the variable preferred_console is set
to a number >= 0. As a result, @need_default_console is always set to
"false" in the magic condition:
if (need_default_console || bcon || !console_drivers)
need_default_console = preferred_console < 0;
This is one small step in removing the above magic condition
that is hard to follow.
The patch removes one superfluous assignment and should not change
the functionality.
Signed-off-by: Petr Mladek <pmladek@suse.com>
Link: https://lore.kernel.org/r/20211122132649.12737-4-pmladek@suse.com
The logic around the variable @has_preferred_console made my head
spin many times. Part of the problem is the ambiguous name.
There is the variable @preferred_console. It points to the last
non-braille console in @console_cmdline array. This array contains
consoles preferred via the command line, device tree, or SPCR.
Then there is the variable @has_preferred_console. It is set to
"true" when @preferred_console is enabled or when a console with
tty binding gets enabled by default.
It might get reset back by the magic condition:
if (!has_preferred_console || bcon || !console_drivers)
has_preferred_console = preferred_console >= 0;
It is a puzzle. Dumb explanation is that it gets re-evaluated
when:
+ it was not set before (see above when it gets set)
+ there is still an early console enabled (bcon)
+ there is no console enabled (!console_drivers)
This is still a puzzle.
It gets more clear when we see where the value is checked. The only
meaning of the variable is to decide whether we should try to enable
the new console by default.
Rename the variable according to the single situation where
the value is checked.
The rename requires an inverted logic. Otherwise, it is a simple
search & replace. It does not change the functionality.
Signed-off-by: Petr Mladek <pmladek@suse.com>
Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Link: https://lore.kernel.org/r/20211122132649.12737-3-pmladek@suse.com
Put the code enabling a console by default into a separate function
called try_enable_default_console().
Rename try_enable_new_console() to try_enable_preferred_console() to
make the purpose of the different variants more clear.
It is a code refactoring without any functional change.
Signed-off-by: Petr Mladek <pmladek@suse.com>
Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Link: https://lore.kernel.org/r/20211122132649.12737-2-pmladek@suse.com
Pull printk fixes from Petr Mladek:
- Try to flush backtraces from other CPUs also on the local one. This
was a regression caused by printk_safe buffers removal.
- Remove header dependency warning.
* tag 'printk-for-5.16-fixup' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux:
printk: Remove printk.h inclusion in percpu.h
printk: restore flushing of NMI buffers on remote CPUs after NMI backtraces
printk from NMI context relies on irq work being raised on the local CPU
to print to console. This can be a problem if the NMI was raised by a
lockup detector to print lockup stack and regs, because the CPU may not
enable irqs (because it is locked up).
Introduce printk_trigger_flush() that can be called another CPU to try
to get those messages to the console, call that where printk_safe_flush
was previously called.
Fixes: 93d102f094 ("printk: remove safe buffers")
Cc: stable@vger.kernel.org # 5.15
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Reviewed-by: John Ogness <john.ogness@linutronix.de>
Signed-off-by: Petr Mladek <pmladek@suse.com>
Link: https://lore.kernel.org/r/20211107045116.1754411-1-npiggin@gmail.com
Merge misc updates from Andrew Morton:
"257 patches.
Subsystems affected by this patch series: scripts, ocfs2, vfs, and
mm (slab-generic, slab, slub, kconfig, dax, kasan, debug, pagecache,
gup, swap, memcg, pagemap, mprotect, mremap, iomap, tracing, vmalloc,
pagealloc, memory-failure, hugetlb, userfaultfd, vmscan, tools,
memblock, oom-kill, hugetlbfs, migration, thp, readahead, nommu, ksm,
vmstat, madvise, memory-hotplug, rmap, zsmalloc, highmem, zram,
cleanups, kfence, and damon)"
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (257 commits)
mm/damon: remove return value from before_terminate callback
mm/damon: fix a few spelling mistakes in comments and a pr_debug message
mm/damon: simplify stop mechanism
Docs/admin-guide/mm/pagemap: wordsmith page flags descriptions
Docs/admin-guide/mm/damon/start: simplify the content
Docs/admin-guide/mm/damon/start: fix a wrong link
Docs/admin-guide/mm/damon/start: fix wrong example commands
mm/damon/dbgfs: add adaptive_targets list check before enable monitor_on
mm/damon: remove unnecessary variable initialization
Documentation/admin-guide/mm/damon: add a document for DAMON_RECLAIM
mm/damon: introduce DAMON-based Reclamation (DAMON_RECLAIM)
selftests/damon: support watermarks
mm/damon/dbgfs: support watermarks
mm/damon/schemes: activate schemes based on a watermarks mechanism
tools/selftests/damon: update for regions prioritization of schemes
mm/damon/dbgfs: support prioritization weights
mm/damon/vaddr,paddr: support pageout prioritization
mm/damon/schemes: prioritize regions within the quotas
mm/damon/selftests: support schemes quotas
mm/damon/dbgfs: support quotas of schemes
...