linux系統計時器

linux時鐘有很多種,粗略來分可分成兩類:提供中斷的週期性時鐘(rtc、pit等),提供計數的遞增型時鐘(如tsc)

這裏簡單羅列幾種常見的。

(1)RTC

(2)TSC

(3)KVM_CLOCK

(4)acpi_pm

查看當前系統支持的時鐘

cat /sys/devices/system/clocksource/clocksource0/available_clocksource

查看當前使用的時鐘

cat /sys/devices/system/clocksource/clocksource0/current_clocksource

RTC


圖片.png

RTC系統結構圖

RTC通過獨立電池供電,系統可從RTC讀取時間信息,來確保斷電後時間運行連續性。在內核中RTC驅動可分爲兩層,一層爲抽象層(與硬件無關)用於管理RTC設備、設備節點、屬性節點註冊及操作。另一層爲底層驅動層(硬件相關)

抽象層程序在/drivers/rtc目錄下,主要涉及下面幾個文件:

  • class.c   用於管理和註冊RTC設備結構、sysfs、procfs及RTC類;

  • rtc-dev.c 用於註冊和管理RTC設備節點,爲用戶空間提供devfs操作接口,主要操作有rtc_read,rtc_ioctl; 

  • rtc-proc.c  用於管理rtc的procfs屬性節點,提供一些中斷狀態、標誌查詢;

  • rtc-sysfs.c 用於管理rtc設備的sysfs屬性,如獲取RTC設備名字、日期、時間等屬性信息;

  • interface.c 爲rtc-dev.c 和RTC低層驅動提供操作接口

RTC設備驅動通過rtc_device_register向系統註冊rtc設備,並在proc、sys等目錄下生成相應屬性文件。當用戶通過/dev/rtcx設備節點發起操作的時候,都需要通過interface接口才能訪問到真實的設備驅動。

在低頻業務場景下,用戶進程通過read(2)、select(2)讀取/dev/rtc來獲取這些中斷。當中斷調用時,進程會阻塞或者退出直到下一個中斷到來。在高頻業務場景下,用戶進程會檢查一箇中斷數來判斷當前是否有未處理的中斷。

中斷頻率可以通過/proc/sys/dev/rtc/max-user-freq文件來修改(默認是64hz)

RTC底層操作接口

這些操作接口都封裝在

int (*open)(struct device *);                           打開設備

void (*release)(struct device *);                    釋放設備

int (*ioctl)(struct device *, unsigned int, unsigned long);    

int (*read_time)(struct device *, struct rtc_time *);   讀取RTC時間;

int (*set_time)(struct device *, struct rtc_time *);    設置RTC時間;

int (*read_alarm)(struct device *, struct rtc_wkalrm *);  讀取RTC報警時間;

int (*set_alarm)(struct device *, struct rtc_wkalrm *);   設置RTC報警時間;

int (*proc)(struct device *, struct seq_file *);                    用於提供procfs查詢rtc狀態接口;

int (*set_mmss)(struct device *, unsigned long secs);   設置以S爲單位RTC時間接口;

int (*read_callback)(struct device *, int data);                        

int (*alarm_irq_enable)(struct device *, unsigned int enabled);  中斷使能接口;


可以通過hwclock來同步系統時鐘和硬件時鐘信息,或者可通過0x70、0x71端口訪問RTC

系統時間同步到硬件時間:hwclock –w、hwclock --systohc

在用hwclock進行顯示,設置RTC硬件時間之前都會先通過進行時鐘tick同步,同步方法是開啓1S 一次update interrupt,每過1S RTC都會產生一次報警中斷,並更新相應的中斷數據,在應用層通過select來監控是否有RTC數據可讀,如果有數據則會繼續顯示或設置硬件時間操作


TSC


TSC是位於CPU裏面的一個64位的TSC寄存器,它記錄自啓動以來處理器消耗的時鐘週期數,每個CPU時鐘週期其值加一。TSC精度很高,因爲TSC隨着處理器週期速率的變化而變化。

可以通過rdtsc指令來讀取。

[秒 = TSC值/CPU時鐘速率]

  • 通過rdtsc指令來讀取TSC值

taticinline unsigned longlong native_read_tsc(void){

     unsigned long longval;

     asm volatile("rdtsc": "=A" (val));

     return val;

}

這個函數將TSC值放在eax和edx寄存器中,然後再存往val變量中。

KVM_CLOCK


kvm_clock是kvm半虛擬化默認時鐘源。大概原理是在客戶機上實現一個kvmclock驅動,然後客戶機通過這個驅動向VMM查詢時間。

工作流程:客戶機先分配一個內存頁,這個內存頁通過MSR寄存器告知給VMM,VMM將母機系統時間寫入這個內存頁,然後客戶機通過讀取這個內存頁來獲取時間。

cpu steal time 指vcpu等待cpu的時間,vcpu通過vm-exit進入vmm,再從vmm進入guest,這個過程就是cpu steal time。這個可用來衡量虛機性能。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章