華為的EulerOS將與鴻蒙統(tǒng)一內(nèi)核
這里使用Ubuntu作為宿主機(jī)器,通過VirtualBox來安裝EulerOS。環(huán)境如下:
客戶機(jī)基本配置
>lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 1
On-line CPU(s) list: 0
Thread(s) per core: 1
Core(s) per socket: 1
座: 1
NUMA 節(jié)點: 1
廠商 ID: GenuineIntel
CPU 系列: 6
型號: 142
型號名稱: Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz
步進(jìn): 10
CPU MHz: 2111.900
BogoMIPS: 4223.80
超管理器廠商: KVM
虛擬化類型: 完全
L1d 緩存: 32K
L1i 緩存: 32K
L2 緩存: 256K
L3 緩存: 8192K
NUMA 節(jié)點0 CPU: 0
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc eagerfpu pni pclmulqdq monitor ssse3 cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx rdrand hypervisor lahf_lm abm 3dnowprefetch fsgsbase avx2 invpcid rdseed clflushopt md_clear flush_l1d
因為需要EulerOS能夠連接外網(wǎng),也需要與本地局域網(wǎng)互通,必要時僅僅與宿主機(jī)戶通。所以啟用了三張網(wǎng)卡,來分別實現(xiàn)。新配置的網(wǎng)卡如果沒有生效,可確認(rèn)在宿主機(jī)啟動了這些網(wǎng)卡,并在EulerOS中使用nmtui圖形界面來管理網(wǎng)卡。
1、訪問Internet
Virtaulbox上配置網(wǎng)卡為nat。
訪問Internet
然后,在客戶機(jī)EulerOS啟用網(wǎng)卡,并看到如下
<:~>ifconfig
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.2.15 netmask 255.255.255.0 broadcast 10.0.2.255
inet6 fe80::7e03:7abe:f6a6:5b43 prefixlen 64 scopeid 0x20<link>
ether 08:00:27:85:04:93 txqueuelen 1000 (Ethernet)
RX packets 53 bytes 5961 (5.8 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 61 bytes 5685 (5.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
2、訪問局域網(wǎng)
Virtaulbox上配置網(wǎng)卡為橋接。
客戶機(jī)中啟用網(wǎng)卡,并看到如下信息:
enp0s9: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.2.136 netmask 255.255.255.0 broadcast 192.168.2.255
inet6 fe80::7c30:6e5d:fd00:d3f2 prefixlen 64 scopeid 0x20<link>
ether 08:00:27:85:2a:f4 txqueuelen 1000 (Ethernet)
RX packets 1252 bytes 109790 (107.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 165 bytes 23796 (23.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
3、只與宿主機(jī)通訊
Virtaulbox上配置主機(jī)網(wǎng)絡(luò),并將客戶機(jī)網(wǎng)卡為Host-only。
客戶機(jī)啟用網(wǎng)卡,將看到如下信息:
enp0s8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.56.102 netmask 255.255.255.0 broadcast 192.168.56.255
inet6 fe80::6d5:1b04:f165:ec3e prefixlen 64 scopeid 0x20<link>
ether 08:00:27:32:23:bc txqueuelen 1000 (Ethernet)
RX packets 14 bytes 5080 (4.9 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 25 bytes 3930 (3.8 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
查看EulerOS版本。
<gaoy:~>cat /etc/euleros-release
EulerOS release 2.0 (SP5)
按照如下情形來配置/etc/yum.repos.d/EulerOS.repo文件
yum repolist
yum install lsof -y
yum install gcc -y
<gaoy:~/code>cat gcc.test.c
#include <stdio.h>
void main(){
printf("Hello gcc. ");
}
<gaoy:~/code>gcc gcc.test.c -o gcc.test
<gaoy:~/code>./gcc.test
Hello gcc. <gaoy:~/code>
yum install gcc-c++ -y
<gaoy:~/code>cat gcc.test.cpp
#include <iostream>
#include <string>
int main(){
std::cout<<"Hello gcc. "<< std::endl;
return 0;
}
<gaoy:~/code>g++ gcc.test.cpp
<gaoy:~/code>./a.out
Hello gcc.
Corrected machine-check error interrupt (CMCI)是MCA的增強(qiáng)特性,它提供了一種threshold-based的錯誤上報方式。這種模式下,軟件可以配置硬件corrected MC errors的閾值,硬件發(fā)生CE(Corrected Error)次數(shù)達(dá)到閾值后,會產(chǎn)生一個中斷通知到軟件處理。
值得一提的是,CMCI是隨MCA加入的特性,最開始只能通過軟件輪詢方式獲取CE信息。CMCI中斷通知方式的優(yōu)點是每個CE都會經(jīng)過IRQ Handle處理,不會丟失任一CE;而輪詢方式可能因為輪詢頻率低、存儲空間有限等原因,導(dǎo)致丟失CE。但是并不是說CMCI最優(yōu),CMCI的缺點是大量CE會產(chǎn)生中斷風(fēng)暴,影響機(jī)器的性能。不幸的是在云服務(wù)器場景,CE風(fēng)暴是比較常見的,那么當(dāng)下Intel服務(wù)器是如何解決這個問題的呢?下面會講到。
CMCI機(jī)制
CMCI默認(rèn)是關(guān)閉的,軟件需要通過配置IA32_MCG_CAP[10]=1打開。
軟件通過IA32_MCi_CTL2 MSR來控制對應(yīng)Bank使能/關(guān)閉CMCI功能。
通過IA32_MCi_CTL2 Bit 14:0設(shè)置閾值,如果設(shè)置非0,則使用配置的閾值;如果CMCI不支持,則全0;
CMCI機(jī)制如下圖
硬件通過比較IA32_MCi_CTL2 Bit 14:0和IA32_MCi_STATUS Bit 52:38,如果數(shù)值相等,那么overflow event發(fā)送到APIC的CMCI LVT entry。如果MC error涉及多個processors,那么CMCI中斷會同時發(fā)送到這些processors,比如2個cpu共享的cache發(fā)生CE,那么這兩個cpu都會收到CMCI。
CMCI初始化
以Linux v6.3分支為例,內(nèi)核使能CMCI代碼
C++ |
1.cmci_supported()函數(shù)主要事項包括
?根據(jù)內(nèi)核啟動參數(shù)"mce=no_cmci,ignore_ce"判斷是否打開cmci和ce上報功能
?檢查硬件是否支持cmci
?通過MCG_CMCI_P bit判斷硬件是否使能cmci功能
2.mce_threshold_vector=intel_threshold_interrupt; 聲明cmci的中斷處理函數(shù)為intel_threshold_interrupt();
3.cmci_discover()函數(shù)主要完成
?遍歷所有banks,通過配置IA32_MCi_CTL2寄存器使能所有bank的cmci功能;
C++ |
?設(shè)置cmci threshold值,代碼如下
C++ |
如果用戶未通過啟動參數(shù)"mce=bios_cmci_threshold"配置值,則val=CMCI_THRESHOLD,為1;
如果啟動參數(shù)"mce=bios_cmci_threshold"配置,那么表示bios已配置threshold值,即val & MCI_CTL2_CMCI_THRESHOLD_MASK不為0,跳過else if判斷,采用bios配置值;如果bios未配置值,val & MCI_CTL2_CMCI_THRESHOLD_MASK為0,那么驅(qū)動初始化threshold為1。
4.cmci_recheck()
cmci_recheck函數(shù)通過調(diào)用machine_check_poll(),檢查CPU #0是否有遺漏的CE&UCE events。
CMCI處理
cmci中斷處理函數(shù)為intel_threshold_interrupt(),定義在arch/x86/kernel/cpu/mce/intel.c
C++ |
1.cmci_storm_detect()函數(shù)主要是對cmci storm的處理,代碼如下
C++ |
該函數(shù)通過jiffies,判斷固定時間內(nèi)發(fā)生的cmci次數(shù)是否大于CMCI_STORM_THRESHOLD(15),如果否則return,反之說明發(fā)生cmci storm,則執(zhí)行cmci_toggle_interrupt_mode()關(guān)閉cmci功能, 切換為poll mode,通過輪詢方式獲取event;
2.非cmci storm情況下,通過machine_check_poll(MCP_TIMESTAMP, this_cpu_ptr(&mce_banks_owned))函數(shù)獲取并記錄故障信息
參數(shù)1定義如下,MCP_TIMESTAMP表示會記錄當(dāng)前TSC
C++ |
machine_check_poll函數(shù)主要功能是通過讀取IA32_MCG_STATUS、IA32_MCi_STATUS寄存器信息和CPU的ip、cs等相關(guān)信息,然后故障分類,將CE event或其他故障類型event記錄到/dev/mcelog。用戶可以通過讀取/dev/mcelog獲取錯誤記錄。
執(zhí)行流程如下,過程說明在代碼注釋中
C++ |
總結(jié)一下,CMCI是MCA的一個增強(qiáng)特性,主要用于將硬件CE、UCNA等類型故障通過中斷方式上報到軟件,軟件收到中斷后,執(zhí)行中斷處理函數(shù)intel_threshold_interrupt()采取irq mode或poll mode記錄錯誤信息到/dev/mcelog,用戶態(tài)可以通過/dev/mcelog獲取硬件故障信息。
參考文檔:《Intel? 64 and IA-32 Architectures Software Developer’s Manual 》
轉(zhuǎn)載:
https://www.eet-china.com/mp/a234382.html