Skip to content

Commit e563592

Browse files
committed
Merge tag 'printk-for-5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux
Pull printk updates from Petr Mladek: - Add %pt[RT]s modifier to vsprintf(). It overrides ISO 8601 separator by using ' ' (space). It produces "YYYY-mm-dd HH:MM:SS" instead of "YYYY-mm-ddTHH:MM:SS". - Correctly parse long row of numbers by sscanf() when using the field width. Add extensive sscanf() selftest. - Generalize re-entrant CPU lock that has already been used to serialize dump_stack() output. It is part of the ongoing printk rework. It will allow to remove the obsoleted printk_safe buffers and introduce atomic consoles. - Some code clean up and sparse warning fixes. * tag 'printk-for-5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux: printk: fix cpu lock ordering lib/dump_stack: move cpu lock to printk.c printk: Remove trailing semicolon in macros random32: Fix implicit truncation warning in prandom_seed_state() lib: test_scanf: Remove pointless use of type_min() with unsigned types selftests: lib: Add wrapper script for test_scanf lib: test_scanf: Add tests for sscanf number conversion lib: vsprintf: Fix handling of number field widths in vsscanf lib: vsprintf: scanf: Negative number must have field width > 1 usb: host: xhci-tegra: Switch to use %ptTs nilfs2: Switch to use %ptTs kdb: Switch to use %ptTs lib/vsprintf: Allow to override ISO 8601 date and time separator
2 parents b694011 + 94f2be5 commit e563592

File tree

20 files changed

+1020
-112
lines changed

20 files changed

+1020
-112
lines changed

Documentation/core-api/printk-formats.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,9 +513,10 @@ Time and date
513513
::
514514

515515
%pt[RT] YYYY-mm-ddTHH:MM:SS
516+
%pt[RT]s YYYY-mm-dd HH:MM:SS
516517
%pt[RT]d YYYY-mm-dd
517518
%pt[RT]t HH:MM:SS
518-
%pt[RT][dt][r]
519+
%pt[RT][dt][r][s]
519520

520521
For printing date and time as represented by::
521522

@@ -527,6 +528,10 @@ in human readable format.
527528
By default year will be incremented by 1900 and month by 1.
528529
Use %pt[RT]r (raw) to suppress this behaviour.
529530

531+
The %pt[RT]s (space) will override ISO 8601 separator by using ' ' (space)
532+
instead of 'T' (Capital T) between date and time. It won't have any effect
533+
when date or time is omitted.
534+
530535
Passed by reference.
531536

532537
struct clk

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19629,6 +19629,7 @@ S: Maintained
1962919629
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pmladek/printk.git
1963019630
F: Documentation/core-api/printk-formats.rst
1963119631
F: lib/test_printf.c
19632+
F: lib/test_scanf.c
1963219633
F: lib/vsprintf.c
1963319634

1963419635
VT1211 HARDWARE MONITOR DRIVER

drivers/usb/host/xhci-tegra.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -917,7 +917,6 @@ static int tegra_xusb_load_firmware(struct tegra_xusb *tegra)
917917
struct xhci_op_regs __iomem *op;
918918
unsigned long timeout;
919919
time64_t timestamp;
920-
struct tm time;
921920
u64 address;
922921
u32 value;
923922
int err;
@@ -1014,11 +1013,8 @@ static int tegra_xusb_load_firmware(struct tegra_xusb *tegra)
10141013
}
10151014

10161015
timestamp = le32_to_cpu(header->fwimg_created_time);
1017-
time64_to_tm(timestamp, 0, &time);
10181016

1019-
dev_info(dev, "Firmware timestamp: %ld-%02d-%02d %02d:%02d:%02d UTC\n",
1020-
time.tm_year + 1900, time.tm_mon + 1, time.tm_mday,
1021-
time.tm_hour, time.tm_min, time.tm_sec);
1017+
dev_info(dev, "Firmware timestamp: %ptTs UTC\n", &timestamp);
10221018

10231019
return 0;
10241020
}

fs/nilfs2/sysfs.c

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,6 @@
1919
/* /sys/fs/<nilfs>/ */
2020
static struct kset *nilfs_kset;
2121

22-
#define NILFS_SHOW_TIME(time_t_val, buf) ({ \
23-
struct tm res; \
24-
int count = 0; \
25-
time64_to_tm(time_t_val, 0, &res); \
26-
res.tm_year += 1900; \
27-
res.tm_mon += 1; \
28-
count = scnprintf(buf, PAGE_SIZE, \
29-
"%ld-%.2d-%.2d %.2d:%.2d:%.2d\n", \
30-
res.tm_year, res.tm_mon, res.tm_mday, \
31-
res.tm_hour, res.tm_min, res.tm_sec);\
32-
count; \
33-
})
34-
3522
#define NILFS_DEV_INT_GROUP_OPS(name, parent_name) \
3623
static ssize_t nilfs_##name##_attr_show(struct kobject *kobj, \
3724
struct attribute *attr, char *buf) \
@@ -576,7 +563,7 @@ nilfs_segctor_last_seg_write_time_show(struct nilfs_segctor_attr *attr,
576563
ctime = nilfs->ns_ctime;
577564
up_read(&nilfs->ns_segctor_sem);
578565

579-
return NILFS_SHOW_TIME(ctime, buf);
566+
return sysfs_emit(buf, "%ptTs\n", &ctime);
580567
}
581568

582569
static ssize_t
@@ -604,7 +591,7 @@ nilfs_segctor_last_nongc_write_time_show(struct nilfs_segctor_attr *attr,
604591
nongc_ctime = nilfs->ns_nongc_ctime;
605592
up_read(&nilfs->ns_segctor_sem);
606593

607-
return NILFS_SHOW_TIME(nongc_ctime, buf);
594+
return sysfs_emit(buf, "%ptTs\n", &nongc_ctime);
608595
}
609596

610597
static ssize_t
@@ -724,7 +711,7 @@ nilfs_superblock_sb_write_time_show(struct nilfs_superblock_attr *attr,
724711
sbwtime = nilfs->ns_sbwtime;
725712
up_read(&nilfs->ns_sem);
726713

727-
return NILFS_SHOW_TIME(sbwtime, buf);
714+
return sysfs_emit(buf, "%ptTs\n", &sbwtime);
728715
}
729716

730717
static ssize_t

include/linux/dev_printk.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ do { \
236236
* using WARN/WARN_ONCE to include file/line information and a backtrace.
237237
*/
238238
#define dev_WARN(dev, format, arg...) \
239-
WARN(1, "%s %s: " format, dev_driver_string(dev), dev_name(dev), ## arg);
239+
WARN(1, "%s %s: " format, dev_driver_string(dev), dev_name(dev), ## arg)
240240

241241
#define dev_WARN_ONCE(dev, condition, format, arg...) \
242242
WARN_ONCE(condition, "%s %s: " format, \

include/linux/prandom.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ static inline u32 __seed(u32 x, u32 m)
111111
*/
112112
static inline void prandom_seed_state(struct rnd_state *state, u64 seed)
113113
{
114-
u32 i = (seed >> 32) ^ (seed << 10) ^ seed;
114+
u32 i = ((seed >> 32) ^ (seed << 10) ^ seed) & 0xffffffffUL;
115115

116116
state->s1 = __seed(i, 2U);
117117
state->s2 = __seed(i, 8U);

include/linux/printk.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,47 @@ static inline void printk_safe_flush_on_panic(void)
282282
}
283283
#endif
284284

285+
#ifdef CONFIG_SMP
286+
extern int __printk_cpu_trylock(void);
287+
extern void __printk_wait_on_cpu_lock(void);
288+
extern void __printk_cpu_unlock(void);
289+
290+
/**
291+
* printk_cpu_lock_irqsave() - Acquire the printk cpu-reentrant spinning
292+
* lock and disable interrupts.
293+
* @flags: Stack-allocated storage for saving local interrupt state,
294+
* to be passed to printk_cpu_unlock_irqrestore().
295+
*
296+
* If the lock is owned by another CPU, spin until it becomes available.
297+
* Interrupts are restored while spinning.
298+
*/
299+
#define printk_cpu_lock_irqsave(flags) \
300+
for (;;) { \
301+
local_irq_save(flags); \
302+
if (__printk_cpu_trylock()) \
303+
break; \
304+
local_irq_restore(flags); \
305+
__printk_wait_on_cpu_lock(); \
306+
}
307+
308+
/**
309+
* printk_cpu_unlock_irqrestore() - Release the printk cpu-reentrant spinning
310+
* lock and restore interrupts.
311+
* @flags: Caller's saved interrupt state, from printk_cpu_lock_irqsave().
312+
*/
313+
#define printk_cpu_unlock_irqrestore(flags) \
314+
do { \
315+
__printk_cpu_unlock(); \
316+
local_irq_restore(flags); \
317+
} while (0) \
318+
319+
#else
320+
321+
#define printk_cpu_lock_irqsave(flags) ((void)flags)
322+
#define printk_cpu_unlock_irqrestore(flags) ((void)flags)
323+
324+
#endif /* CONFIG_SMP */
325+
285326
extern int kptr_restrict;
286327

287328
/**

kernel/debug/kdb/kdb_main.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2488,7 +2488,6 @@ static void kdb_sysinfo(struct sysinfo *val)
24882488
static int kdb_summary(int argc, const char **argv)
24892489
{
24902490
time64_t now;
2491-
struct tm tm;
24922491
struct sysinfo val;
24932492

24942493
if (argc)
@@ -2502,13 +2501,7 @@ static int kdb_summary(int argc, const char **argv)
25022501
kdb_printf("domainname %s\n", init_uts_ns.name.domainname);
25032502

25042503
now = __ktime_get_real_seconds();
2505-
time64_to_tm(now, 0, &tm);
2506-
kdb_printf("date %04ld-%02d-%02d %02d:%02d:%02d "
2507-
"tz_minuteswest %d\n",
2508-
1900+tm.tm_year, tm.tm_mon+1, tm.tm_mday,
2509-
tm.tm_hour, tm.tm_min, tm.tm_sec,
2510-
sys_tz.tz_minuteswest);
2511-
2504+
kdb_printf("date %ptTs tz_minuteswest %d\n", &now, sys_tz.tz_minuteswest);
25122505
kdb_sysinfo(&val);
25132506
kdb_printf("uptime ");
25142507
if (val.uptime > (24*60*60)) {

kernel/printk/printk.c

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3531,3 +3531,119 @@ void kmsg_dump_rewind(struct kmsg_dump_iter *iter)
35313531
EXPORT_SYMBOL_GPL(kmsg_dump_rewind);
35323532

35333533
#endif
3534+
3535+
#ifdef CONFIG_SMP
3536+
static atomic_t printk_cpulock_owner = ATOMIC_INIT(-1);
3537+
static atomic_t printk_cpulock_nested = ATOMIC_INIT(0);
3538+
3539+
/**
3540+
* __printk_wait_on_cpu_lock() - Busy wait until the printk cpu-reentrant
3541+
* spinning lock is not owned by any CPU.
3542+
*
3543+
* Context: Any context.
3544+
*/
3545+
void __printk_wait_on_cpu_lock(void)
3546+
{
3547+
do {
3548+
cpu_relax();
3549+
} while (atomic_read(&printk_cpulock_owner) != -1);
3550+
}
3551+
EXPORT_SYMBOL(__printk_wait_on_cpu_lock);
3552+
3553+
/**
3554+
* __printk_cpu_trylock() - Try to acquire the printk cpu-reentrant
3555+
* spinning lock.
3556+
*
3557+
* If no processor has the lock, the calling processor takes the lock and
3558+
* becomes the owner. If the calling processor is already the owner of the
3559+
* lock, this function succeeds immediately.
3560+
*
3561+
* Context: Any context. Expects interrupts to be disabled.
3562+
* Return: 1 on success, otherwise 0.
3563+
*/
3564+
int __printk_cpu_trylock(void)
3565+
{
3566+
int cpu;
3567+
int old;
3568+
3569+
cpu = smp_processor_id();
3570+
3571+
/*
3572+
* Guarantee loads and stores from this CPU when it is the lock owner
3573+
* are _not_ visible to the previous lock owner. This pairs with
3574+
* __printk_cpu_unlock:B.
3575+
*
3576+
* Memory barrier involvement:
3577+
*
3578+
* If __printk_cpu_trylock:A reads from __printk_cpu_unlock:B, then
3579+
* __printk_cpu_unlock:A can never read from __printk_cpu_trylock:B.
3580+
*
3581+
* Relies on:
3582+
*
3583+
* RELEASE from __printk_cpu_unlock:A to __printk_cpu_unlock:B
3584+
* of the previous CPU
3585+
* matching
3586+
* ACQUIRE from __printk_cpu_trylock:A to __printk_cpu_trylock:B
3587+
* of this CPU
3588+
*/
3589+
old = atomic_cmpxchg_acquire(&printk_cpulock_owner, -1,
3590+
cpu); /* LMM(__printk_cpu_trylock:A) */
3591+
if (old == -1) {
3592+
/*
3593+
* This CPU is now the owner and begins loading/storing
3594+
* data: LMM(__printk_cpu_trylock:B)
3595+
*/
3596+
return 1;
3597+
3598+
} else if (old == cpu) {
3599+
/* This CPU is already the owner. */
3600+
atomic_inc(&printk_cpulock_nested);
3601+
return 1;
3602+
}
3603+
3604+
return 0;
3605+
}
3606+
EXPORT_SYMBOL(__printk_cpu_trylock);
3607+
3608+
/**
3609+
* __printk_cpu_unlock() - Release the printk cpu-reentrant spinning lock.
3610+
*
3611+
* The calling processor must be the owner of the lock.
3612+
*
3613+
* Context: Any context. Expects interrupts to be disabled.
3614+
*/
3615+
void __printk_cpu_unlock(void)
3616+
{
3617+
if (atomic_read(&printk_cpulock_nested)) {
3618+
atomic_dec(&printk_cpulock_nested);
3619+
return;
3620+
}
3621+
3622+
/*
3623+
* This CPU is finished loading/storing data:
3624+
* LMM(__printk_cpu_unlock:A)
3625+
*/
3626+
3627+
/*
3628+
* Guarantee loads and stores from this CPU when it was the
3629+
* lock owner are visible to the next lock owner. This pairs
3630+
* with __printk_cpu_trylock:A.
3631+
*
3632+
* Memory barrier involvement:
3633+
*
3634+
* If __printk_cpu_trylock:A reads from __printk_cpu_unlock:B,
3635+
* then __printk_cpu_trylock:B reads from __printk_cpu_unlock:A.
3636+
*
3637+
* Relies on:
3638+
*
3639+
* RELEASE from __printk_cpu_unlock:A to __printk_cpu_unlock:B
3640+
* of this CPU
3641+
* matching
3642+
* ACQUIRE from __printk_cpu_trylock:A to __printk_cpu_trylock:B
3643+
* of the next CPU
3644+
*/
3645+
atomic_set_release(&printk_cpulock_owner,
3646+
-1); /* LMM(__printk_cpu_unlock:B) */
3647+
}
3648+
EXPORT_SYMBOL(__printk_cpu_unlock);
3649+
#endif /* CONFIG_SMP */

lib/Kconfig.debug

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2180,6 +2180,9 @@ config TEST_KSTRTOX
21802180
config TEST_PRINTF
21812181
tristate "Test printf() family of functions at runtime"
21822182

2183+
config TEST_SCANF
2184+
tristate "Test scanf() family of functions at runtime"
2185+
21832186
config TEST_BITMAP
21842187
tristate "Test bitmap_*() family of functions at runtime"
21852188
help

0 commit comments

Comments
 (0)