Skip to content

Commit c8dbea6

Browse files
committed
Merge branch 'printk-rework' into for-linus
2 parents da34b03 + acebb55 commit c8dbea6

File tree

11 files changed

+316
-309
lines changed

11 files changed

+316
-309
lines changed

arch/powerpc/kernel/nvram_64.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,7 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
647647
{
648648
struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf;
649649
static unsigned int oops_count = 0;
650+
static struct kmsg_dump_iter iter;
650651
static bool panicking = false;
651652
static DEFINE_SPINLOCK(lock);
652653
unsigned long flags;
@@ -681,13 +682,14 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
681682
return;
682683

683684
if (big_oops_buf) {
684-
kmsg_dump_get_buffer(dumper, false,
685+
kmsg_dump_rewind(&iter);
686+
kmsg_dump_get_buffer(&iter, false,
685687
big_oops_buf, big_oops_buf_sz, &text_len);
686688
rc = zip_oops(text_len);
687689
}
688690
if (rc != 0) {
689-
kmsg_dump_rewind(dumper);
690-
kmsg_dump_get_buffer(dumper, false,
691+
kmsg_dump_rewind(&iter);
692+
kmsg_dump_get_buffer(&iter, false,
691693
oops_data, oops_data_sz, &text_len);
692694
err_type = ERR_TYPE_KERNEL_PANIC;
693695
oops_hdr->version = cpu_to_be16(OOPS_HDR_VERSION);

arch/powerpc/xmon/xmon.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3005,7 +3005,7 @@ print_address(unsigned long addr)
30053005
static void
30063006
dump_log_buf(void)
30073007
{
3008-
struct kmsg_dumper dumper = { .active = 1 };
3008+
struct kmsg_dump_iter iter;
30093009
unsigned char buf[128];
30103010
size_t len;
30113011

@@ -3017,9 +3017,9 @@ dump_log_buf(void)
30173017
catch_memory_errors = 1;
30183018
sync();
30193019

3020-
kmsg_dump_rewind_nolock(&dumper);
3020+
kmsg_dump_rewind(&iter);
30213021
xmon_start_pagination();
3022-
while (kmsg_dump_get_line_nolock(&dumper, false, buf, sizeof(buf), &len)) {
3022+
while (kmsg_dump_get_line(&iter, false, buf, sizeof(buf), &len)) {
30233023
buf[len] = '\0';
30243024
printf("%s", buf);
30253025
}

arch/um/kernel/kmsg_dump.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// SPDX-License-Identifier: GPL-2.0
22
#include <linux/kmsg_dump.h>
3+
#include <linux/spinlock.h>
34
#include <linux/console.h>
45
#include <linux/string.h>
56
#include <shared/init.h>
@@ -9,8 +10,11 @@
910
static void kmsg_dumper_stdout(struct kmsg_dumper *dumper,
1011
enum kmsg_dump_reason reason)
1112
{
13+
static struct kmsg_dump_iter iter;
14+
static DEFINE_SPINLOCK(lock);
1215
static char line[1024];
1316
struct console *con;
17+
unsigned long flags;
1418
size_t len = 0;
1519

1620
/* only dump kmsg when no console is available */
@@ -29,11 +33,18 @@ static void kmsg_dumper_stdout(struct kmsg_dumper *dumper,
2933
if (con)
3034
return;
3135

36+
if (!spin_trylock_irqsave(&lock, flags))
37+
return;
38+
39+
kmsg_dump_rewind(&iter);
40+
3241
printf("kmsg_dump:\n");
33-
while (kmsg_dump_get_line(dumper, true, line, sizeof(line), &len)) {
42+
while (kmsg_dump_get_line(&iter, true, line, sizeof(line), &len)) {
3443
line[len] = '\0';
3544
printf("%s", line);
3645
}
46+
47+
spin_unlock_irqrestore(&lock, flags);
3748
}
3849

3950
static struct kmsg_dumper kmsg_dumper = {

drivers/hv/vmbus_drv.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1391,6 +1391,7 @@ static void vmbus_isr(void)
13911391
static void hv_kmsg_dump(struct kmsg_dumper *dumper,
13921392
enum kmsg_dump_reason reason)
13931393
{
1394+
struct kmsg_dump_iter iter;
13941395
size_t bytes_written;
13951396
phys_addr_t panic_pa;
13961397

@@ -1404,7 +1405,8 @@ static void hv_kmsg_dump(struct kmsg_dumper *dumper,
14041405
* Write dump contents to the page. No need to synchronize; panic should
14051406
* be single-threaded.
14061407
*/
1407-
kmsg_dump_get_buffer(dumper, false, hv_panic_page, HV_HYP_PAGE_SIZE,
1408+
kmsg_dump_rewind(&iter);
1409+
kmsg_dump_get_buffer(&iter, false, hv_panic_page, HV_HYP_PAGE_SIZE,
14081410
&bytes_written);
14091411
if (bytes_written)
14101412
hyperv_report_panic_msg(panic_pa, bytes_written);

drivers/mtd/mtdoops.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ static struct mtdoops_context {
5252
int nextcount;
5353
unsigned long *oops_page_used;
5454

55+
unsigned long oops_buf_busy;
5556
void *oops_buf;
5657
} oops_cxt;
5758

@@ -180,6 +181,9 @@ static void mtdoops_write(struct mtdoops_context *cxt, int panic)
180181
u32 *hdr;
181182
int ret;
182183

184+
if (test_and_set_bit(0, &cxt->oops_buf_busy))
185+
return;
186+
183187
/* Add mtdoops header to the buffer */
184188
hdr = cxt->oops_buf;
185189
hdr[0] = cxt->nextcount;
@@ -190,7 +194,7 @@ static void mtdoops_write(struct mtdoops_context *cxt, int panic)
190194
record_size, &retlen, cxt->oops_buf);
191195
if (ret == -EOPNOTSUPP) {
192196
printk(KERN_ERR "mtdoops: Cannot write from panic without panic_write\n");
193-
return;
197+
goto out;
194198
}
195199
} else
196200
ret = mtd_write(mtd, cxt->nextpage * record_size,
@@ -203,6 +207,8 @@ static void mtdoops_write(struct mtdoops_context *cxt, int panic)
203207
memset(cxt->oops_buf, 0xff, record_size);
204208

205209
mtdoops_inc_counter(cxt);
210+
out:
211+
clear_bit(0, &cxt->oops_buf_busy);
206212
}
207213

208214
static void mtdoops_workfunc_write(struct work_struct *work)
@@ -271,13 +277,19 @@ static void mtdoops_do_dump(struct kmsg_dumper *dumper,
271277
{
272278
struct mtdoops_context *cxt = container_of(dumper,
273279
struct mtdoops_context, dump);
280+
struct kmsg_dump_iter iter;
274281

275282
/* Only dump oopses if dump_oops is set */
276283
if (reason == KMSG_DUMP_OOPS && !dump_oops)
277284
return;
278285

279-
kmsg_dump_get_buffer(dumper, true, cxt->oops_buf + MTDOOPS_HEADER_SIZE,
286+
kmsg_dump_rewind(&iter);
287+
288+
if (test_and_set_bit(0, &cxt->oops_buf_busy))
289+
return;
290+
kmsg_dump_get_buffer(&iter, true, cxt->oops_buf + MTDOOPS_HEADER_SIZE,
280291
record_size - MTDOOPS_HEADER_SIZE, NULL);
292+
clear_bit(0, &cxt->oops_buf_busy);
281293

282294
if (reason != KMSG_DUMP_OOPS) {
283295
/* Panics must be written immediately */
@@ -394,6 +406,7 @@ static int __init mtdoops_init(void)
394406
return -ENOMEM;
395407
}
396408
memset(cxt->oops_buf, 0xff, record_size);
409+
cxt->oops_buf_busy = 0;
397410

398411
INIT_WORK(&cxt->work_erase, mtdoops_workfunc_erase);
399412
INIT_WORK(&cxt->work_write, mtdoops_workfunc_write);

fs/pstore/platform.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ void pstore_record_init(struct pstore_record *record,
385385
static void pstore_dump(struct kmsg_dumper *dumper,
386386
enum kmsg_dump_reason reason)
387387
{
388+
struct kmsg_dump_iter iter;
388389
unsigned long total = 0;
389390
const char *why;
390391
unsigned int part = 1;
@@ -405,6 +406,8 @@ static void pstore_dump(struct kmsg_dumper *dumper,
405406
}
406407
}
407408

409+
kmsg_dump_rewind(&iter);
410+
408411
oopscount++;
409412
while (total < kmsg_bytes) {
410413
char *dst;
@@ -435,7 +438,7 @@ static void pstore_dump(struct kmsg_dumper *dumper,
435438
dst_size -= header_size;
436439

437440
/* Write dump contents. */
438-
if (!kmsg_dump_get_buffer(dumper, true, dst + header_size,
441+
if (!kmsg_dump_get_buffer(&iter, true, dst + header_size,
439442
dst_size, &dump_size))
440443
break;
441444

include/linux/kmsg_dump.h

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ enum kmsg_dump_reason {
2929
KMSG_DUMP_MAX
3030
};
3131

32+
/**
33+
* struct kmsg_dump_iter - iterator for retrieving kernel messages
34+
* @cur_seq: Points to the oldest message to dump
35+
* @next_seq: Points after the newest message to dump
36+
*/
37+
struct kmsg_dump_iter {
38+
u64 cur_seq;
39+
u64 next_seq;
40+
};
41+
3242
/**
3343
* struct kmsg_dumper - kernel crash message dumper structure
3444
* @list: Entry in the dumper list (private)
@@ -41,31 +51,19 @@ struct kmsg_dumper {
4151
struct list_head list;
4252
void (*dump)(struct kmsg_dumper *dumper, enum kmsg_dump_reason reason);
4353
enum kmsg_dump_reason max_reason;
44-
bool active;
4554
bool registered;
46-
47-
/* private state of the kmsg iterator */
48-
u32 cur_idx;
49-
u32 next_idx;
50-
u64 cur_seq;
51-
u64 next_seq;
5255
};
5356

5457
#ifdef CONFIG_PRINTK
5558
void kmsg_dump(enum kmsg_dump_reason reason);
5659

57-
bool kmsg_dump_get_line_nolock(struct kmsg_dumper *dumper, bool syslog,
58-
char *line, size_t size, size_t *len);
59-
60-
bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog,
60+
bool kmsg_dump_get_line(struct kmsg_dump_iter *iter, bool syslog,
6161
char *line, size_t size, size_t *len);
6262

63-
bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
64-
char *buf, size_t size, size_t *len);
65-
66-
void kmsg_dump_rewind_nolock(struct kmsg_dumper *dumper);
63+
bool kmsg_dump_get_buffer(struct kmsg_dump_iter *iter, bool syslog,
64+
char *buf, size_t size, size_t *len_out);
6765

68-
void kmsg_dump_rewind(struct kmsg_dumper *dumper);
66+
void kmsg_dump_rewind(struct kmsg_dump_iter *iter);
6967

7068
int kmsg_dump_register(struct kmsg_dumper *dumper);
7169

@@ -77,30 +75,19 @@ static inline void kmsg_dump(enum kmsg_dump_reason reason)
7775
{
7876
}
7977

80-
static inline bool kmsg_dump_get_line_nolock(struct kmsg_dumper *dumper,
81-
bool syslog, const char *line,
82-
size_t size, size_t *len)
83-
{
84-
return false;
85-
}
86-
87-
static inline bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog,
78+
static inline bool kmsg_dump_get_line(struct kmsg_dump_iter *iter, bool syslog,
8879
const char *line, size_t size, size_t *len)
8980
{
9081
return false;
9182
}
9283

93-
static inline bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
84+
static inline bool kmsg_dump_get_buffer(struct kmsg_dump_iter *iter, bool syslog,
9485
char *buf, size_t size, size_t *len)
9586
{
9687
return false;
9788
}
9889

99-
static inline void kmsg_dump_rewind_nolock(struct kmsg_dumper *dumper)
100-
{
101-
}
102-
103-
static inline void kmsg_dump_rewind(struct kmsg_dumper *dumper)
90+
static inline void kmsg_dump_rewind(struct kmsg_dump_iter *iter)
10491
{
10592
}
10693

kernel/debug/kdb/kdb_main.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2101,7 +2101,7 @@ static int kdb_dmesg(int argc, const char **argv)
21012101
int adjust = 0;
21022102
int n = 0;
21032103
int skip = 0;
2104-
struct kmsg_dumper dumper = { .active = 1 };
2104+
struct kmsg_dump_iter iter;
21052105
size_t len;
21062106
char buf[201];
21072107

@@ -2126,8 +2126,8 @@ static int kdb_dmesg(int argc, const char **argv)
21262126
kdb_set(2, setargs);
21272127
}
21282128

2129-
kmsg_dump_rewind_nolock(&dumper);
2130-
while (kmsg_dump_get_line_nolock(&dumper, 1, NULL, 0, NULL))
2129+
kmsg_dump_rewind(&iter);
2130+
while (kmsg_dump_get_line(&iter, 1, NULL, 0, NULL))
21312131
n++;
21322132

21332133
if (lines < 0) {
@@ -2159,8 +2159,8 @@ static int kdb_dmesg(int argc, const char **argv)
21592159
if (skip >= n || skip < 0)
21602160
return 0;
21612161

2162-
kmsg_dump_rewind_nolock(&dumper);
2163-
while (kmsg_dump_get_line_nolock(&dumper, 1, buf, sizeof(buf), &len)) {
2162+
kmsg_dump_rewind(&iter);
2163+
while (kmsg_dump_get_line(&iter, 1, buf, sizeof(buf), &len)) {
21642164
if (skip) {
21652165
skip--;
21662166
continue;

kernel/printk/internal.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,13 @@
1212

1313
#define PRINTK_NMI_CONTEXT_OFFSET 0x010000000
1414

15-
extern raw_spinlock_t logbuf_lock;
16-
1715
__printf(4, 0)
1816
int vprintk_store(int facility, int level,
1917
const struct dev_printk_info *dev_info,
2018
const char *fmt, va_list args);
2119

2220
__printf(1, 0) int vprintk_default(const char *fmt, va_list args);
2321
__printf(1, 0) int vprintk_deferred(const char *fmt, va_list args);
24-
__printf(1, 0) int vprintk_func(const char *fmt, va_list args);
2522
void __printk_safe_enter(void);
2623
void __printk_safe_exit(void);
2724

@@ -56,10 +53,8 @@ void defer_console_output(void);
5653

5754
#else
5855

59-
__printf(1, 0) int vprintk_func(const char *fmt, va_list args) { return 0; }
60-
6156
/*
62-
* In !PRINTK builds we still export logbuf_lock spin_lock, console_sem
57+
* In !PRINTK builds we still export console_sem
6358
* semaphore and some of console functions (console_unlock()/etc.), so
6459
* printk-safe must preserve the existing local IRQ guarantees.
6560
*/

0 commit comments

Comments
 (0)