static int __init mtdoops_init(void)
向workstruct &cxt->work_erase 注册延期执行函数
INIT_WORK(&cxt->work_write, mtdoops_workfunc_write);
注册MTD 使用者,
/**
* register_mtd_user - register a 'user' of MTD devices.
* @new: pointer to notifier info structure
*
* Registers a pair of callbacks function to be called upon addition
* or removal of MTD devices. Causes the 'add' callback to be immediately
* invoked for each MTD device currently present in the system.
*/
static struct mtd_notifier mtdoops_notifier = {
.add = mtdoops_notify_add,.remove = mtdoops_notify_remove,
};
static void mtdoops_notify_add(struct mtd_info *mtd)
注册kmsg_dump
/**
* kmsg_dump_register - register a kernel log dumper.
* @dumper: pointer to the kmsg_dumper structure
*
* Adds a kernel log dumper to the system. The dump callback in the
* structure will be called when the kernel oopses or panics and must be
* set. Returns zero on success and %-EINVAL or %-EBUSY otherwise.
*/
cxt->dump.dump = mtdoops_do_dump;
err = kmsg_dump_register(&cxt->dump);
发生kernel panic/oops, 调用注册的kmsg_dump callback 函数:
static void mtdoops_do_dump(struct kmsg_dumper *dumper,
panic 立即执行MTD 写入
/* Panics must be written immediately */
if (reason != KMSG_DUMP_OOPS) {
if (!cxt->mtd->panic_write)
printk(KERN_ERR "mtdoops: Cannot write from panic without panic_write\n");
else
mtdoops_write(cxt, 1);
return;
}
OOPS 向标准工作队列 events 添加workstruct,
/* For other cases, schedule work to write it "nicely" */
schedule_work(&cxt->work_write);
scheduler 调度events 线程时,执行
static void mtdoops_workfunc_write(struct work_struct *work)
{
struct mtdoops_context *cxt =
container_of(work, struct mtdoops_context, work_write);
mtdoops_write(cxt, 0);
}