Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
c8dbea6d
Commit
c8dbea6d
authored
Apr 27, 2021
by
Petr Mladek
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'printk-rework' into for-linus
parents
da34b03f
acebb559
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
316 additions
and
309 deletions
+316
-309
arch/powerpc/kernel/nvram_64.c
arch/powerpc/kernel/nvram_64.c
+5
-3
arch/powerpc/xmon/xmon.c
arch/powerpc/xmon/xmon.c
+3
-3
arch/um/kernel/kmsg_dump.c
arch/um/kernel/kmsg_dump.c
+12
-1
drivers/hv/vmbus_drv.c
drivers/hv/vmbus_drv.c
+3
-1
drivers/mtd/mtdoops.c
drivers/mtd/mtdoops.c
+15
-2
fs/pstore/platform.c
fs/pstore/platform.c
+4
-1
include/linux/kmsg_dump.h
include/linux/kmsg_dump.h
+17
-30
kernel/debug/kdb/kdb_main.c
kernel/debug/kdb/kdb_main.c
+5
-5
kernel/printk/internal.h
kernel/printk/internal.h
+1
-6
kernel/printk/printk.c
kernel/printk/printk.c
+240
-238
kernel/printk/printk_safe.c
kernel/printk/printk_safe.c
+11
-19
No files found.
arch/powerpc/kernel/nvram_64.c
View file @
c8dbea6d
...
...
@@ -647,6 +647,7 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
{
struct
oops_log_info
*
oops_hdr
=
(
struct
oops_log_info
*
)
oops_buf
;
static
unsigned
int
oops_count
=
0
;
static
struct
kmsg_dump_iter
iter
;
static
bool
panicking
=
false
;
static
DEFINE_SPINLOCK
(
lock
);
unsigned
long
flags
;
...
...
@@ -681,13 +682,14 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
return
;
if
(
big_oops_buf
)
{
kmsg_dump_get_buffer
(
dumper
,
false
,
kmsg_dump_rewind
(
&
iter
);
kmsg_dump_get_buffer
(
&
iter
,
false
,
big_oops_buf
,
big_oops_buf_sz
,
&
text_len
);
rc
=
zip_oops
(
text_len
);
}
if
(
rc
!=
0
)
{
kmsg_dump_rewind
(
dump
er
);
kmsg_dump_get_buffer
(
dump
er
,
false
,
kmsg_dump_rewind
(
&
it
er
);
kmsg_dump_get_buffer
(
&
it
er
,
false
,
oops_data
,
oops_data_sz
,
&
text_len
);
err_type
=
ERR_TYPE_KERNEL_PANIC
;
oops_hdr
->
version
=
cpu_to_be16
(
OOPS_HDR_VERSION
);
...
...
arch/powerpc/xmon/xmon.c
View file @
c8dbea6d
...
...
@@ -3005,7 +3005,7 @@ print_address(unsigned long addr)
static
void
dump_log_buf
(
void
)
{
struct
kmsg_dump
er
dumper
=
{
.
active
=
1
}
;
struct
kmsg_dump
_iter
iter
;
unsigned
char
buf
[
128
];
size_t
len
;
...
...
@@ -3017,9 +3017,9 @@ dump_log_buf(void)
catch_memory_errors
=
1
;
sync
();
kmsg_dump_rewind
_nolock
(
&
dump
er
);
kmsg_dump_rewind
(
&
it
er
);
xmon_start_pagination
();
while
(
kmsg_dump_get_line
_nolock
(
&
dump
er
,
false
,
buf
,
sizeof
(
buf
),
&
len
))
{
while
(
kmsg_dump_get_line
(
&
it
er
,
false
,
buf
,
sizeof
(
buf
),
&
len
))
{
buf
[
len
]
=
'\0'
;
printf
(
"%s"
,
buf
);
}
...
...
arch/um/kernel/kmsg_dump.c
View file @
c8dbea6d
// SPDX-License-Identifier: GPL-2.0
#include <linux/kmsg_dump.h>
#include <linux/spinlock.h>
#include <linux/console.h>
#include <linux/string.h>
#include <shared/init.h>
...
...
@@ -9,8 +10,11 @@
static
void
kmsg_dumper_stdout
(
struct
kmsg_dumper
*
dumper
,
enum
kmsg_dump_reason
reason
)
{
static
struct
kmsg_dump_iter
iter
;
static
DEFINE_SPINLOCK
(
lock
);
static
char
line
[
1024
];
struct
console
*
con
;
unsigned
long
flags
;
size_t
len
=
0
;
/* only dump kmsg when no console is available */
...
...
@@ -29,11 +33,18 @@ static void kmsg_dumper_stdout(struct kmsg_dumper *dumper,
if
(
con
)
return
;
if
(
!
spin_trylock_irqsave
(
&
lock
,
flags
))
return
;
kmsg_dump_rewind
(
&
iter
);
printf
(
"kmsg_dump:
\n
"
);
while
(
kmsg_dump_get_line
(
dump
er
,
true
,
line
,
sizeof
(
line
),
&
len
))
{
while
(
kmsg_dump_get_line
(
&
it
er
,
true
,
line
,
sizeof
(
line
),
&
len
))
{
line
[
len
]
=
'\0'
;
printf
(
"%s"
,
line
);
}
spin_unlock_irqrestore
(
&
lock
,
flags
);
}
static
struct
kmsg_dumper
kmsg_dumper
=
{
...
...
drivers/hv/vmbus_drv.c
View file @
c8dbea6d
...
...
@@ -1391,6 +1391,7 @@ static void vmbus_isr(void)
static
void
hv_kmsg_dump
(
struct
kmsg_dumper
*
dumper
,
enum
kmsg_dump_reason
reason
)
{
struct
kmsg_dump_iter
iter
;
size_t
bytes_written
;
phys_addr_t
panic_pa
;
...
...
@@ -1404,7 +1405,8 @@ static void hv_kmsg_dump(struct kmsg_dumper *dumper,
* Write dump contents to the page. No need to synchronize; panic should
* be single-threaded.
*/
kmsg_dump_get_buffer
(
dumper
,
false
,
hv_panic_page
,
HV_HYP_PAGE_SIZE
,
kmsg_dump_rewind
(
&
iter
);
kmsg_dump_get_buffer
(
&
iter
,
false
,
hv_panic_page
,
HV_HYP_PAGE_SIZE
,
&
bytes_written
);
if
(
bytes_written
)
hyperv_report_panic_msg
(
panic_pa
,
bytes_written
);
...
...
drivers/mtd/mtdoops.c
View file @
c8dbea6d
...
...
@@ -52,6 +52,7 @@ static struct mtdoops_context {
int
nextcount
;
unsigned
long
*
oops_page_used
;
unsigned
long
oops_buf_busy
;
void
*
oops_buf
;
}
oops_cxt
;
...
...
@@ -180,6 +181,9 @@ static void mtdoops_write(struct mtdoops_context *cxt, int panic)
u32
*
hdr
;
int
ret
;
if
(
test_and_set_bit
(
0
,
&
cxt
->
oops_buf_busy
))
return
;
/* Add mtdoops header to the buffer */
hdr
=
cxt
->
oops_buf
;
hdr
[
0
]
=
cxt
->
nextcount
;
...
...
@@ -190,7 +194,7 @@ static void mtdoops_write(struct mtdoops_context *cxt, int panic)
record_size
,
&
retlen
,
cxt
->
oops_buf
);
if
(
ret
==
-
EOPNOTSUPP
)
{
printk
(
KERN_ERR
"mtdoops: Cannot write from panic without panic_write
\n
"
);
return
;
goto
out
;
}
}
else
ret
=
mtd_write
(
mtd
,
cxt
->
nextpage
*
record_size
,
...
...
@@ -203,6 +207,8 @@ static void mtdoops_write(struct mtdoops_context *cxt, int panic)
memset
(
cxt
->
oops_buf
,
0xff
,
record_size
);
mtdoops_inc_counter
(
cxt
);
out:
clear_bit
(
0
,
&
cxt
->
oops_buf_busy
);
}
static
void
mtdoops_workfunc_write
(
struct
work_struct
*
work
)
...
...
@@ -271,13 +277,19 @@ static void mtdoops_do_dump(struct kmsg_dumper *dumper,
{
struct
mtdoops_context
*
cxt
=
container_of
(
dumper
,
struct
mtdoops_context
,
dump
);
struct
kmsg_dump_iter
iter
;
/* Only dump oopses if dump_oops is set */
if
(
reason
==
KMSG_DUMP_OOPS
&&
!
dump_oops
)
return
;
kmsg_dump_get_buffer
(
dumper
,
true
,
cxt
->
oops_buf
+
MTDOOPS_HEADER_SIZE
,
kmsg_dump_rewind
(
&
iter
);
if
(
test_and_set_bit
(
0
,
&
cxt
->
oops_buf_busy
))
return
;
kmsg_dump_get_buffer
(
&
iter
,
true
,
cxt
->
oops_buf
+
MTDOOPS_HEADER_SIZE
,
record_size
-
MTDOOPS_HEADER_SIZE
,
NULL
);
clear_bit
(
0
,
&
cxt
->
oops_buf_busy
);
if
(
reason
!=
KMSG_DUMP_OOPS
)
{
/* Panics must be written immediately */
...
...
@@ -394,6 +406,7 @@ static int __init mtdoops_init(void)
return
-
ENOMEM
;
}
memset
(
cxt
->
oops_buf
,
0xff
,
record_size
);
cxt
->
oops_buf_busy
=
0
;
INIT_WORK
(
&
cxt
->
work_erase
,
mtdoops_workfunc_erase
);
INIT_WORK
(
&
cxt
->
work_write
,
mtdoops_workfunc_write
);
...
...
fs/pstore/platform.c
View file @
c8dbea6d
...
...
@@ -385,6 +385,7 @@ void pstore_record_init(struct pstore_record *record,
static
void
pstore_dump
(
struct
kmsg_dumper
*
dumper
,
enum
kmsg_dump_reason
reason
)
{
struct
kmsg_dump_iter
iter
;
unsigned
long
total
=
0
;
const
char
*
why
;
unsigned
int
part
=
1
;
...
...
@@ -405,6 +406,8 @@ static void pstore_dump(struct kmsg_dumper *dumper,
}
}
kmsg_dump_rewind
(
&
iter
);
oopscount
++
;
while
(
total
<
kmsg_bytes
)
{
char
*
dst
;
...
...
@@ -435,7 +438,7 @@ static void pstore_dump(struct kmsg_dumper *dumper,
dst_size
-=
header_size
;
/* Write dump contents. */
if
(
!
kmsg_dump_get_buffer
(
dump
er
,
true
,
dst
+
header_size
,
if
(
!
kmsg_dump_get_buffer
(
&
it
er
,
true
,
dst
+
header_size
,
dst_size
,
&
dump_size
))
break
;
...
...
include/linux/kmsg_dump.h
View file @
c8dbea6d
...
...
@@ -29,6 +29,16 @@ enum kmsg_dump_reason {
KMSG_DUMP_MAX
};
/**
* struct kmsg_dump_iter - iterator for retrieving kernel messages
* @cur_seq: Points to the oldest message to dump
* @next_seq: Points after the newest message to dump
*/
struct
kmsg_dump_iter
{
u64
cur_seq
;
u64
next_seq
;
};
/**
* struct kmsg_dumper - kernel crash message dumper structure
* @list: Entry in the dumper list (private)
...
...
@@ -41,31 +51,19 @@ struct kmsg_dumper {
struct
list_head
list
;
void
(
*
dump
)(
struct
kmsg_dumper
*
dumper
,
enum
kmsg_dump_reason
reason
);
enum
kmsg_dump_reason
max_reason
;
bool
active
;
bool
registered
;
/* private state of the kmsg iterator */
u32
cur_idx
;
u32
next_idx
;
u64
cur_seq
;
u64
next_seq
;
};
#ifdef CONFIG_PRINTK
void
kmsg_dump
(
enum
kmsg_dump_reason
reason
);
bool
kmsg_dump_get_line_nolock
(
struct
kmsg_dumper
*
dumper
,
bool
syslog
,
char
*
line
,
size_t
size
,
size_t
*
len
);
bool
kmsg_dump_get_line
(
struct
kmsg_dumper
*
dumper
,
bool
syslog
,
bool
kmsg_dump_get_line
(
struct
kmsg_dump_iter
*
iter
,
bool
syslog
,
char
*
line
,
size_t
size
,
size_t
*
len
);
bool
kmsg_dump_get_buffer
(
struct
kmsg_dumper
*
dumper
,
bool
syslog
,
char
*
buf
,
size_t
size
,
size_t
*
len
);
void
kmsg_dump_rewind_nolock
(
struct
kmsg_dumper
*
dumper
);
bool
kmsg_dump_get_buffer
(
struct
kmsg_dump_iter
*
iter
,
bool
syslog
,
char
*
buf
,
size_t
size
,
size_t
*
len_out
);
void
kmsg_dump_rewind
(
struct
kmsg_dump
er
*
dump
er
);
void
kmsg_dump_rewind
(
struct
kmsg_dump
_iter
*
it
er
);
int
kmsg_dump_register
(
struct
kmsg_dumper
*
dumper
);
...
...
@@ -77,30 +75,19 @@ static inline void kmsg_dump(enum kmsg_dump_reason reason)
{
}
static
inline
bool
kmsg_dump_get_line_nolock
(
struct
kmsg_dumper
*
dumper
,
bool
syslog
,
const
char
*
line
,
size_t
size
,
size_t
*
len
)
{
return
false
;
}
static
inline
bool
kmsg_dump_get_line
(
struct
kmsg_dumper
*
dumper
,
bool
syslog
,
static
inline
bool
kmsg_dump_get_line
(
struct
kmsg_dump_iter
*
iter
,
bool
syslog
,
const
char
*
line
,
size_t
size
,
size_t
*
len
)
{
return
false
;
}
static
inline
bool
kmsg_dump_get_buffer
(
struct
kmsg_dump
er
*
dump
er
,
bool
syslog
,
static
inline
bool
kmsg_dump_get_buffer
(
struct
kmsg_dump
_iter
*
it
er
,
bool
syslog
,
char
*
buf
,
size_t
size
,
size_t
*
len
)
{
return
false
;
}
static
inline
void
kmsg_dump_rewind_nolock
(
struct
kmsg_dumper
*
dumper
)
{
}
static
inline
void
kmsg_dump_rewind
(
struct
kmsg_dumper
*
dumper
)
static
inline
void
kmsg_dump_rewind
(
struct
kmsg_dump_iter
*
iter
)
{
}
...
...
kernel/debug/kdb/kdb_main.c
View file @
c8dbea6d
...
...
@@ -2101,7 +2101,7 @@ static int kdb_dmesg(int argc, const char **argv)
int
adjust
=
0
;
int
n
=
0
;
int
skip
=
0
;
struct
kmsg_dump
er
dumper
=
{
.
active
=
1
}
;
struct
kmsg_dump
_iter
iter
;
size_t
len
;
char
buf
[
201
];
...
...
@@ -2126,8 +2126,8 @@ static int kdb_dmesg(int argc, const char **argv)
kdb_set
(
2
,
setargs
);
}
kmsg_dump_rewind
_nolock
(
&
dump
er
);
while
(
kmsg_dump_get_line
_nolock
(
&
dump
er
,
1
,
NULL
,
0
,
NULL
))
kmsg_dump_rewind
(
&
it
er
);
while
(
kmsg_dump_get_line
(
&
it
er
,
1
,
NULL
,
0
,
NULL
))
n
++
;
if
(
lines
<
0
)
{
...
...
@@ -2159,8 +2159,8 @@ static int kdb_dmesg(int argc, const char **argv)
if
(
skip
>=
n
||
skip
<
0
)
return
0
;
kmsg_dump_rewind
_nolock
(
&
dump
er
);
while
(
kmsg_dump_get_line
_nolock
(
&
dump
er
,
1
,
buf
,
sizeof
(
buf
),
&
len
))
{
kmsg_dump_rewind
(
&
it
er
);
while
(
kmsg_dump_get_line
(
&
it
er
,
1
,
buf
,
sizeof
(
buf
),
&
len
))
{
if
(
skip
)
{
skip
--
;
continue
;
...
...
kernel/printk/internal.h
View file @
c8dbea6d
...
...
@@ -12,8 +12,6 @@
#define PRINTK_NMI_CONTEXT_OFFSET 0x010000000
extern
raw_spinlock_t
logbuf_lock
;
__printf
(
4
,
0
)
int
vprintk_store
(
int
facility
,
int
level
,
const
struct
dev_printk_info
*
dev_info
,
...
...
@@ -21,7 +19,6 @@ int vprintk_store(int facility, int level,
__printf
(
1
,
0
)
int
vprintk_default
(
const
char
*
fmt
,
va_list
args
);
__printf
(
1
,
0
)
int
vprintk_deferred
(
const
char
*
fmt
,
va_list
args
);
__printf
(
1
,
0
)
int
vprintk_func
(
const
char
*
fmt
,
va_list
args
);
void
__printk_safe_enter
(
void
);
void
__printk_safe_exit
(
void
);
...
...
@@ -56,10 +53,8 @@ void defer_console_output(void);
#else
__printf
(
1
,
0
)
int
vprintk_func
(
const
char
*
fmt
,
va_list
args
)
{
return
0
;
}
/*
* In !PRINTK builds we still export
logbuf_lock spin_lock,
console_sem
* In !PRINTK builds we still export console_sem
* semaphore and some of console functions (console_unlock()/etc.), so
* printk-safe must preserve the existing local IRQ guarantees.
*/
...
...
kernel/printk/printk.c
View file @
c8dbea6d
This diff is collapsed.
Click to expand it.
kernel/printk/printk_safe.c
View file @
c8dbea6d
...
...
@@ -16,7 +16,7 @@
#include "internal.h"
/*
*
printk() could not take logbuf_lock in NMI context
. Instead,
*
In NMI and safe mode, printk() avoids taking locks
. Instead,
* it uses an alternative implementation that temporary stores
* the strings into a per-CPU buffer. The content of the buffer
* is later flushed into the main ring buffer via IRQ work.
...
...
@@ -267,17 +267,9 @@ void printk_safe_flush(void)
void
printk_safe_flush_on_panic
(
void
)
{
/*
* Make sure that we could access the
main ring buffer
.
* Make sure that we could access the
safe buffers
.
* Do not risk a double release when more CPUs are up.
*/
if
(
raw_spin_is_locked
(
&
logbuf_lock
))
{
if
(
num_online_cpus
()
>
1
)
return
;
debug_locks_off
();
raw_spin_lock_init
(
&
logbuf_lock
);
}
if
(
raw_spin_is_locked
(
&
safe_read_lock
))
{
if
(
num_online_cpus
()
>
1
)
return
;
...
...
@@ -319,9 +311,7 @@ void noinstr printk_nmi_exit(void)
* reordering.
*
* It has effect only when called in NMI context. Then printk()
* will try to store the messages into the main logbuf directly
* and use the per-CPU buffers only as a fallback when the lock
* is not available.
* will store the messages into the main logbuf directly.
*/
void
printk_nmi_direct_enter
(
void
)
{
...
...
@@ -367,7 +357,7 @@ void __printk_safe_exit(void)
this_cpu_dec
(
printk_context
);
}
__printf
(
1
,
0
)
int
vprintk_func
(
const
char
*
fmt
,
va_list
args
)
asmlinkage
int
vprintk
(
const
char
*
fmt
,
va_list
args
)
{
#ifdef CONFIG_KGDB_KDB
/* Allow to pass printk() to kdb but avoid a recursion. */
...
...
@@ -376,20 +366,21 @@ __printf(1, 0) int vprintk_func(const char *fmt, va_list args)
#endif
/*
*
Try to u
se the main logbuf even in NMI. But avoid calling console
*
U
se the main logbuf even in NMI. But avoid calling console
* drivers that might have their own locks.
*/
if
((
this_cpu_read
(
printk_context
)
&
PRINTK_NMI_DIRECT_CONTEXT_MASK
)
&&
raw_spin_trylock
(
&
logbuf_lock
))
{
if
((
this_cpu_read
(
printk_context
)
&
PRINTK_NMI_DIRECT_CONTEXT_MASK
)
)
{
unsigned
long
flags
;
int
len
;
printk_safe_enter_irqsave
(
flags
);
len
=
vprintk_store
(
0
,
LOGLEVEL_DEFAULT
,
NULL
,
fmt
,
args
);
raw_spin_unlock
(
&
logbuf_lock
);
printk_safe_exit_irqrestore
(
flags
);
defer_console_output
();
return
len
;
}
/* Use extra buffer in NMI
when logbuf_lock is taken or in safe mode
. */
/* Use extra buffer in NMI. */
if
(
this_cpu_read
(
printk_context
)
&
PRINTK_NMI_CONTEXT_MASK
)
return
vprintk_nmi
(
fmt
,
args
);
...
...
@@ -420,3 +411,4 @@ void __init printk_safe_init(void)
/* Flush pending messages that did not have scheduled IRQ works. */
printk_safe_flush
();
}
EXPORT_SYMBOL
(
vprintk
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment