kernel crash 发生后的那些事(四)

2024-06-03 16:32
文章标签 发生 kernel crash

本文主要是介绍kernel crash 发生后的那些事(四),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Oops信息打印后,后面还有一个 crash dump 和系统重启的过程,本例为系统重启,在UBoot中保存core dump.

die-> crash_kexec

kernel/kexec.c:
void crash_kexec(struct pt_regs *regs)
{
    /* Take the kexec_mutex here to prevent sys_kexec_load
     * running on one cpu from replacing the crash kernel
     * we are using after a panic on a different cpu.
     *
     * If the crash kernel was not located in a fixed area
     * of memory the xchg(&kexec_crash_image) would be
     * sufficient.  But since I reuse the memory...
     */
    if (mutex_trylock(&kexec_mutex)) {
        if (kexec_crash_image) {
            struct pt_regs fixed_regs;

            crash_setup_regs(&fixed_regs, regs);
            crash_save_vmcoreinfo();
            machine_crash_shutdown(&fixed_regs);
            machine_kexec(kexec_crash_image);
        }
        else{
            printk(KERN_ERR "Enter crash kexec !!\n");
            struct pt_regs fixed_regs;
            extern void machine_crash_swreset(void);
            crash_setup_regs(&fixed_regs, regs);
            crash_save_vmcoreinfo();
            machine_crash_shutdown(&fixed_regs);
            machine_crash_swreset();
        }
        mutex_unlock(&kexec_mutex);
    }
}

die-> crash_kexec->machine_crash_shutdown

如果是使用Uboot做为crash kernel,代码运行 else分支。
arch/arm/kenerl/machine_kexec.c
void machine_crash_shutdown(struct pt_regs *regs)
{
    unsigned long msecs;

    local_irq_disable();

    atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
    smp_call_function(machine_crash_nonpanic_core, NULL, false);
    msecs = 1000; /* Wait at most a second for the other cpus to stop */
    while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
        mdelay(1);
        msecs--;
    }
    if (atomic_read(&waiting_for_crash_ipi) > 0)
        printk(KERN_WARNING "Non-crashing CPUs did not react to IPI\n");

    crash_save_cpu(regs, smp_processor_id());
    machine_kexec_mask_interrupts();

    printk(KERN_INFO "Loading crashdump kernel...\n");
}

这里有个SMP相关的操作:smp_call_function

kernel/smp.c
/**
 * smp_call_function(): Run a function on all other CPUs.
 * @func: The function to run. This must be fast and non-blocking.
 * @info: An arbitrary pointer to pass to the function.
 * @wait: If true, wait (atomically) until function has completed
 *        on other CPUs.
 *
 * Returns 0.
 *
 * If @wait is true, then returns once @func has returned; otherwise
 * it returns just before the target cpu calls @func.
 *
 * You must not call this function with disabled interrupts or from a
 * hardware interrupt handler or from a bottom half handler.
 */
int smp_call_function(smp_call_func_t func, void *info, int wait)
{
    preempt_disable();
    smp_call_function_many(cpu_online_mask, func, info, wait);
    preempt_enable();

    return 0;
}


void machine_crash_nonpanic_core(void *unused)
{
    struct pt_regs regs;

    crash_setup_regs(&regs, NULL);
    printk(KERN_DEBUG "CPU %u will stop doing anything useful since another CPU has crashed\n",
           smp_processor_id());
    crash_save_cpu(&regs, smp_processor_id());
    flush_cache_all();

    atomic_dec(&waiting_for_crash_ipi);
    while (1)
        cpu_relax();
}

其它的CPU保存寄存器和flush cache 后,进入死循环cpu_relax。

软件复位

machime_kexec.c文件中实现machine_crash_swreset,其中有个定义在 arch/arm/include/asm/system_misc.h
中的全局变量:extern void (*arm_pm_restart)(char str, const char *cmd);
void machine_crash_swreset(void)
{
    printk(KERN_INFO "Software reset on panic!\n");

    flush_cache_all();
    outer_flush_all();
    outer_disable();
    arm_pm_restart(0, NULL);
}
在mach相关的代码中进行赋值
Core.c (arch\arm\mach-xxx):    arm_pm_restart = xxx_restart;

static void xxx_restart(char mode, const char *cmd)
{
    prcm_glb_soft_reset();

}

至此,kernel crash 发生后的所有事情分析完毕。后面会介绍怎样保存有效的kernel dump文件。

这篇关于kernel crash 发生后的那些事(四)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1027515

相关文章

IntelliJ IDEA svn chekout 项目发生svn不是内部命令

错误信息: 1、Cannot checkout from svn: 'C:\Program' 不是内部或外部命令,也不是可运行的程序 或批处理文件 2、server ssl cerificate verification failed:certificate issued for a different hostname.issuer is not trusted (服务器ssl证书验证失败

海思3518平台的uboot 和 kernel烧写

############################# 3518 kernel & uboot 16Mflash  ######################################### 1、组件网络:                                                setenv serverip 1

输入url发生了什么

1.浏览器查询缓存,如果有缓存,则直接跳到第9步 2.浏览器询问操作系统服务器ip 3.操作系统做dns查询,返回ip地址给浏览器 4.浏览器打开对服务器的tcp连接(如果是https的话则更复杂) 5.浏览器通过tcp发送http请求 6.浏览器接收响应并且可能关掉Tcp连接,或者是重新使用连接处理新请求 7.浏览器检查响应是否为一个重定向(3xx结果状态码),或者是重新

android反馈Crash报告

此文章转载他人,担有所改动,,在全局获取异常有所改动 为什么需要反馈Crash报告?   做Android应用程序,要尽量避免程序Crash的发生。虽然说零Crash是程序员追逐的最终目标,但是现实的情况是,程序员只能尽量的减少Crash的发生,而几乎不可能完全杜绝Crash。也许,你认为你的应用的健壮性已经近乎完美,轻松的经受住了测试部门魔鬼般的考验,但是当你的应用发布到市

金蝶KIS新建账套时 从字符串向DateTime转换时失败 从字符串转换为Datetime类型时发生语法错误

需要修改以下几点 控制面板---区域和语言选项---区域选项---自定义,修改为如下格式

展锐T820平台Android11开发:kernel设备树编译问题

一.kernel多board自适应         展锐平台的kernel具有多board自适应功能,即相同体系架构的两个不同的board间,boot.img、socko.img/odmko(vendorboot.img)、dtbo.img是可替换的,这些镜像文件称为R-img(Replaceable images,可替换的镜像)。         要实现这样的效果,R-img都要满足一个共性

kernel中的日志打印

1.kernel中打印日志形式 (1)printk(2)pr_xxx (pr_debug支持动态打印)(3)dev_xxx (dev_dbg支持动态打印)(4)module_param_named (支持动态动态打印)目前在kernel驱动代码中,不在建议直接使用printk直接添加打印信息,而是使用pr_debug、pr_info、dev_info、dev_dbg之类的函数替代,这些函数

Linux Kernel入门到精通系列讲解(QEMU-虚拟化篇) 2.6 Qemu实现power控制器,实现reboot和halt指令

1. 概述 本章节我们想要给我们的Naruto Pi添加Power控制器,由于现在我们的Linux kernel 内使用reboot或halt指令还无法复位或者下电,所以需要添加Power控制器,Qemu里面我们可以写一个简单的寄存器去实现该功能。 2. Qemu杂项驱动 Qemu将一些杂项的实例归入了misc目录,里面都是一些没有统一标准,用户自定义的IP,比如Power contro

80端口被NT kernel System占用

 前段时间停止了Apache,结果在打开的时候发现无法打开,80端口被占用,于是win+r 运行cmd 输入netstat -ano 可以看到80端口被PID4占用,于是打开任务管理器-进程-查看,选择列,勾选PID 可以看到pid 4 的被NT kernel & System 占用

5、catch中发生了未知异常,finally代码块如何应对?

catch中发生了未知异常,finally还会执行么? catch发生了异常,finally还是会执行的,并且是finally执行完成后,才会抛出catch中的异常。 不过catch会吃掉try中抛出的异常,为了避免这种情况,在一些可以预见catch中会发生异常的地方,先把try抛出的异常打印出来,这样从日志中就可以看到完整的异常信息。