性能分析_linux服務器CPU_中斷


 

中斷

1.  指標范圍

1.1  Interrupt rate

應該與cpu利用率結合分析,如果cpu利用率在合理范圍內,大量的中斷也是可以接受的。一個巨大的中斷值,同時伴隨着緩慢的系統性能表現,指示存在硬件問題

1.2  Context Switch Rate

應該與cpu利用率結合分析,如果cpu利用率在合理范圍內,大量的中斷也是可以接受的。

當每次調用引起的上下文切換大於等於4時,需要結合分析

網上也有說,需要少於5000*cpu個數

2.  概念說明

CPU 是一種硬件資源,和任何其他硬件設備一樣也需要驅動和管理程序才能使用,我們可以把內核的進程調度看作是 CPU 的管理程序,用來管理和分配CPU 資源,合理安排進程搶占 CPU,並決定哪個進程該使用 CPU、哪個進程該等待。操作系統內核里的進程調度主要用來調度兩類資源:進程(或線程)和中斷,進程調度給不同的資源分配了不同的優先級,優先級最高的是硬件中斷,其次是內核(系統)進程,最后是用戶進程。每個 CPU 都維護着一個可運行隊列,用來存放那些可運行的線程。線程要么在睡眠狀態(blocked 正在等待 IO)要么在可運行狀態,如果 CPU 當前負載太高而新的請求不斷,就會出現進程調度暫時應付不過來的情況,這個時候就不得不把線程暫時放到可運行隊列里。

2.1  Interrupt rate

每秒內的設備中斷數。CPU接收硬件驅動發出的中斷請求數。當一個驅動器有一個時間需要被kernel操作時。例如:如果一個磁盤控制器從磁盤上取得了一個數據塊,kernel需要讀取使用這個塊,那么磁盤控制器會觸發一個中斷; kernel接收每個中斷。

在系統中,中斷處理器的優先級非常高,而且執行速度非常快。很多時候,有些中斷處理並不需要很高的處理優先級,所以也有soft-interrupt handler。如果有很多的中斷,kernel需要花費大量的時間去處理中斷。可以檢查/proc/interrupts能夠知道中斷發生在哪個CPU 上。

Interrupt Rate中包括內核由於進程的時間片中斷,內核的時鍾頻率可以通過如下命令知道,每秒總的時鍾中斷數就是 = cpu個數 * 核數 * CONFIG_HZ

cat /boot/config-`uname -r` | grep '^CONFIG_HZ='

CONFIG_HZ=100

通過cat /proc/interrupts可以查看中斷的類型以及次數,用vmstat查看的 in(Interrupt)就是這個參數

 

2.2  Context Switch Rate

大部分現在的CPU在同一時間只能運行一個process,雖然也有一些CPU,例如超線程技術的CPU,能實現同時運行超過一個process。linux把這種CPU看作多個單線程CPU,linux內核不斷的在不同process間切換,造成一個錯覺,讓人感覺一個單CPU同時處理多個任務,不同process之間的切換稱作 Context Switch。

當系統做Context Switch時,CPU保存所有old process的context信息並獲得new process的所有context信息,Context信息包括大量的linux追蹤每個process信息,尤其是一些資源: 那些process正在執行,被分配了哪些內存,它打開了那些文件,等等。切換Context會觸發大量的信息移動,這是比較高的開銷。

首先,kernel調度觸發context switches。為了保證每個process平等的共享CPU時間,kernel周期性中斷running的process,如果合適kernel調度器會開始一個其他的process而不是讓當前的process繼續執行,每次的周期性中斷或者定時中斷都可能觸發context switch。每秒定時中斷的次數因不同架構和不同的kernel版本而不同。

獲取每秒中斷次數的一個簡單辦法是通過監控 /proc/interrupts文件,通過命令cat /proc/interrupts | grep timer; sleep 10 ; cat /proc/interrupts | grep timer 可以看到在指定的時間內timer次數的變化。如果你的context switch比timer中斷大很多。那么context switch更多的可能是I/O請求或者其他長時間的系統調用(比如sleep)產生。 

當一個應用請求一個操作不能立即實現時,kernel開始 context switch操作: 存入請求的process並且試着切換到其他runnable process。這將使得CPU保持工作狀態。Context Switch大體上由兩個部分組成:中斷和進程(包括線程)切換,一次中斷(Interrupt)會引起一次切換,進程(線程)的創建、激活之類的也會引起一次切換。 Context Switch 的值也和TPS(Transaction Per Second)相關的,假設每次調用會引起N次CS,那么就可以得出

     Context Switch Rate = Interrupt Rate + TPS* N

CSR減掉IR,就是進程/線程的切換,假如主進程收到請求交給線程處理,線程處理完畢歸還給主進程,這里就是2次切換。也可以用CSR、IR、TPS的值代入公式中,得出每次事物導致的切換數。因此,要降低CSR,就必須在每個TPS引起的切換上下功夫,只有N這個值降下去,CSR就能降低,理想情況下N=0,但是無論如何如果N >= 4,則要分析。用vmstat查看 cs(Context Switch)就是這個參數

 

3.  淺析cpu中斷過程

此處可直接閱讀http://www.cnblogs.com/funeral/archive/2013/03/06/2945485.html

3.1  cpu中斷技術的定義

ü  計算機處於執行期間

ü  系統內發生了非尋常或非預期的急需處理事件

ü  CPU暫時中斷當前正在執行的程序而轉去執行相應的事件處理程序

ü  處理完畢后返回原來被中斷處繼續執行

舉個現實中的例子:

你正在看書,突然你的朋友打來電話,於是你放下書本去接電話,電話打完接着看書。電話響->放下書本->接電話->繼續看書這一個過程,就類似於CPU中斷的處理過程。

3.2  CPU中斷的作用

早期的CPU處理外設的事件(比如接收鍵盤輸入),往往采用“輪詢”的方式。即CPU像個查崗的一樣輪番對外設順序訪問,比如它先看看鍵盤有沒被按下,有的話就處理,沒的話繼續往下看鼠標有沒有移動,再看看打印機……這種方式使CPU的執行效率很低,且CPU與外設不能同時工作(因為要等待CPU來“巡查”)。中斷模式時就是說CPU不主動訪問這些設備,只管處理自己的任務。如果有設備要與CPU聯系,或要CPU處理一些事情,它會給CPU發一個中斷請求信號。這時CPU就會放下正在進行的工作而去處理這個外設的請求。處理完中斷后,CPU返回去繼續執行中斷以前的工作。

中斷模式的作用和優點

ü  可以使CPU和外設同時工作,使系統可以及時地響應外部事件,外設的處理速度一般慢於cpu,cpu不能一直等待外部事件

ü  可允許多個外設同時工作,大大提高了CPU的利用率,也提高了數據輸入、輸出的速度。

ü  可以使CPU及時處理各種軟硬件故障(比如計算機在運行過程中,出現了難以預料的情況或一些故障,如電源掉電、存儲出錯、運算溢出等等。計算機可以利用中斷系統自行處理,而不必停機或報告工作人員。)

3.3  CPU中斷的類型

在計算機系統中,根據中斷源的不同,通常將分為硬件中斷和軟件中斷

ü  硬件中斷

硬件中斷又稱外部中斷,分為:可屏蔽中斷、非屏蔽中斷。

可屏蔽中斷。常由計算機的外設或一些接口功能產生,如鍵盤、打印機、串行口等;這種類型的中斷可以在CPU要處理其它緊急操作時,被軟件屏蔽或忽略。例如打印機中斷,CPU對打印機中斷請求的響應可以快一些,也可以慢一些,因為讓打印機稍等待一會也是完全合理的。

非屏蔽中斷。由意外事件導致,如電源斷電、內存校驗錯誤等;對於這種類型的中斷事件,無法通過軟件進行屏蔽,CPU必須無條件響應。例如電源斷電,一旦出現此中斷請求,必須立即無條件地響應,否則進行其他任何工作都是沒有意義的。

 在x86架構的處理器中,CPU的中斷控制器由兩根引腳(INTR和NMI)接收外部中斷請求信號。其中: 1. INTR接收可屏蔽中斷請求;2. NMI接收非屏蔽中斷請求 

ü  軟件中斷

軟件中斷又稱內部中斷、異常,是指在程序中調用INTR中斷指令引起的中斷。比如winAPI中,keybd_event和mouse_event兩個函數,就是用來模擬鍵盤和鼠標的輸入(只是猜測)。 

3.4  CPU中斷的過程

ü  中斷請求

中斷請求是由中斷源向CPU發出中斷請求信號。外部設備發出中斷請求信號要具備以下條件:外部設備的工作已經告一段落。例如輸入設備只有在啟動后,將要輸入的數據送到接口電路的數據寄存器(即准備好要輸入的數據)之后,才可以向CPU發出中斷請求;系統允許該外設發出中斷請求。如果系統不允許該外設發出中斷請求,可以將這個外設的請求屏蔽。當這個外設中斷請求被屏蔽,雖然這個外設准備工作已經完成,也不能發出中斷請求。

ü  中斷響應、處理和返回

當滿足了中斷的條件后,CPU就會響應中斷,轉入中斷程序處理。關閉中斷信號接收器;保存現場(context);給出中斷入口,轉入相應的中斷服務程序;處理完成,返回並恢復現場(context);開啟中斷信號接收器

ü  中斷排隊和中斷判優

中斷申請是隨機的,有時會出現多個中斷源同時提出中斷申請。CPU每次只能響應一個中斷源的請求。CPU不可能對所有中斷請求一視同仁,它會根據各中斷源工作性質的輕重緩急,預先安排一個優先級順序。當多個中斷源同時申請中斷時,即按此優先級順序進行排隊,等候CPU處理。 

3.5  多核CPU對中斷的處理

多核CPU的中斷處理和單核有很大不同。多核的各處理器核心之間需要通過中斷方式進行通信,所以CPU芯片內部既有各處理器核心的本地中斷控制器,又有負責仲裁各核之間中斷分配的全局中斷控制器。現今的多核處理器在中斷處理和中斷控制方面主要使用的是APIC(Advanced Programmable Interrupt Controllers),即高級編程中斷控制器。它是基於中斷控制器兩個基礎功能單元--本地單元以及I/O單元的分布式體系結構。在多核系統中,多個本地和I/O APIC單元能夠作為一個整體通過APIC總線互相操作。

APIC的功能有,接受來自處理器中斷引腳的內部或外部I/O APIC的中斷,然后將這些中斷發送給處理器核心進行處理。在多核處理器系統中,接收和發送核內中斷消息

對於外部設備發出的中斷請求,由全局中斷控制器接收請求並決定交給CPU的哪一個核心處理。也可針對APIC編程,讓所有的中斷都被一個固定的CPU處理。

4.  Linux中的中斷處理

本章節文章可直接閱讀http://www.uml.org.cn/embeded/201304021.asp

4.1  中斷實現

在Linux驅動程序中,為設備實現一個中斷包含兩個步驟:向內核注冊中斷;實現中斷處理函數。

在實地址模式中,CPU把內存中從0開始的1KB空間作為一個中斷向量表。表中的每一項占4個字節。但是在保護模式中,有這4個字節的表項構成的中斷向量表不滿足實際需求,於是根據反映模式切換的信息和偏移量的足夠使得中斷向量表的表項由8個字節組成,而中斷向量表也叫做了中斷描述符表(IDT)。在CPU中增加了一個用來描述中斷描述符表寄存器(IDTR),用來保存中斷描述符表的起始地址。

外部設備當需要操作系統做相關的事情的時候,會產生相應的中斷。設備通過相應的中斷線向中斷控制器發送高電平以產生中斷信號,而操作系統則會從中斷控制器的狀態位取得那根中斷線上產生的中斷。而且只有在設備在對某一條中斷線擁有控制權,才可以向這條中斷線上發送信號。也由於現在的外設越來越多,中斷線又是很寶貴的資源不可能被一一對應。因此在使用中斷線前,就得對相應的中斷線進行申請。無論采用共享中斷方式還是獨占一個中斷,申請過程都是先將所有的中斷線進行掃描,得出哪些沒有別占用,從其中選擇一個作為該設備的IRQ。其次,通過中斷申請函數申請相應的IRQ。最后,根據申請結果查看中斷是否能夠被執行

4.2  中斷處理機制

Linux中斷下半部處理有三種方式:軟中斷、tasklet、工作隊列。

4.2.1    最簡單的中斷機制

最簡單的中斷機制就是像芯片手冊上講的那樣,在中斷向量表中填入跳轉到對應處理函數的指令,然后在處理函數中實現需要的功能,它的好處很明顯,簡單,直接。類似下圖:

 

4.2.2    下半部

中斷處理函數所做的第一件事情就是屏蔽中斷(或者是什么都不做,因為常常是如果不清除IF位,就等於屏蔽中斷了),當然只屏蔽同一種中斷。之所以要屏蔽中斷,是因為新的中斷會再次調用中斷處理函數,導致原來中斷處理現場的破壞。即破壞了interrupt context。

隨着系統的不斷復雜,中斷處理函數要做的事情也越來越多,多到都來不及接收新的中斷了。於是發生了中斷丟失,這顯然不行,於是產生了新的機制:分離中斷接收與中斷處理過程。

Linux中斷分為兩個半部:上半部(tophalf)和下半部(bottom half)。上半部的功能是"登記中斷",當一個中斷發生時,它進行相應地硬件讀寫后就把中斷例程的下半部掛到該設備的下半部執行隊列中去。因此,上半部 執行的速度就會很快,可以服務更多的中斷請求。但是,僅有"登記中斷"是遠遠不夠的,因為中斷的事件可能很復雜。因此,Linux引入了一個下半部,來完 成中斷事件的絕大多數使命。下半部和上半部最大的不同是下半部是可中斷的,而上半部是不可中斷的,下半部幾乎做了中斷處理程序所有的事情,而且可以被新的中斷打斷!下半部則相對來說並不是非常緊急的,通常還是比較耗時的,因此由系統自行安排運行時機,不在中斷服務上下文中執行。

從上圖中看,只看int0的處理。Func0為中斷接收函數。中斷只能簡單的觸發func0,而func0則能做更多的事情,它與funcA之間可以使用隊列等緩存機制。當又有中斷發生時,func0被觸發,然后發送一個中斷請求到緩存隊列,然后讓funcA去處理。由於func0做的事情是很簡單的,所以不會影響int0的再次接收。而且在func0返回時就會使能int0,因此funcA執行時間再長也不會影響int0的接收。

4.2.3    軟中斷

linux中斷處理。作為一個操作系統顯然不能任由每個中斷都各自為政,統一管理是必須的。不可中斷部分的共同部分放在函數do_IRQ中,需要添加中斷處理函數時,通過request_irq實現。下半部放在do_softirq中,也就是軟中斷,通過open_softirq添加對應的處理函數。

 

4.2.4    Tasklet

隨着中斷數的不停增加,軟中斷不夠用了,於是下半部又做了進化。軟中斷用輪詢的方式處理。假如正好是最后一種中斷,則必須循環完所有的中斷類型,才能最終執行對應的處理函數。顯然當年開發人員為了保證輪詢的效率,於是限制中斷個數為32個。為了提高中斷處理數量,順道改進處理效率,於是產生了tasklet機制。

Tasklet采用無差別的隊列機制,有中斷時才執行,免去了循環查表之苦。Tasklet作為一種新機制,顯然可以承擔更多的優點。正好這時候SMP越來越火了,因此又在tasklet中加入了SMP機制,保證同種中斷只在一個cpu上執行。在軟中斷時代,顯然沒有這種考慮。因此同一種中斷可以在兩個cpu上同時執行,很可能造成沖突。tasklet的優點無類型數量限制;效率高無需循環查表;支持SMP機制;

 

4.2.5    工作隊列

前面的機制不論如何折騰,有一點是不會變的。它們都在中斷上下文中。即它們不可掛起。而且由於是串行執行,因此只要有一個處理時間較長,則會導致其他中斷響應的延遲。為了完成這些不可能完成的任務,於是出現了工作隊列。工作隊列說白了就是一組內核線程,作為中斷守護線程來使用。多個中斷可以放在一個線程中,也可以每個中斷分配一個線程。工作隊列對線程作了封裝,使用起來更方便。因為工作隊列是線程,所以我們可以使用所有可以在線程中使用的方法。

 

Tasklet其實也不一定是在中斷上下文中執行,它也有可能在線程中執行。假如中斷數量很多,而且這些中斷都是自啟動型的(中斷處理函數會導致新的中斷產生),則有可能cpu一直在這里執行中斷處理函數,會導致用戶進程永遠得不到調度時間。為了避免這種情況,linux發現中斷數量過多時,會把多余的中斷處理放到一個單獨的線程中去做,就是ksoftirqd線程。這樣又保證了中斷不多時的響應速度,又保證了中斷過多時不會把用戶進程餓死。

問題是我們不能保證我們的tasklet或軟中斷處理函數一定會在線程中執行,所以還是不能使用進程才能用的一些方法,如放棄調度、長延時等。

Linux實現下半部的機制主要有tasklet和工作隊列

4.3  中斷函數

與Linux設備驅動中中斷處理相關的首先是申請與釋放IRQ的API request_irq()和free_irq()

4.3.1    中斷注冊函數

用於實現中斷的注冊功能的request_irq,int request_irq(unsigned int irq, void (*handler)(int, void*, struct pt_regs *), unsigned long irqflags, const char *devname, void *dev_id)返回0表示成功,或者返回一個錯誤碼

參數說明:

ü  unsigned int irq //要申請的硬件中斷號

ü  void (*handler)(int,void *,struct pt_regs *) //是向系統登記的中斷處理函數,是一個回調函數,中斷發生時,系統調用這個函數

ü  unsigned long irqflags //與中斷管理有關的屬性,若設置SA_INTERRUPT,標明中斷處理程序是快速處理程序,快速處理程序被調用時屏蔽所有中斷,慢速處理程 序不屏蔽;若設置SA_SHIRQ,則多個設備共享中斷。

ü  const char * devname //設備名

ü  void *dev_id 共享中斷時使用,用作共享中斷線的指針。一般設置為這個設備的device結構本身或者NULL。它是一個獨特的標識,用在當釋放中斷線時以及可能還被驅動用來指向它自己的私有數據區,來標識哪個設備在中斷;這個參數在真正的驅動程序中一般是指向設備數據結構的指針。在調用中斷處理程序的時候它就會傳遞給中斷處理程序的void *dev_id。如果中斷沒有被共享dev_id 可以設置為 NULL。

flags參數與中斷管理有關的選項說明

#define IRQF_DISABLED       0x00000020    /*中斷禁止*/

#define IRQF_SAMPLE_RANDOM  0x00000040    /*供系統產生隨機數使用*/

#define IRQF_SHARED      0x00000080 /*在設備之間可共享*/

#define IRQF_PROBE_SHARED   0x00000100/*探測共享中斷*/

#define IRQF_TIMER       0x00000200/*專用於時鍾中斷*/

#define IRQF_PERCPU      0x00000400/*每CPU周期執行中斷*/

#define IRQF_NOBALANCING 0x00000800/*復位中斷*/

#define IRQF_IRQPOLL     0x00001000/*共享中斷中根據注冊時間判斷*/

#define IRQF_ONESHOT     0x00002000/*硬件中斷處理完后觸發*/

#define IRQF_TRIGGER_NONE   0x00000000/*無觸發中斷*/

#define IRQF_TRIGGER_RISING 0x00000001/*指定中斷觸發類型:上升沿有效*/

#define IRQF_TRIGGER_FALLING 0x00000002/*中斷觸發類型:下降沿有效*/

#define IRQF_TRIGGER_HIGH   0x00000004/*指定中斷觸發類型:高電平有效*/

#define IRQF_TRIGGER_LOW 0x00000008/*指定中斷觸發類型:低電平有效*/

#define IRQF_TRIGGER_MASK   (IRQF_TRIGGER_HIGH|IRQF_TRIGGER_LOW|\IRQF_TRIGGER_RISING| IRQF_TRIGGER_FALLING)

#define IRQF_TRIGGER_PROBE  0x00000010/*觸發式檢測中斷*/

 說明:如果設置IRQF_DISABLED(SA_INTERRUPT),表示是一個“快速”中斷處理程序否則是一個“慢速”中斷處理程序。快速中斷保證中斷處理的原子性(不被打斷),而慢速中斷則不保證。即“開啟中斷”標志位(處理器IF)在運行快速中斷處理程序時是關閉的,因此在服務該中斷時,不會被其他類型的中斷打斷;而調用慢速中斷處理時,其它類型的中斷仍可以得到服務。

ü  IRQF_SHARED(SA_SHIRQ)

該位表明中斷可以在設備間共享。共享中斷就是將不同的設備掛到同一個中斷信號線上。Linux對共享的支持主要是為PCI設備服務。共享中斷也是通過request_irq函數來注冊的,但有三個特別之處:申請共享中斷時,必須在flags參數中指定 IRQF_SHARED位;dev_id參數必須是唯一的;共享中斷的處理程序中,不能使用disable_irq(unsigned int irq),如果使用了這個函數,共享中斷信號線的其它設備將同樣無法使用中斷,也就無法正常工作了

4.3.2    中斷處理函數

中斷處理程序就是普通的C代碼,是在中斷上下文中運行的,它的行為受到某些限制:不能向用戶空間發送或接受數據;不能使用可能引起阻塞的函數;不能使用可能引起調度的函數。

void short_sh_interrupt(int irq, void *dev_id, struct pt_regs *regs)//判斷是否是本設備產生了中斷

{value = inb(short_base);

if (!(value & 0x80)) return;//清除中斷位(如果設備支持自動清除,則不需要這步)

outb(value & 0x7F, short_base);//中斷處理,通常是數據接收

。。。。。。。。。/* 喚醒等待數據的進程 */

wake_up_interruptible(&short_queue);

4.3.3    釋放中斷

當設備不再需要使用中斷時(通常在驅動卸載時),應當把它們返還給系統,使用函數void free_irq(unsigned int irq, void *dev_id)

5.  參考資料

http://www.cnblogs.com/funeral/archive/2013/03/06/2945485.html

http://www.uml.org.cn/embeded/201304021.asp

http://blog.chinaunix.net/uid-27139412-id-3955865.html

http://blog.163.com/leichi3255@126/blog/static/748333872010047527968/

http://blog.csdn.net/stanjiang2010/article/details/5760743

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM