A target running with oops_only=1 receives nothing when the kernel
oopses, which is the one thing the option exists for. Only a panic
still gets through.
netconsole_write() bails out unless oops_in_progress is set, and that
flag is already gone by the time netconsole runs. netconsole is
CON_NBCON_ATOMIC_UNSAFE, so console_is_usable() keeps it out of the
emergency flush an oops prints in, and the records only leave the box
once the printer thread runs.
die() wakes that thread from oops_exit(), by which point
bust_spinlocks(0) has cleared oops_in_progress again. TAINT_DIE is set
in between, so test that as well, behind a helper.
With oops_only=1 on a netdevsim target, an lkdtm EXCEPTION produces 44
lines of oops. The receiver gets none of them before this change and
all of them after it, while ordinary messages stay suppressed.
The taint never clears, so from the first oops on, an oops_only target
sends everything instead of going quiet again. Sending the aftermath of
a crash beats sending nothing.
Fixes: 7eab73b18630 ("netconsole: convert to NBCON console infrastructure")
Signed-off-by: Breno Leitao <[email protected]>
---
drivers/net/netconsole.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index b358e5c3673510..833da29717ed1d 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -83,7 +83,8 @@ MODULE_PARM_DESC(netconsole, "
netconsole=[src-port]@[src-ip]/[dev],[tgt-port]@<
static bool oops_only;
module_param(oops_only, bool, 0600);
-MODULE_PARM_DESC(oops_only, "Only log oops messages");
+MODULE_PARM_DESC(oops_only,
+ "Only log oops messages, everything once the kernel died");
#define NETCONSOLE_PARAM_TARGET_PREFIX "cmdline"
@@ -96,6 +97,17 @@ static int __init option_setup(char *opt)
__setup("netconsole=", option_setup);
#endif /* MODULE */
+/* The kernel is dying, or has died.
+ *
+ * oops_in_progress only spans the printing of the crash. netconsole is
+ * CON_NBCON_ATOMIC_UNSAFE, so the records reach the target later, from the
+ * printer thread, with the flag already cleared. TAINT_DIE outlives it.
+ */
+static bool netconsole_kernel_dying(void)
+{
+ return oops_in_progress || test_taint(TAINT_DIE);
+}
+
/* Linked list of all configured targets */
static LIST_HEAD(target_list);
/* target_cleanup_list is used to track targets that need to be cleaned outside
@@ -2474,7 +2486,7 @@ static void netconsole_write(struct nbcon_write_context
*wctxt, bool extended)
{
struct netconsole_target *nt;
- if (oops_only && !oops_in_progress)
+ if (oops_only && !netconsole_kernel_dying())
return;
list_for_each_entry(nt, &target_list, list) {
--
2.53.0-Meta