Commit 7cc84e0e authored by Ray Zhang's avatar Ray Zhang Committed by Miquel Raynal

mtd: mtdoops: panic caused mtdoops to call mtdoops_erase function immediately

The panic function disables the local interrupts, preemption, and all
other processors. When the invoked mtdoops needs to erase a used page,
calling schedule_work() to do it will not work. Instead, just call
mtdoops_erase function immediately.

Tested:
~# echo c > /proc/sysrq-trigger
[  171.654759] sysrq: Trigger a crash
[  171.658325] Kernel panic - not syncing: sysrq triggered crash
......
[  172.406423] mtdoops: not ready 34, 35 (erase immediately)
[  172.432285] mtdoops: ready 34, 35
[  172.435633] Rebooting in 10 seconds..
Signed-off-by: default avatarRay Zhang <sgzhang@google.com>
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20221010045549.2221965-4-sgzhang@google.com
parent 340193e0
...@@ -170,7 +170,7 @@ static void mtdoops_workfunc_erase(struct work_struct *work) ...@@ -170,7 +170,7 @@ static void mtdoops_workfunc_erase(struct work_struct *work)
mtdoops_erase(cxt); mtdoops_erase(cxt);
} }
static void mtdoops_inc_counter(struct mtdoops_context *cxt) static void mtdoops_inc_counter(struct mtdoops_context *cxt, int panic)
{ {
cxt->nextpage++; cxt->nextpage++;
if (cxt->nextpage >= cxt->oops_pages) if (cxt->nextpage >= cxt->oops_pages)
...@@ -180,12 +180,20 @@ static void mtdoops_inc_counter(struct mtdoops_context *cxt) ...@@ -180,12 +180,20 @@ static void mtdoops_inc_counter(struct mtdoops_context *cxt)
cxt->nextcount = 0; cxt->nextcount = 0;
if (page_is_used(cxt, cxt->nextpage)) { if (page_is_used(cxt, cxt->nextpage)) {
schedule_work(&cxt->work_erase); pr_debug("not ready %d, %d (erase %s)\n",
return; cxt->nextpage, cxt->nextcount,
panic ? "immediately" : "scheduled");
if (panic) {
/* In case of panic, erase immediately */
mtdoops_erase(cxt);
} else {
/* Otherwise, schedule work to erase it "nicely" */
schedule_work(&cxt->work_erase);
}
} else {
pr_debug("ready %d, %d (no erase)\n",
cxt->nextpage, cxt->nextcount);
} }
pr_debug("ready %d, %d (no erase)\n",
cxt->nextpage, cxt->nextcount);
} }
static void mtdoops_write(struct mtdoops_context *cxt, int panic) static void mtdoops_write(struct mtdoops_context *cxt, int panic)
...@@ -221,7 +229,7 @@ static void mtdoops_write(struct mtdoops_context *cxt, int panic) ...@@ -221,7 +229,7 @@ static void mtdoops_write(struct mtdoops_context *cxt, int panic)
mark_page_used(cxt, cxt->nextpage); mark_page_used(cxt, cxt->nextpage);
memset(cxt->oops_buf, 0xff, record_size); memset(cxt->oops_buf, 0xff, record_size);
mtdoops_inc_counter(cxt); mtdoops_inc_counter(cxt, panic);
out: out:
clear_bit(0, &cxt->oops_buf_busy); clear_bit(0, &cxt->oops_buf_busy);
} }
...@@ -286,7 +294,7 @@ static void find_next_position(struct mtdoops_context *cxt) ...@@ -286,7 +294,7 @@ static void find_next_position(struct mtdoops_context *cxt)
cxt->nextcount = maxcount; cxt->nextcount = maxcount;
} }
mtdoops_inc_counter(cxt); mtdoops_inc_counter(cxt, 0);
} }
static void mtdoops_do_dump(struct kmsg_dumper *dumper, static void mtdoops_do_dump(struct kmsg_dumper *dumper,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment