Printk changes for 4.18
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIbBAABAgAGBQJbFnd0AAoJEFKgDEdIgJTyuWgP+O/+kRbXR5WTphJ8e9+CqHp4 LF6AJXTuiA0fPJ5TcTNtZ84AVvmoNcTXnaM3Ou8HfR2qER8Gqu4WbdcfqhU2/KUq L4x4YlW+DZPOhy7chFx/yTgdSWc8vBwSG80DLSQhjnOJBY4SwBaVSSCYi/CSiAvr I18zt03mSXUe9RADrT3W0rbryIbyICvZjMbKkUlSm7ZTQv482FaU2Jezp86qDYLB FWc7QOLKzXRjFTg5IQ91mTtqnM2gnHwqOzGFR+jILn8BQwVe5dYp42sCSne34kBD pHz5GosIIYRH3Eik7pNzOhN4nsncLfPwwQQx/YH1KmKteNPTPJZO01pEwMaurc3w LaoTD7LNDyZCkzxJF/kKOiW4ys1cMf5jyoiV9Sou7PIVPcxuR1ToMXQvHSplZPG1 UyDwW41XVmluYdC2O4ybRQWMu3nmrQKCjjGkCmizK3xMWNs4u/5Y4kS3mi7Zwk3y X1wlm2BW7RPzVl7WWlNergR2UHNq2zgToOWzFfSqXtMukYbmei+mXYIIe6nKa2GH ji/d/Sr/RIAgUs46sBzRBLK9ZCqybPxSvnfNZx8WodLU1dLYT3yY1vGZbGPEMB2w puS7ctPT9dfnBxi/MOegXlTyKTOJkCB3o/bsWkIdSvRI45qbYE1aQN8IMmDQ20sv X8A3LnDQZvUfKEULrU0= =hB2y -----END PGP SIGNATURE----- Merge tag 'printk-for-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/pmladek/printk Pull printk updates from Petr Mladek: - Help userspace log daemons to catch up with a flood of messages. They will get woken after each message even if the console is far behind and handled by another process. - Flush printk safe buffers safely even when panic() happens in the normal context. - Fix possible va_list reuse when race happened in printk_safe(). - Remove %pCr printf format to prevent sleeping in the atomic context. - Misc vsprintf code cleanup. * tag 'printk-for-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/pmladek/printk: printk: drop in_nmi check from printk_safe_flush_on_panic() lib/vsprintf: Remove atomic-unsafe support for %pCr serial: sh-sci: Stop using printk format %pCr thermal: bcm2835: Stop using printk format %pCr clk: renesas: cpg-mssr: Stop using printk format %pCr printk: fix possible reuse of va_list variable printk: wake up klogd in vprintk_emit vsprintf: Tweak pF/pf comment lib/vsprintf: Mark expected switch fall-through lib/vsprintf: Replace space with '_' before crng is ready lib/vsprintf: Deduplicate pointer_string() lib/vsprintf: Move pointer_string() upper lib/vsprintf: Make flag_spec global lib/vsprintf: Make strspec global lib/vsprintf: Make dec_spec global lib/test_printf: Mark big constant with UL
This commit is contained in:
commit
d75ae5bdf2
|
@ -419,11 +419,10 @@ struct clk
|
|||
|
||||
%pC pll1
|
||||
%pCn pll1
|
||||
%pCr 1560000000
|
||||
|
||||
For printing struct clk structures. %pC and %pCn print the name
|
||||
(Common Clock Framework) or address (legacy clock framework) of the
|
||||
structure; %pCr prints the current clock rate.
|
||||
structure.
|
||||
|
||||
Passed by reference.
|
||||
|
||||
|
|
|
@ -258,8 +258,9 @@ struct clk *cpg_mssr_clk_src_twocell_get(struct of_phandle_args *clkspec,
|
|||
dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx,
|
||||
PTR_ERR(clk));
|
||||
else
|
||||
dev_dbg(dev, "clock (%u, %u) is %pC at %pCr Hz\n",
|
||||
clkspec->args[0], clkspec->args[1], clk, clk);
|
||||
dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n",
|
||||
clkspec->args[0], clkspec->args[1], clk,
|
||||
clk_get_rate(clk));
|
||||
return clk;
|
||||
}
|
||||
|
||||
|
@ -326,7 +327,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
|
|||
if (IS_ERR_OR_NULL(clk))
|
||||
goto fail;
|
||||
|
||||
dev_dbg(dev, "Core clock %pC at %pCr Hz\n", clk, clk);
|
||||
dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
|
||||
priv->clks[id] = clk;
|
||||
return;
|
||||
|
||||
|
@ -392,7 +393,7 @@ static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod,
|
|||
if (IS_ERR(clk))
|
||||
goto fail;
|
||||
|
||||
dev_dbg(dev, "Module clock %pC at %pCr Hz\n", clk, clk);
|
||||
dev_dbg(dev, "Module clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
|
||||
priv->clks[id] = clk;
|
||||
priv->smstpcr_saved[clock->index / 32].mask |= BIT(clock->index % 32);
|
||||
return;
|
||||
|
|
|
@ -213,8 +213,8 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
|
|||
rate = clk_get_rate(data->clk);
|
||||
if ((rate < 1920000) || (rate > 5000000))
|
||||
dev_warn(&pdev->dev,
|
||||
"Clock %pCn running at %pCr Hz is outside of the recommended range: 1.92 to 5MHz\n",
|
||||
data->clk, data->clk);
|
||||
"Clock %pCn running at %lu Hz is outside of the recommended range: 1.92 to 5MHz\n",
|
||||
data->clk, rate);
|
||||
|
||||
/* register of thermal sensor and get info from DT */
|
||||
tz = thermal_zone_of_sensor_register(&pdev->dev, 0, data,
|
||||
|
|
|
@ -2724,8 +2724,8 @@ found:
|
|||
dev_dbg(dev, "failed to get %s (%ld)\n", clk_names[i],
|
||||
PTR_ERR(clk));
|
||||
else
|
||||
dev_dbg(dev, "clk %s is %pC rate %pCr\n", clk_names[i],
|
||||
clk, clk);
|
||||
dev_dbg(dev, "clk %s is %pC rate %lu\n", clk_names[i],
|
||||
clk, clk_get_rate(clk));
|
||||
sci_port->clks[i] = IS_ERR(clk) ? NULL : clk;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -1908,6 +1908,7 @@ asmlinkage int vprintk_emit(int facility, int level,
|
|||
preempt_enable();
|
||||
}
|
||||
|
||||
wake_up_klogd();
|
||||
return printed_len;
|
||||
}
|
||||
EXPORT_SYMBOL(vprintk_emit);
|
||||
|
@ -2289,9 +2290,7 @@ void console_unlock(void)
|
|||
{
|
||||
static char ext_text[CONSOLE_EXT_LOG_MAX];
|
||||
static char text[LOG_LINE_MAX + PREFIX_MAX];
|
||||
static u64 seen_seq;
|
||||
unsigned long flags;
|
||||
bool wake_klogd = false;
|
||||
bool do_cond_resched, retry;
|
||||
|
||||
if (console_suspended) {
|
||||
|
@ -2335,11 +2334,6 @@ again:
|
|||
|
||||
printk_safe_enter_irqsave(flags);
|
||||
raw_spin_lock(&logbuf_lock);
|
||||
if (seen_seq != log_next_seq) {
|
||||
wake_klogd = true;
|
||||
seen_seq = log_next_seq;
|
||||
}
|
||||
|
||||
if (console_seq < log_first_seq) {
|
||||
len = sprintf(text, "** %u printk messages dropped **\n",
|
||||
(unsigned)(log_first_seq - console_seq));
|
||||
|
@ -2397,7 +2391,7 @@ skip:
|
|||
|
||||
if (console_lock_spinning_disable_and_check()) {
|
||||
printk_safe_exit_irqrestore(flags);
|
||||
goto out;
|
||||
return;
|
||||
}
|
||||
|
||||
printk_safe_exit_irqrestore(flags);
|
||||
|
@ -2429,10 +2423,6 @@ skip:
|
|||
|
||||
if (retry && console_trylock())
|
||||
goto again;
|
||||
|
||||
out:
|
||||
if (wake_klogd)
|
||||
wake_up_klogd();
|
||||
}
|
||||
EXPORT_SYMBOL(console_unlock);
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@ static __printf(2, 0) int printk_safe_log_store(struct printk_safe_seq_buf *s,
|
|||
{
|
||||
int add;
|
||||
size_t len;
|
||||
va_list ap;
|
||||
|
||||
again:
|
||||
len = atomic_read(&s->len);
|
||||
|
@ -100,7 +101,9 @@ again:
|
|||
if (!len)
|
||||
smp_rmb();
|
||||
|
||||
add = vscnprintf(s->buffer + len, sizeof(s->buffer) - len, fmt, args);
|
||||
va_copy(ap, args);
|
||||
add = vscnprintf(s->buffer + len, sizeof(s->buffer) - len, fmt, ap);
|
||||
va_end(ap);
|
||||
if (!add)
|
||||
return 0;
|
||||
|
||||
|
@ -278,7 +281,7 @@ void printk_safe_flush_on_panic(void)
|
|||
* Make sure that we could access the main ring buffer.
|
||||
* Do not risk a double release when more CPUs are up.
|
||||
*/
|
||||
if (in_nmi() && raw_spin_is_locked(&logbuf_lock)) {
|
||||
if (raw_spin_is_locked(&logbuf_lock)) {
|
||||
if (num_online_cpus() > 1)
|
||||
return;
|
||||
|
||||
|
|
|
@ -204,7 +204,7 @@ test_string(void)
|
|||
#if BITS_PER_LONG == 64
|
||||
|
||||
#define PTR_WIDTH 16
|
||||
#define PTR ((void *)0xffff0123456789ab)
|
||||
#define PTR ((void *)0xffff0123456789abUL)
|
||||
#define PTR_STR "ffff0123456789ab"
|
||||
#define ZEROS "00000000" /* hex 32 zero bits */
|
||||
|
||||
|
|
133
lib/vsprintf.c
133
lib/vsprintf.c
|
@ -703,6 +703,22 @@ char *symbol_string(char *buf, char *end, void *ptr,
|
|||
#endif
|
||||
}
|
||||
|
||||
static const struct printf_spec default_str_spec = {
|
||||
.field_width = -1,
|
||||
.precision = -1,
|
||||
};
|
||||
|
||||
static const struct printf_spec default_flag_spec = {
|
||||
.base = 16,
|
||||
.precision = -1,
|
||||
.flags = SPECIAL | SMALL,
|
||||
};
|
||||
|
||||
static const struct printf_spec default_dec_spec = {
|
||||
.base = 10,
|
||||
.precision = -1,
|
||||
};
|
||||
|
||||
static noinline_for_stack
|
||||
char *resource_string(char *buf, char *end, struct resource *res,
|
||||
struct printf_spec spec, const char *fmt)
|
||||
|
@ -732,21 +748,11 @@ char *resource_string(char *buf, char *end, struct resource *res,
|
|||
.precision = -1,
|
||||
.flags = SMALL | ZEROPAD,
|
||||
};
|
||||
static const struct printf_spec dec_spec = {
|
||||
.base = 10,
|
||||
.precision = -1,
|
||||
.flags = 0,
|
||||
};
|
||||
static const struct printf_spec str_spec = {
|
||||
.field_width = -1,
|
||||
.precision = 10,
|
||||
.flags = LEFT,
|
||||
};
|
||||
static const struct printf_spec flag_spec = {
|
||||
.base = 16,
|
||||
.precision = -1,
|
||||
.flags = SPECIAL | SMALL,
|
||||
};
|
||||
|
||||
/* 32-bit res (sizeof==4): 10 chars in dec, 10 in hex ("0x" + 8)
|
||||
* 64-bit res (sizeof==8): 20 chars in dec, 18 in hex ("0x" + 16) */
|
||||
|
@ -770,10 +776,10 @@ char *resource_string(char *buf, char *end, struct resource *res,
|
|||
specp = &mem_spec;
|
||||
} else if (res->flags & IORESOURCE_IRQ) {
|
||||
p = string(p, pend, "irq ", str_spec);
|
||||
specp = &dec_spec;
|
||||
specp = &default_dec_spec;
|
||||
} else if (res->flags & IORESOURCE_DMA) {
|
||||
p = string(p, pend, "dma ", str_spec);
|
||||
specp = &dec_spec;
|
||||
specp = &default_dec_spec;
|
||||
} else if (res->flags & IORESOURCE_BUS) {
|
||||
p = string(p, pend, "bus ", str_spec);
|
||||
specp = &bus_spec;
|
||||
|
@ -803,7 +809,7 @@ char *resource_string(char *buf, char *end, struct resource *res,
|
|||
p = string(p, pend, " disabled", str_spec);
|
||||
} else {
|
||||
p = string(p, pend, " flags ", str_spec);
|
||||
p = number(p, pend, res->flags, flag_spec);
|
||||
p = number(p, pend, res->flags, default_flag_spec);
|
||||
}
|
||||
*p++ = ']';
|
||||
*p = '\0';
|
||||
|
@ -913,9 +919,6 @@ char *bitmap_list_string(char *buf, char *end, unsigned long *bitmap,
|
|||
int cur, rbot, rtop;
|
||||
bool first = true;
|
||||
|
||||
/* reused to print numbers */
|
||||
spec = (struct printf_spec){ .base = 10 };
|
||||
|
||||
rbot = cur = find_first_bit(bitmap, nr_bits);
|
||||
while (cur < nr_bits) {
|
||||
rtop = cur;
|
||||
|
@ -930,13 +933,13 @@ char *bitmap_list_string(char *buf, char *end, unsigned long *bitmap,
|
|||
}
|
||||
first = false;
|
||||
|
||||
buf = number(buf, end, rbot, spec);
|
||||
buf = number(buf, end, rbot, default_dec_spec);
|
||||
if (rbot < rtop) {
|
||||
if (buf < end)
|
||||
*buf = '-';
|
||||
buf++;
|
||||
|
||||
buf = number(buf, end, rtop, spec);
|
||||
buf = number(buf, end, rtop, default_dec_spec);
|
||||
}
|
||||
|
||||
rbot = cur;
|
||||
|
@ -1354,11 +1357,9 @@ char *uuid_string(char *buf, char *end, const u8 *addr,
|
|||
return string(buf, end, uuid, spec);
|
||||
}
|
||||
|
||||
int kptr_restrict __read_mostly;
|
||||
|
||||
static noinline_for_stack
|
||||
char *restricted_pointer(char *buf, char *end, const void *ptr,
|
||||
struct printf_spec spec)
|
||||
char *pointer_string(char *buf, char *end, const void *ptr,
|
||||
struct printf_spec spec)
|
||||
{
|
||||
spec.base = 16;
|
||||
spec.flags |= SMALL;
|
||||
|
@ -1367,6 +1368,15 @@ char *restricted_pointer(char *buf, char *end, const void *ptr,
|
|||
spec.flags |= ZEROPAD;
|
||||
}
|
||||
|
||||
return number(buf, end, (unsigned long int)ptr, spec);
|
||||
}
|
||||
|
||||
int kptr_restrict __read_mostly;
|
||||
|
||||
static noinline_for_stack
|
||||
char *restricted_pointer(char *buf, char *end, const void *ptr,
|
||||
struct printf_spec spec)
|
||||
{
|
||||
switch (kptr_restrict) {
|
||||
case 0:
|
||||
/* Always print %pK values */
|
||||
|
@ -1378,8 +1388,11 @@ char *restricted_pointer(char *buf, char *end, const void *ptr,
|
|||
* kptr_restrict==1 cannot be used in IRQ context
|
||||
* because its test for CAP_SYSLOG would be meaningless.
|
||||
*/
|
||||
if (in_irq() || in_serving_softirq() || in_nmi())
|
||||
if (in_irq() || in_serving_softirq() || in_nmi()) {
|
||||
if (spec.field_width == -1)
|
||||
spec.field_width = 2 * sizeof(ptr);
|
||||
return string(buf, end, "pK-error", spec);
|
||||
}
|
||||
|
||||
/*
|
||||
* Only print the real pointer value if the current
|
||||
|
@ -1404,7 +1417,7 @@ char *restricted_pointer(char *buf, char *end, const void *ptr,
|
|||
break;
|
||||
}
|
||||
|
||||
return number(buf, end, (unsigned long)ptr, spec);
|
||||
return pointer_string(buf, end, ptr, spec);
|
||||
}
|
||||
|
||||
static noinline_for_stack
|
||||
|
@ -1456,9 +1469,6 @@ char *clock(char *buf, char *end, struct clk *clk, struct printf_spec spec,
|
|||
return string(buf, end, NULL, spec);
|
||||
|
||||
switch (fmt[1]) {
|
||||
case 'r':
|
||||
return number(buf, end, clk_get_rate(clk), spec);
|
||||
|
||||
case 'n':
|
||||
default:
|
||||
#ifdef CONFIG_COMMON_CLK
|
||||
|
@ -1474,23 +1484,13 @@ char *format_flags(char *buf, char *end, unsigned long flags,
|
|||
const struct trace_print_flags *names)
|
||||
{
|
||||
unsigned long mask;
|
||||
const struct printf_spec strspec = {
|
||||
.field_width = -1,
|
||||
.precision = -1,
|
||||
};
|
||||
const struct printf_spec numspec = {
|
||||
.flags = SPECIAL|SMALL,
|
||||
.field_width = -1,
|
||||
.precision = -1,
|
||||
.base = 16,
|
||||
};
|
||||
|
||||
for ( ; flags && names->name; names++) {
|
||||
mask = names->mask;
|
||||
if ((flags & mask) != mask)
|
||||
continue;
|
||||
|
||||
buf = string(buf, end, names->name, strspec);
|
||||
buf = string(buf, end, names->name, default_str_spec);
|
||||
|
||||
flags &= ~mask;
|
||||
if (flags) {
|
||||
|
@ -1501,7 +1501,7 @@ char *format_flags(char *buf, char *end, unsigned long flags,
|
|||
}
|
||||
|
||||
if (flags)
|
||||
buf = number(buf, end, flags, numspec);
|
||||
buf = number(buf, end, flags, default_flag_spec);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
@ -1548,22 +1548,18 @@ char *device_node_gen_full_name(const struct device_node *np, char *buf, char *e
|
|||
{
|
||||
int depth;
|
||||
const struct device_node *parent = np->parent;
|
||||
static const struct printf_spec strspec = {
|
||||
.field_width = -1,
|
||||
.precision = -1,
|
||||
};
|
||||
|
||||
/* special case for root node */
|
||||
if (!parent)
|
||||
return string(buf, end, "/", strspec);
|
||||
return string(buf, end, "/", default_str_spec);
|
||||
|
||||
for (depth = 0; parent->parent; depth++)
|
||||
parent = parent->parent;
|
||||
|
||||
for ( ; depth >= 0; depth--) {
|
||||
buf = string(buf, end, "/", strspec);
|
||||
buf = string(buf, end, "/", default_str_spec);
|
||||
buf = string(buf, end, device_node_name_for_depth(np, depth),
|
||||
strspec);
|
||||
default_str_spec);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
@ -1655,20 +1651,6 @@ char *device_node_string(char *buf, char *end, struct device_node *dn,
|
|||
return widen_string(buf, buf - buf_start, end, spec);
|
||||
}
|
||||
|
||||
static noinline_for_stack
|
||||
char *pointer_string(char *buf, char *end, const void *ptr,
|
||||
struct printf_spec spec)
|
||||
{
|
||||
spec.base = 16;
|
||||
spec.flags |= SMALL;
|
||||
if (spec.field_width == -1) {
|
||||
spec.field_width = 2 * sizeof(ptr);
|
||||
spec.flags |= ZEROPAD;
|
||||
}
|
||||
|
||||
return number(buf, end, (unsigned long int)ptr, spec);
|
||||
}
|
||||
|
||||
static DEFINE_STATIC_KEY_TRUE(not_filled_random_ptr_key);
|
||||
static siphash_key_t ptr_key __read_mostly;
|
||||
|
||||
|
@ -1710,13 +1692,13 @@ early_initcall(initialize_ptr_random);
|
|||
/* Maps a pointer to a 32 bit unique identifier. */
|
||||
static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec)
|
||||
{
|
||||
const char *str = sizeof(ptr) == 8 ? "(____ptrval____)" : "(ptrval)";
|
||||
unsigned long hashval;
|
||||
const int default_width = 2 * sizeof(ptr);
|
||||
|
||||
if (static_branch_unlikely(¬_filled_random_ptr_key)) {
|
||||
spec.field_width = default_width;
|
||||
spec.field_width = 2 * sizeof(ptr);
|
||||
/* string length must be less than default_width */
|
||||
return string(buf, end, "(ptrval)", spec);
|
||||
return string(buf, end, str, spec);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
|
@ -1729,15 +1711,7 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec)
|
|||
#else
|
||||
hashval = (unsigned long)siphash_1u32((u32)ptr, &ptr_key);
|
||||
#endif
|
||||
|
||||
spec.flags |= SMALL;
|
||||
if (spec.field_width == -1) {
|
||||
spec.field_width = default_width;
|
||||
spec.flags |= ZEROPAD;
|
||||
}
|
||||
spec.base = 16;
|
||||
|
||||
return number(buf, end, hashval, spec);
|
||||
return pointer_string(buf, end, (const void *)hashval, spec);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1750,10 +1724,10 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec)
|
|||
*
|
||||
* Right now we handle:
|
||||
*
|
||||
* - 'F' For symbolic function descriptor pointers with offset
|
||||
* - 'f' For simple symbolic function names without offset
|
||||
* - 'S' For symbolic direct pointers with offset
|
||||
* - 's' For symbolic direct pointers without offset
|
||||
* - 'S' For symbolic direct pointers (or function descriptors) with offset
|
||||
* - 's' For symbolic direct pointers (or function descriptors) without offset
|
||||
* - 'F' Same as 'S'
|
||||
* - 'f' Same as 's'
|
||||
* - '[FfSs]R' as above with __builtin_extract_return_addr() translation
|
||||
* - 'B' For backtraced symbolic direct pointers with offset
|
||||
* - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref]
|
||||
|
@ -1850,10 +1824,6 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec)
|
|||
* ** When making changes please also update:
|
||||
* Documentation/core-api/printk-formats.rst
|
||||
*
|
||||
* Note: The difference between 'S' and 'F' is that on ia64 and ppc64
|
||||
* function pointers are really function descriptors, which contain a
|
||||
* pointer to the real address.
|
||||
*
|
||||
* Note: The default behaviour (unadorned %p) is to hash the address,
|
||||
* rendering it useful as a unique identifier.
|
||||
*/
|
||||
|
@ -2129,6 +2099,7 @@ qualifier:
|
|||
|
||||
case 'x':
|
||||
spec->flags |= SMALL;
|
||||
/* fall through */
|
||||
|
||||
case 'X':
|
||||
spec->base = 16;
|
||||
|
@ -3087,8 +3058,10 @@ int vsscanf(const char *buf, const char *fmt, va_list args)
|
|||
break;
|
||||
case 'i':
|
||||
base = 0;
|
||||
/* fall through */
|
||||
case 'd':
|
||||
is_sign = true;
|
||||
/* fall through */
|
||||
case 'u':
|
||||
break;
|
||||
case '%':
|
||||
|
|
Loading…
Reference in a new issue