Skip to content

Commit 78c83c8

Browse files
committed
pstore: Do not leave timer disabled for next backend
The pstore.update_ms value was being disabled during pstore_unregister(), which would cause any prior value to go unnoticed on the next pstore_register(). Instead, just let del_timer() stop the timer, which was always sufficient. This additionally refactors the timer reset code and allows the timer to be enabled if the module parameter is changed away from the default. Link: https://lore.kernel.org/lkml/[email protected]/ Signed-off-by: Kees Cook <[email protected]>
1 parent 27e5041 commit 78c83c8

File tree

1 file changed

+19
-15
lines changed

1 file changed

+19
-15
lines changed

fs/pstore/platform.c

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ static int pstore_update_ms = -1;
4444
module_param_named(update_ms, pstore_update_ms, int, 0600);
4545
MODULE_PARM_DESC(update_ms, "milliseconds before pstore updates its content "
4646
"(default is -1, which means runtime updates are disabled; "
47-
"enabling this option is not safe, it may lead to further "
47+
"enabling this option may not be safe; it may lead to further "
4848
"corruption on Oopses)");
4949

5050
/* Names should be in the same order as the enum pstore_type_id */
@@ -150,6 +150,14 @@ static const char *get_reason_str(enum kmsg_dump_reason reason)
150150
}
151151
}
152152

153+
static void pstore_timer_kick(void)
154+
{
155+
if (pstore_update_ms < 0)
156+
return;
157+
158+
mod_timer(&pstore_timer, jiffies + msecs_to_jiffies(pstore_update_ms));
159+
}
160+
153161
/*
154162
* Should pstore_dump() wait for a concurrent pstore_dump()? If
155163
* not, the current pstore_dump() will report a failure to dump
@@ -460,8 +468,10 @@ static void pstore_dump(struct kmsg_dumper *dumper,
460468
}
461469

462470
ret = psinfo->write(&record);
463-
if (ret == 0 && reason == KMSG_DUMP_OOPS)
471+
if (ret == 0 && reason == KMSG_DUMP_OOPS) {
464472
pstore_new_entry = 1;
473+
pstore_timer_kick();
474+
}
465475

466476
total += record.size;
467477
part++;
@@ -604,11 +614,7 @@ int pstore_register(struct pstore_info *psi)
604614
pstore_register_pmsg();
605615

606616
/* Start watching for new records, if desired. */
607-
if (pstore_update_ms >= 0) {
608-
pstore_timer.expires = jiffies +
609-
msecs_to_jiffies(pstore_update_ms);
610-
add_timer(&pstore_timer);
611-
}
617+
pstore_timer_kick();
612618

613619
/*
614620
* Update the module parameter backend, so it is visible
@@ -637,11 +643,7 @@ void pstore_unregister(struct pstore_info *psi)
637643
return;
638644
}
639645

640-
/* Stop timer and make sure all work has finished. */
641-
pstore_update_ms = -1;
642-
del_timer_sync(&pstore_timer);
643-
flush_work(&pstore_work);
644-
646+
/* Unregister all callbacks. */
645647
if (psi->flags & PSTORE_FLAGS_PMSG)
646648
pstore_unregister_pmsg();
647649
if (psi->flags & PSTORE_FLAGS_FTRACE)
@@ -651,6 +653,10 @@ void pstore_unregister(struct pstore_info *psi)
651653
if (psi->flags & PSTORE_FLAGS_DMESG)
652654
pstore_unregister_kmsg();
653655

656+
/* Stop timer and make sure all work has finished. */
657+
del_timer_sync(&pstore_timer);
658+
flush_work(&pstore_work);
659+
654660
free_buf_for_compression();
655661

656662
psinfo = NULL;
@@ -792,9 +798,7 @@ static void pstore_timefunc(struct timer_list *unused)
792798
schedule_work(&pstore_work);
793799
}
794800

795-
if (pstore_update_ms >= 0)
796-
mod_timer(&pstore_timer,
797-
jiffies + msecs_to_jiffies(pstore_update_ms));
801+
pstore_timer_kick();
798802
}
799803

800804
static void __init pstore_choose_compression(void)

0 commit comments

Comments
 (0)