author | Linus Torvalds <torvalds@linux-foundation.org> | |
Thu, 1 Feb 2018 21:36:15 +0000 (13:36 -0800) | ||
committer | Linus Torvalds <torvalds@linux-foundation.org> | |
Thu, 1 Feb 2018 21:36:15 +0000 (13:36 -0800) |
Pull printk updates from Petr Mladek:
- Add a console_msg_format command line option:
The value "default" keeps the old "[time stamp] text\n" format. The
value "syslog" allows to see the syslog-like "<log
level>[timestamp] text" format.
This feature was requested by people doing regression tests, for
example, 0day robot. They want to have both filtered and full logs
at hands.
- Reduce the risk of softlockup:
Pass the console owner in a busy loop.
This is a new approach to the old problem. It was first proposed by
Steven Rostedt on Kernel Summit 2017. It marks a context in which
the console_lock owner calls console drivers and could not sleep.
On the other side, printk() callers could detect this state and use
a busy wait instead of a simple console_trylock(). Finally, the
console_lock owner checks if there is a busy waiter at the end of
the special context and eventually passes the console_lock to the
waiter.
The hand-off works surprisingly well and helps in many situations.
Well, there is still a possibility of the softlockup, for example,
when the flood of messages stops and the last owner still has too
much to flush.
There is increasing number of people having problems with
printk-related softlockups. We might eventually need to get better
solution. Anyway, this looks like a good start and promising
direction.
- Do not allow to schedule in console_unlock() called from printk():
This reverts an older controversial commit. The reschedule helped
to avoid softlockups. But it also slowed down the console output.
This patch is obsoleted by the new console waiter logic described
above. In fact, the reschedule made the hand-off less effective.
- Deprecate "%pf" and "%pF" format specifier:
It was needed on ia64, ppc64 and parisc64 to dereference function
descriptors and show the real function address. It is done
transparently by "%ps" and "pS" format specifier now.
Sergey Senozhatsky found that all the function descriptors were in
a special elf section and could be easily detected.
- Remove printk_symbol() API:
It has been obsoleted by "%pS" format specifier, and this change
helped to remove few continuous lines and a less intuitive old API.
- Remove redundant memsets:
Sergey removed unnecessary memset when processing printk.devkmsg
command line option.
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/pmladek/printk: (27 commits)
printk: drop redundant devkmsg_log_str memsets
printk: Never set console_may_schedule in console_trylock()
printk: Hide console waiter logic into helpers
printk: Add console owner and waiter logic to load balance console writes
kallsyms: remove print_symbol() function
checkpatch: add pF/pf deprecation warning
symbol lookup: introduce dereference_symbol_descriptor()
parisc64: Add .opd based function descriptor dereference
powerpc64: Add .opd based function descriptor dereference
ia64: Add .opd based function descriptor dereference
sections: split dereference_function_descriptor()
openrisc: Fix conflicting types for _exext and _stext
lib: do not use print_symbol()
irq debug: do not use print_symbol()
sysfs: do not use print_symbol()
drivers: do not use print_symbol()
x86: do not use print_symbol()
unicore32: do not use print_symbol()
sh: do not use print_symbol()
mn10300: do not use print_symbol()
...
- Add a console_msg_format command line option:
The value "default" keeps the old "[time stamp] text\n" format. The
value "syslog" allows to see the syslog-like "<log
level>[timestamp] text" format.
This feature was requested by people doing regression tests, for
example, 0day robot. They want to have both filtered and full logs
at hands.
- Reduce the risk of softlockup:
Pass the console owner in a busy loop.
This is a new approach to the old problem. It was first proposed by
Steven Rostedt on Kernel Summit 2017. It marks a context in which
the console_lock owner calls console drivers and could not sleep.
On the other side, printk() callers could detect this state and use
a busy wait instead of a simple console_trylock(). Finally, the
console_lock owner checks if there is a busy waiter at the end of
the special context and eventually passes the console_lock to the
waiter.
The hand-off works surprisingly well and helps in many situations.
Well, there is still a possibility of the softlockup, for example,
when the flood of messages stops and the last owner still has too
much to flush.
There is increasing number of people having problems with
printk-related softlockups. We might eventually need to get better
solution. Anyway, this looks like a good start and promising
direction.
- Do not allow to schedule in console_unlock() called from printk():
This reverts an older controversial commit. The reschedule helped
to avoid softlockups. But it also slowed down the console output.
This patch is obsoleted by the new console waiter logic described
above. In fact, the reschedule made the hand-off less effective.
- Deprecate "%pf" and "%pF" format specifier:
It was needed on ia64, ppc64 and parisc64 to dereference function
descriptors and show the real function address. It is done
transparently by "%ps" and "pS" format specifier now.
Sergey Senozhatsky found that all the function descriptors were in
a special elf section and could be easily detected.
- Remove printk_symbol() API:
It has been obsoleted by "%pS" format specifier, and this change
helped to remove few continuous lines and a less intuitive old API.
- Remove redundant memsets:
Sergey removed unnecessary memset when processing printk.devkmsg
command line option.
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/pmladek/printk: (27 commits)
printk: drop redundant devkmsg_log_str memsets
printk: Never set console_may_schedule in console_trylock()
printk: Hide console waiter logic into helpers
printk: Add console owner and waiter logic to load balance console writes
kallsyms: remove print_symbol() function
checkpatch: add pF/pf deprecation warning
symbol lookup: introduce dereference_symbol_descriptor()
parisc64: Add .opd based function descriptor dereference
powerpc64: Add .opd based function descriptor dereference
ia64: Add .opd based function descriptor dereference
sections: split dereference_function_descriptor()
openrisc: Fix conflicting types for _exext and _stext
lib: do not use print_symbol()
irq debug: do not use print_symbol()
sysfs: do not use print_symbol()
drivers: do not use print_symbol()
x86: do not use print_symbol()
unicore32: do not use print_symbol()
sh: do not use print_symbol()
mn10300: do not use print_symbol()
...
18 files changed:
Simple merge
index 258b46435320a75c399854aaa2cb4027286029ec,58c44cce90b662c7a96772fce4ad971a4130d7cb..934559b3c130f6910abd2e587cc8f4dd78e4bf72
::
+ %pS versatile_init+0x0/0x110
+ %ps versatile_init
%pF versatile_init+0x0/0x110
%pf versatile_init
- %pS versatile_init+0x0/0x110
%pSR versatile_init+0x9/0x110
(with __builtin_extract_return_addr() translation)
- %ps versatile_init
%pB prev_fn_of_versatile_init+0x88/0x88
- The ``F`` and ``f`` specifiers are for printing function pointers,
- for example, f->func, &gettimeofday. They have the same result as
- ``S`` and ``s`` specifiers. But they do an extra conversion on
- ia64, ppc64 and parisc64 architectures where the function pointers
- are actually function descriptors.
+
-format. They result in the symbol name with (``S``) or without (``s``)
+ The ``S`` and ``s`` specifiers are used for printing a pointer in symbolic
++format. They result in the symbol name with (S) or without (s)
+ offsets. If KALLSYMS are disabled then the symbol address is printed instead.
- The ``S`` and ``s`` specifiers can be used for printing symbols
- from direct addresses, for example, __builtin_return_address(0),
- (void *)regs->ip. They result in the symbol name with (S) or
- without (s) offsets. If KALLSYMS are disabled then the symbol
- address is printed instead.
+ Note, that the ``F`` and ``f`` specifiers are identical to ``S`` (``s``)
+ and thus deprecated. We have ``F`` and ``f`` because on ia64, ppc64 and
+ parisc64 function pointers are indirect and, in fact, are function
+ descriptors, which require additional dereferencing before we can lookup
+ the symbol. As of now, ``S`` and ``s`` perform dereferencing on those
+ platforms (when needed), so ``F`` and ``f`` exist for compatibility
+ reasons only.
The ``B`` specifier results in the symbol name with offsets and should be
used when printing stack backtraces. The specifier takes into
consideration the effect of compiler optimisations which may occur
-when tail-call``s are used and marked with the noreturn GCC attribute.
+when tail-calls are used and marked with the noreturn GCC attribute.
- Examples::
-
- printk("Going to call: %pF\n", gettimeofday);
- printk("Going to call: %pF\n", p->func);
- printk("%s: called from %pS\n", __func__, (void *)_RET_IP_);
- printk("%s: called from %pS\n", __func__,
- (void *)__builtin_return_address(0));
- printk("Faulted at %pS\n", (void *)regs->ip);
- printk(" %s%pB\n", (reliable ? "" : "? "), (void *)*stack);
-
Kernel Pointers
-===============
+---------------
::
diff --cc arch/arm64/kernel/process.c
Simple merge
diff --cc arch/ia64/kernel/vmlinux.lds.S
Simple merge
diff --cc arch/openrisc/kernel/traps.c
Simple merge
diff --cc arch/parisc/kernel/process.c
Simple merge
diff --cc arch/powerpc/kernel/vmlinux.lds.S
Simple merge
diff --cc arch/x86/kernel/cpu/mcheck/mce.c
Simple merge
diff --cc drivers/base/core.c
Simple merge
diff --cc fs/sysfs/file.c
Simple merge
diff --cc include/linux/kallsyms.h
index bd118a6c60cbf8c5dd28478239e44550d899b57c,7574b1db483d5184a31a5f61d19485aeacd25f07..d79d1e7486bdf78d291d92ed785a9845a59ceb5e
+++ b/include/linux/kallsyms.h
#define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s]") + (KSYM_NAME_LEN - 1) + \
2*(BITS_PER_LONG*3/10) + (MODULE_NAME_LEN - 1) + 1)
-#ifndef CONFIG_64BIT
-# define KALLSYM_FMT "%08lx"
-#else
-# define KALLSYM_FMT "%016lx"
-#endif
-
struct module;
+ static inline int is_kernel_inittext(unsigned long addr)
+ {
+ if (addr >= (unsigned long)_sinittext
+ && addr <= (unsigned long)_einittext)
+ return 1;
+ return 0;
+ }
+
+ static inline int is_kernel_text(unsigned long addr)
+ {
+ if ((addr >= (unsigned long)_stext && addr <= (unsigned long)_etext) ||
+ arch_is_kernel_text(addr))
+ return 1;
+ return in_gate_area_no_mm(addr);
+ }
+
+ static inline int is_kernel(unsigned long addr)
+ {
+ if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
+ return 1;
+ return in_gate_area_no_mm(addr);
+ }
+
+ static inline int is_ksym_addr(unsigned long addr)
+ {
+ if (IS_ENABLED(CONFIG_KALLSYMS_ALL))
+ return is_kernel(addr);
+
+ return is_kernel_text(addr) || is_kernel_inittext(addr);
+ }
+
+ static inline void *dereference_symbol_descriptor(void *ptr)
+ {
+ #ifdef HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR
+ struct module *mod;
+
+ ptr = dereference_kernel_function_descriptor(ptr);
+ if (is_ksym_addr((unsigned long)ptr))
+ return ptr;
+
+ preempt_disable();
+ mod = __module_address((unsigned long)ptr);
+ preempt_enable();
+
+ if (mod)
+ ptr = dereference_module_function_descriptor(mod, ptr);
+ #endif
+ return ptr;
+ }
+
#ifdef CONFIG_KALLSYMS
/* Lookup the address for a symbol. Returns 0 if not found. */
unsigned long kallsyms_lookup_name(const char *name);
diff --cc include/linux/module.h
Simple merge
diff --cc kernel/irq/debug.h
index e4d3819a91cc7d7bda5416bfd5aaba99a5576cce,7e06dd275c17b32b2635fde6b097f301ce3183d6..8ccb326d2977aca1347269296d9661ce8718bc11
--- 1/kernel/irq/debug.h
--- 2/kernel/irq/debug.h
+++ b/kernel/irq/debug.h
static inline void print_irq_desc(unsigned int irq, struct irq_desc *desc)
{
+ static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 5);
+
+ if (!__ratelimit(&ratelimit))
+ return;
+
printk("irq %d, desc: %p, depth: %d, count: %d, unhandled: %d\n",
irq, desc, desc->depth, desc->irq_count, desc->irqs_unhandled);
- printk("->handle_irq(): %p, ", desc->handle_irq);
- print_symbol("%s\n", (unsigned long)desc->handle_irq);
- printk("->irq_data.chip(): %p, ", desc->irq_data.chip);
- print_symbol("%s\n", (unsigned long)desc->irq_data.chip);
+ printk("->handle_irq(): %p, %pS\n",
+ desc->handle_irq, desc->handle_irq);
+ printk("->irq_data.chip(): %p, %pS\n",
+ desc->irq_data.chip, desc->irq_data.chip);
printk("->action(): %p\n", desc->action);
if (desc->action) {
- printk("->action->handler(): %p, ", desc->action->handler);
- print_symbol("%s\n", (unsigned long)desc->action->handler);
+ printk("->action->handler(): %p, %pS\n",
+ desc->action->handler, desc->action->handler);
}
___P(IRQ_LEVEL);
diff --cc kernel/kallsyms.c
Simple merge
diff --cc kernel/module.c
Simple merge
diff --cc kernel/printk/printk.c
Simple merge
diff --cc lib/vsprintf.c
Simple merge
diff --cc scripts/checkpatch.pl
index ba03f17ff662a16e6226876aebf71ddff4601f8b,0bb68e7ff1734d3b1388ac095935deee59c25a05..e954df2b207706875ab9695ad2c1c5daf0ec1ed0
+++ b/scripts/checkpatch.pl
for (my $count = $linenr; $count <= $lc; $count++) {
my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
$fmt =~ s/%%//g;
- if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGNOx]).)/) {
- if ($fmt =~ /(\%[\*\d\.]*p(?![\WSsBKRraEhMmIiUDdgVCbGNO]).)/) {
++ if ($fmt =~ /(\%[\*\d\.]*p(?![\WSsBKRraEhMmIiUDdgVCbGNOx]).)/) {
$bad_extension = $1;
last;
}