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: Ray Zhang <sgzhang@google.com> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Link: https://lore.kernel.org/linux-mtd/20221010045549.2221965-4-sgzhang@google.com
This commit is contained in:
Родитель
340193e079
Коммит
7cc84e0e07
|
@ -170,7 +170,7 @@ static void mtdoops_workfunc_erase(struct work_struct *work)
|
|||
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++;
|
||||
if (cxt->nextpage >= cxt->oops_pages)
|
||||
|
@ -180,12 +180,20 @@ static void mtdoops_inc_counter(struct mtdoops_context *cxt)
|
|||
cxt->nextcount = 0;
|
||||
|
||||
if (page_is_used(cxt, cxt->nextpage)) {
|
||||
schedule_work(&cxt->work_erase);
|
||||
return;
|
||||
pr_debug("not ready %d, %d (erase %s)\n",
|
||||
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)
|
||||
|
@ -221,7 +229,7 @@ static void mtdoops_write(struct mtdoops_context *cxt, int panic)
|
|||
mark_page_used(cxt, cxt->nextpage);
|
||||
memset(cxt->oops_buf, 0xff, record_size);
|
||||
|
||||
mtdoops_inc_counter(cxt);
|
||||
mtdoops_inc_counter(cxt, panic);
|
||||
out:
|
||||
clear_bit(0, &cxt->oops_buf_busy);
|
||||
}
|
||||
|
@ -286,7 +294,7 @@ static void find_next_position(struct mtdoops_context *cxt)
|
|||
cxt->nextcount = maxcount;
|
||||
}
|
||||
|
||||
mtdoops_inc_counter(cxt);
|
||||
mtdoops_inc_counter(cxt, 0);
|
||||
}
|
||||
|
||||
static void mtdoops_do_dump(struct kmsg_dumper *dumper,
|
||||
|
|
Загрузка…
Ссылка в новой задаче