linux mce的一些相关内容和用户态监控的设计方法

摘要:
我之所以想写一些关于MCE的东西,并不是因为我遇到了MCE的一个例外。我以前遇到过很多MCE的例外。大多数都在记忆中,但我没有正确记录它们。我写这篇文章是因为我正在考虑参加2018 CLK南京会议。

之所以想起写一点关于mce的东西,倒不是因为遇到mce的异常了,之前遇到过很多mce的异常,内存居多,但没有好好记录下来,写这个是因为参加2018 clk南京会议的一点想法。

void __init trap_init(void)
{
。。。
#ifdef CONFIG_X86_MCE
    set_intr_gate_ist(X86_TRAP_MC, &machine_check, MCE_STACK);
#endif
。。。
}

其中mce的初始化流程为:

Start_kernel-->check_bugs-->identify_boot_cpu-->identify_cpu-->mcheck_cpu_init
 
/*
 * Called for each booted CPU to set up machine checks.
 * Must be called with preempt off:
 */
void mcheck_cpu_init(struct cpuinfo_x86 *c)
{
...
    machine_check_vector = do_machine_check;----------这个函数,主要工作函数

    __mcheck_cpu_init_generic();
    __mcheck_cpu_init_vendor(c);
    __mcheck_cpu_init_clear_banks();
    __mcheck_cpu_init_timer();
....
}

 

 

如果为了调试mce功能,模拟硬件真的出问题,那么可以使用 mce-inject 用户态工具来实现,对应内核的函数为:

void mce_inject_log(struct mce *m)
{
    mutex_lock(&mce_chrdev_read_mutex);
    mce_log(m);
    mutex_unlock(&mce_chrdev_read_mutex);
}

当然调试的时候,一般需要修改tolerant 值,不然有可能引起复位:

cat /sys/devices/system/machinecheck/machinecheck15/tolerant
1
[root@centos7 ~]#
[root@centos7 ~]# ls -alrt /sys/devices/system/machinecheck/machinecheck15/tolerant
-rw-r--r--. 1 root root 4096 10月 15 10:05 /sys/devices/system/machinecheck/machinecheck15/tolerant
[root@centos7 ~]# echo 2 > /sys/devices/system/machinecheck/machinecheck15/tolerant
[root@centos7 ~]# cat /sys/devices/system/machinecheck/machinecheck15/tolerant
2

    
/*
     * Tolerant levels:
     * 0: always panic on uncorrected errors, log corrected errors
     * 1: panic or SIGBUS on uncorrected errors, log corrected errors
     * 2: SIGBUS or log uncorrected errors (if possible), log corr. errors
     * 3: never panic or SIGBUS, log all errors (for testing only)
     */

下面描述的是引发思考的过程,即mce的通知机制,为什么突然想写mce的机制,是因为其实它应用的模式可以解签,

我们把内核维护mce数据的方式视为mce数据的生产者,而用户态取该数据视为消费者的话,生产消费模型非常明显,针对这种模型,一般由两种方式来处理:

1.轮询,

2.中断通知

其中中断通知又可以细分为有守护进程,即daemon 方式,还有一种是无守护进程,直接回调一个trigger的方式。

[root@centos7 ~]# ps -ef |grep -i mce
root       920     1  0 10月13 ?      00:00:00 /usr/sbin/mcelog --ignorenodev --daemon --syslog
root     22125  7650  0 10:18 pts/0    00:00:00 grep --color=auto -i mce
[root@centos7 ~]# cat /proc/920/stack
[<ffffffff81212b95>] poll_schedule_timeout+0x55/0xb0
[<ffffffff8121411d>] do_sys_poll+0x4cd/0x580
[<ffffffff8121443e>] SyS_ppoll+0xce/0x1d0
[<ffffffff816965c9>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff

上面这个例子就是daemon方式,等待在poll中,等内核事件通知。

等待的文件名是/dev/mcelog:

[root@centos7 ~]# lsof -p 920
COMMAND PID USER   FD   TYPE             DEVICE SIZE/OFF     NODE NAME
mcelog  920 root  cwd    DIR                8,2     4096        2 /
mcelog  920 root  rtd    DIR                8,2     4096        2 /
mcelog  920 root  txt    REG                8,2   155952 11550884 /usr/sbin/mcelog
mcelog  920 root  mem    REG                8,2    61752 11535695 /usr/lib64/libnss_files-2.17.so
mcelog  920 root  mem    REG                8,2  2116736 11535677 /usr/lib64/libc-2.17.so
mcelog  920 root  mem    REG                8,2   155064 11535670 /usr/lib64/ld-2.17.so
mcelog  920 root    0u   CHR                1,3      0t0     2052 /dev/null
mcelog  920 root    1u   CHR                1,3      0t0     2052 /dev/null
mcelog  920 root    2u   CHR                1,3      0t0     2052 /dev/null
mcelog  920 root    3r   CHR             10,227      0t0     2205 /dev/mcelog------------------这个设备
mcelog  920 root    4u  unix 0xffff880035de8000      0t0    25331 /var/run/mcelog-client

那么,既然是sys文件系统,肯定有对应的read和write来提供给用户使用,read显而易见,是读取mce日志,write是干啥的?其实这里的write主要就是为了给别人注册用的,mce本身不是

调用write来写数据,它直接维护一个数据区,等别人来读,另外daemon是使用poll方法来等待的,所以自然还得实现poll方法:

static const struct file_operations mce_chrdev_ops = {
    .open            = mce_chrdev_open,
    .release        = mce_chrdev_release,
    .read            = mce_chrdev_read,
    .write            = mce_chrdev_write,
    .poll            = mce_chrdev_poll,
    .unlocked_ioctl        = mce_chrdev_ioctl,
    .llseek            = no_llseek,
};

poll方法的最终实现:

static unsigned int mce_chrdev_poll(struct file *file, poll_table *wait)
{
    poll_wait(file, &mce_chrdev_wait, wait);----------一般阻塞在这,mce_chrdev_wait是一个等待队列
    if (READ_ONCE(mcelog.next))
        return POLLIN | POLLRDNORM;
    if (!mce_apei_read_done && apei_check_mce())
        return POLLIN | POLLRDNORM;
    return 0;
}

既然有等待队列,自然而然就会想,我什么时候唤醒:

int mce_notify_irq(void)
{
    /* Not more than two messages every minute */
    static DEFINE_RATELIMIT_STATE(ratelimit, 60*HZ, 2);

    if (test_and_clear_bit(0, &mce_need_notify)) {
        /* wake processes polling /dev/mcelog */
        wake_up_interruptible(&mce_chrdev_wait);

        if (mce_helper[0])
            schedule_work(&mce_trigger_work);

        if (__ratelimit(&ratelimit))
            pr_info(HW_ERR "Machine check events logged
");

        return 1;
    }
    return 0;
}

既然mce的来源有用户调试,以及真实检测,所以很自然唤醒也有多个来源。比如inject来唤醒和mce真实中断唤醒。

用户进程被poll唤醒之后,一般是poll_in,自然需要去读取数据,直接调用read方法就行。也就是一个简单的read和poll,就解决了监控用户态侧的大部分功能。

其他信息就不一一列了,昨天参加clk南京的会议,其中富士通一个兄弟说他们实现了NVDIMM 的一个监控,原因在于他们认为NVDIMM 是很难replace,所有有必要监控它。

它列出了一个模型,就是用户态daemon,然后设置filter到内核,内核将其监控到的event发给等待的用户进程,使用的方法正是triggers a poll event ,和目前的mce有异曲同工之妙。

假设让你设计这种监控类的东西,你会怎么设计呢?

免责声明:文章转载自《linux mce的一些相关内容和用户态监控的设计方法》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇WebStorm主题设置全国城市部分js下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

linux 中awk命令实现统计列的频数

linux 中awk命令实现统计频数 1、 root@PC1:/home/test# ls a.txt root@PC1:/home/test# cat a.txt 3 4 6 3 2 4 8 2 1 5 6 2 4 3 6 1 2 4 7 3 3 4 7 2 root@PC1:/home/test# awk '{s[$3]++} END {for (i...

MongoDB的使用学习之(四)权限设置--用户名、密码、端口==

本文参照:http://hi.baidu.com/tianhuimin/item/590d96cfd7ac1509c610b26a 本人也是按照此文章操作的,但是有些不妥,红色文字就是我实践后,需要改正的地方 一、关于权限的默认配置    在默认情况下,mongod是监听在0.0.0.0之上的,任何客户端都可以直接连接27017,且没有认证。这样做的好处是...

linux系统redhat7.9安装R

1、查看系统信息 [root@localhost home]# cat /etc/redhat-release Red Hat Enterprise Linux Server release 7.9 (Maipo) [root@localhost home]# lsb_release -a LSB Version: :core-4.1-amd64:c...

【分享】嵌入式Linux系统中的CPU控制

目录 作者 测试环境 介绍 工具 CPU隔离 进程CPU亲和 中断CPU亲和 进程优先级 其它 作者 Hank FU 付汉杰 hankf@xilinx.com 测试环境 Xilinx ZCU106 单板 Xilinx VCU TRD2020.1 介绍 嵌入式Linux系统中,Linux直接管理所有CPU。默认情况下,系统的目标是提高吞吐率,而不...

Linux下查看日志用到的常用命令(一)

首选,如何查看日志:  很多初级测试人员,在进行执行测试用例这个步骤时,发现bug,不能更加的准确去定位bug,在这样的情况下就可以打开Linux服务器,敲命令查看操作进行中的实时日志,当系统报错时,可以截图日志在缺陷管理系统中,开发人员就知道什么地方错了,操作步骤一定要写明确。        1、下载xshell,百度xshell进行下载即      ...

Linux新增用户,并设置Root(管理员)权限

在使用Linux过程中,Root账号拥有最大的操作权限。为保证Root账号安全,一般不直接使用Root账号,而是直接创建一个拥有Root权限的其它账号来使用。详细操作步骤如下 第一步,创建用户,如下图所示: 执行命令:usermod -a -G wheel ypsroot 将用户加入管理权限组 第二步,修改sudoers文件为可修改状态,如下图所示:...