Skip to content

Commit f9f3f02

Browse files
jognesspmladek
authored andcommitted
printk: introduce a kmsg_dump iterator
Rather than storing the iterator information in the registered kmsg_dumper structure, create a separate iterator structure. The kmsg_dump_iter structure can reside on the stack of the caller, thus allowing lockless use of the kmsg_dump functions. Update code that accesses the kernel logs using the kmsg_dumper structure to use the new kmsg_dump_iter structure. For kmsg_dumpers, this also means adding a call to kmsg_dump_rewind() to initialize the iterator. All this is in preparation for removal of @logbuf_lock. Signed-off-by: John Ogness <[email protected]> Reviewed-by: Kees Cook <[email protected]> # pstore Reviewed-by: Petr Mladek <[email protected]> Signed-off-by: Petr Mladek <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 5f6c764 commit f9f3f02

File tree

9 files changed

+80
-62
lines changed

9 files changed

+80
-62
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;
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_nolock(&iter);
30213021
xmon_start_pagination();
3022-
while (kmsg_dump_get_line_nolock(&dumper, false, buf, sizeof(buf), &len)) {
3022+
while (kmsg_dump_get_line_nolock(&iter, false, buf, sizeof(buf), &len)) {
30233023
buf[len] = '\0';
30243024
printf("%s", buf);
30253025
}

arch/um/kernel/kmsg_dump.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
static void kmsg_dumper_stdout(struct kmsg_dumper *dumper,
1111
enum kmsg_dump_reason reason)
1212
{
13+
static struct kmsg_dump_iter iter;
1314
static DEFINE_SPINLOCK(lock);
1415
static char line[1024];
1516
struct console *con;
@@ -35,8 +36,10 @@ static void kmsg_dumper_stdout(struct kmsg_dumper *dumper,
3536
if (!spin_trylock_irqsave(&lock, flags))
3637
return;
3738

39+
kmsg_dump_rewind(&iter);
40+
3841
printf("kmsg_dump:\n");
39-
while (kmsg_dump_get_line(dumper, true, line, sizeof(line), &len)) {
42+
while (kmsg_dump_get_line(&iter, true, line, sizeof(line), &len)) {
4043
line[len] = '\0';
4144
printf("%s", line);
4245
}

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: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,14 +277,17 @@ static void mtdoops_do_dump(struct kmsg_dumper *dumper,
277277
{
278278
struct mtdoops_context *cxt = container_of(dumper,
279279
struct mtdoops_context, dump);
280+
struct kmsg_dump_iter iter;
280281

281282
/* Only dump oopses if dump_oops is set */
282283
if (reason == KMSG_DUMP_OOPS && !dump_oops)
283284
return;
284285

286+
kmsg_dump_rewind(&iter);
287+
285288
if (test_and_set_bit(0, &cxt->oops_buf_busy))
286289
return;
287-
kmsg_dump_get_buffer(dumper, true, cxt->oops_buf + MTDOOPS_HEADER_SIZE,
290+
kmsg_dump_get_buffer(&iter, true, cxt->oops_buf + MTDOOPS_HEADER_SIZE,
288291
record_size - MTDOOPS_HEADER_SIZE, NULL);
289292
clear_bit(0, &cxt->oops_buf_busy);
290293

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: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,42 +29,46 @@ 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)
3545
* @dump: Call into dumping code which will retrieve the data with
3646
* through the record iterator
3747
* @max_reason: filter for highest reason number that should be dumped
3848
* @registered: Flag that specifies if this is already registered
39-
* @cur_seq: Points to the oldest message to dump
40-
* @next_seq: Points after the newest message to dump
4149
*/
4250
struct kmsg_dumper {
4351
struct list_head list;
4452
void (*dump)(struct kmsg_dumper *dumper, enum kmsg_dump_reason reason);
4553
enum kmsg_dump_reason max_reason;
4654
bool registered;
47-
48-
/* private state of the kmsg iterator */
49-
u64 cur_seq;
50-
u64 next_seq;
5155
};
5256

5357
#ifdef CONFIG_PRINTK
5458
void kmsg_dump(enum kmsg_dump_reason reason);
5559

56-
bool kmsg_dump_get_line_nolock(struct kmsg_dumper *dumper, bool syslog,
60+
bool kmsg_dump_get_line_nolock(struct kmsg_dump_iter *iter, bool syslog,
5761
char *line, size_t size, size_t *len);
5862

59-
bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog,
63+
bool kmsg_dump_get_line(struct kmsg_dump_iter *iter, bool syslog,
6064
char *line, size_t size, size_t *len);
6165

62-
bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
66+
bool kmsg_dump_get_buffer(struct kmsg_dump_iter *iter, bool syslog,
6367
char *buf, size_t size, size_t *len_out);
6468

65-
void kmsg_dump_rewind_nolock(struct kmsg_dumper *dumper);
69+
void kmsg_dump_rewind_nolock(struct kmsg_dump_iter *iter);
6670

67-
void kmsg_dump_rewind(struct kmsg_dumper *dumper);
71+
void kmsg_dump_rewind(struct kmsg_dump_iter *iter);
6872

6973
int kmsg_dump_register(struct kmsg_dumper *dumper);
7074

@@ -76,30 +80,30 @@ static inline void kmsg_dump(enum kmsg_dump_reason reason)
7680
{
7781
}
7882

79-
static inline bool kmsg_dump_get_line_nolock(struct kmsg_dumper *dumper,
83+
static inline bool kmsg_dump_get_line_nolock(struct kmsg_dump_iter *iter,
8084
bool syslog, const char *line,
8185
size_t size, size_t *len)
8286
{
8387
return false;
8488
}
8589

86-
static inline bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog,
90+
static inline bool kmsg_dump_get_line(struct kmsg_dump_iter *iter, bool syslog,
8791
const char *line, size_t size, size_t *len)
8892
{
8993
return false;
9094
}
9195

92-
static inline bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
96+
static inline bool kmsg_dump_get_buffer(struct kmsg_dump_iter *iter, bool syslog,
9397
char *buf, size_t size, size_t *len)
9498
{
9599
return false;
96100
}
97101

98-
static inline void kmsg_dump_rewind_nolock(struct kmsg_dumper *dumper)
102+
static inline void kmsg_dump_rewind_nolock(struct kmsg_dump_iter *iter)
99103
{
100104
}
101105

102-
static inline void kmsg_dump_rewind(struct kmsg_dumper *dumper)
106+
static inline void kmsg_dump_rewind(struct kmsg_dump_iter *iter)
103107
{
104108
}
105109

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;
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_nolock(&iter);
2130+
while (kmsg_dump_get_line_nolock(&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_nolock(&iter);
2163+
while (kmsg_dump_get_line_nolock(&iter, 1, buf, sizeof(buf), &len)) {
21642164
if (skip) {
21652165
skip--;
21662166
continue;

0 commit comments

Comments
 (0)