一.Linux系統(tǒng)笔宿,陷入內(nèi)核的三種方式
1.系統(tǒng)調(diào)用:應(yīng)用程序主動像操作系統(tǒng)發(fā)出的服務(wù)請求关贵,系統(tǒng)調(diào)用是應(yīng)用程序主動讓內(nèi)核代替進程執(zhí)行在內(nèi)核空間搓译,可能同步也可能異步。
2.中斷:一般由外設(shè)(硬件)發(fā)送電信號到處理器引起的民晒,處理器接收中斷后,會馬上向操作系統(tǒng)反應(yīng)信號的到來锄禽,由操作系統(tǒng)處理新來的數(shù)據(jù)潜必,硬件產(chǎn)生中斷的過程不考慮時鐘同步(隨時產(chǎn)生),也稱為異步中斷沃但。
3.異常:在產(chǎn)生時必須考慮與處理器時鐘同步磁滚,又稱為同步中斷,在處理器執(zhí)行到由于程序失誤而導(dǎo)致的錯誤指令(如被0除)的時候宵晚,或者是在執(zhí)行期間出現(xiàn)特殊情況(缺頁)垂攘,處理器就會產(chǎn)生一個異常维雇。
二.中斷處理機制的實現(xiàn)
1.中斷從硬件到內(nèi)核的路由
從本質(zhì)上來講,中斷是一種電信號搜贤,當設(shè)備有某種事件發(fā)生時谆沃,它就會產(chǎn)生中斷,通過總線把電信號發(fā)送給中斷控制器仪芒。如果中斷的線是激活的唁影,中斷控制器就把電信號發(fā)送給處理器的某個特定引腳。處理器于是立即停止自己正在做的事掂名,跳到中斷處理程序的入口點据沈,進行中斷處理。(上述描述的是硬中斷饺蔑,軟中斷利用指令信號觸發(fā)锌介,處理過程基本一致。)
2.查看Linux下中斷系統(tǒng)
1)文件/proc/interrupts包含系統(tǒng)中斷號猾警,在cpu上發(fā)送中斷的次數(shù)孔祸,設(shè)備接口、中斷名稱等信息
1)第一列表示IRQ號发皿, 第二崔慧、三列表示相應(yīng)的CPU核心被中斷的次數(shù), 第四列表示設(shè)備接口穴墅,第五列表示中斷名稱惶室,如timer(系統(tǒng)時鐘)被CPU0中斷44次
2)IRQ號決定了需要被CPU處理的優(yōu)先級,IRQ號越小意味著優(yōu)先級越高玄货,如 IRQ0 :系統(tǒng)時鐘(不能改變)皇钞,IRQ1 :鍵盤控制器(不能改變)
2)文件/proc/stat
以intr開頭的信息記錄了機器從啟動開始,依賴各個中斷號發(fā)送中斷次數(shù)松捉,第一個數(shù)字3813161表示總的中斷數(shù)目夹界,之后數(shù)字分別表示從中斷號0開始各個中斷號中斷的次數(shù)。
2)文件/proc/irq
? ? ? ? /proc/irq目錄下面會為每個注冊的irq創(chuàng)建一個以irq編號為名字的子目錄隘世,每個子目錄下分別有以下條目:
smp_affinity :irq和cpu之間的親緣綁定關(guān)系掉盅;
smp_affinity_hint :只讀條目,用于用戶空間做irq平衡只用以舒;
spurious? :可以獲得該irq被處理和未被處理的次數(shù)的統(tǒng)計信息趾痘;
? ? ? ? ? Linux 2.4內(nèi)核之后引入了將特定中斷綁定到指定的CPU的技術(shù),稱為SMP IRQ affinity蔓钟。該技術(shù)允許你限制或者重新分配服務(wù)器的工作負載, 從而讓服務(wù)器更有效的工作. 以網(wǎng)卡中斷為例永票,在沒有設(shè)置SMP IRQ affinity時,所有網(wǎng)卡中斷都關(guān)聯(lián)到CPU0, 這導(dǎo)致了CPU0負載過高,而無法有效快速的處理網(wǎng)絡(luò)數(shù)據(jù)包侣集,導(dǎo)致了瓶頸键俱。 通過SMP IRQ affinity,把網(wǎng)卡多個中斷分配到多個CPU上世分,可以分散CPU壓力编振,提高數(shù)據(jù)處理速度。
smp_affinity文件中的數(shù)值以十六進制顯示臭埋,如 /proc/irq/0/smp_affinity內(nèi)容為f踪央, /proc/irq/1/smp_affinity/內(nèi)容為3,對應(yīng)的二進制為1111瓢阴,0011畅蹂,二進制表示中每一位代表一個CPU,1表示該CPU可以中斷該IRQ荣恐,即把0號中斷綁定到前4個CPU(CPU0-3)上面液斜,把1號中斷綁定到前2個CPU(CPU0-2)上面,(當然我的主機只有2個CPU)叠穆;
/proc/irq/default_smp_affinity 指定了默認情況下未激活的IRQ的中斷親和掩碼(affinity mask)少漆。一旦IRQ被激活,它將被設(shè)置為默認的設(shè)置(即default_smp_affinity中記錄的設(shè)置)硼被,該文件能被修改检疫,默認設(shè)置是f。
三.中斷的分類
1.硬中斷
1)硬中斷是由硬件產(chǎn)生的祷嘶,比如,像磁盤夺溢,網(wǎng)卡论巍,鍵盤,時鐘等风响。每個設(shè)備或設(shè)備集都有它自己的IRQ(中斷請求)嘉汰。基于IRQ状勤,CPU可以將相應(yīng)的請求分發(fā)到對應(yīng)的硬件驅(qū)動上(注:硬件驅(qū)動通常是內(nèi)核中的一個子程序鞋怀,而不是一個獨立的進程)。
2)處理中斷的驅(qū)動是需要運行在CPU上的持搜,因此密似,當中斷產(chǎn)生的時候,CPU會中斷當前正在運行的任務(wù)葫盼,來處理中斷残腌。在有多核心的系統(tǒng)上,一個中斷通常只能中斷一顆CPU。
2.軟中斷
1)由當前正在運行的進程所產(chǎn)生的
2)通常抛猫,軟中斷是一些對I/O的請求蟆盹。這些請求會調(diào)用內(nèi)核中可以調(diào)度I/O發(fā)生的程序。對于某些設(shè)備闺金,I/O請求需要被立即處理逾滥,而磁盤I/O請求通常可以排隊并且可以稍后處理败匹。根據(jù)I/O模型的不同寨昙,進程或許會被掛起直到I/O完成,此時內(nèi)核調(diào)度器就會選擇另一個進程去運行哎壳。I/O可以在進程之間產(chǎn)生并且調(diào)度過程通常和磁盤I/O的方式是相同
3)軟中斷僅與內(nèi)核相聯(lián)系毅待。而內(nèi)核主要負責對需要運行的任何其他的進程進行調(diào)度。一些內(nèi)核允許設(shè)備驅(qū)動的一些部分存在于用戶空間归榕,并且當需要的時候內(nèi)核也會調(diào)度這個進程去運行尸红。
4)軟中斷并不會直接中斷CPU。也只有當前正在運行的代碼(或進程)才會產(chǎn)生軟中斷刹泄。這種中斷是一種需要內(nèi)核為正在運行的進程去做一些事情(通常為I/O)的請求外里。有一個特殊的軟中斷是Yield調(diào)用,它的作用是請求內(nèi)核調(diào)度器去查看是否有一些其他的進程可以運行
硬中斷與軟中斷的區(qū)別:
①硬中斷是由外部事件引起的因此具有隨機性和突發(fā)性特石;軟中斷是執(zhí)行中斷指令產(chǎn)生的盅蝗,無面外部施加中斷請求信號,因此中斷的發(fā)生不是隨機的而是由程序安排好的姆蘸。
②硬中斷的中斷響應(yīng)周期墩莫,CPU需要發(fā)中斷回合信號(NMI不需要),軟中斷的中斷響應(yīng)周期逞敷,CPU不需發(fā)中斷回合信號狂秦。
③硬中斷的中斷號是由中斷控制器提供的(NMI硬中斷中斷號系統(tǒng)指定為02H);軟中斷的中斷號由指令直接給出推捐,無需使用中斷控制器裂问。
④硬中斷是可屏蔽的(NMI硬中斷不可屏蔽),軟中斷不可屏蔽牛柒。
3.時鐘中斷
? ? ? ? Linux的OS時鐘的物理產(chǎn)生原因是可編程定時/計數(shù)器產(chǎn)生的輸出脈沖堪簿,這個脈沖送入CPU,就可以引發(fā)一個中斷請求信號皮壁,我們就把它叫做時鐘中斷椭更。
? ? ? 時鐘中斷的主要工作是處理和時間有關(guān)的所有信息、決定是否執(zhí)行調(diào)度程序以及處理下半部分蛾魄。和時間有關(guān)的所有信息包括系統(tǒng)時間甜孤、進程的時間片协饲、延時、使用CPU的時間缴川、各種定時器茉稠,進程更新后的時間片為進程調(diào)度提供依據(jù),然后在時鐘中斷返回時決定是否要執(zhí)行調(diào)度程序把夸。下半部分處理程序是Linux提供的一種機制而线,它使一部分工作推遲執(zhí)行。
四.中斷上下文與進程上下文
中斷上下文是由于硬件發(fā)生中斷時會觸發(fā)中斷信號請求恋日,請求系統(tǒng)處理中斷膀篮,執(zhí)行中斷服務(wù)子程序。
1.中斷上下文:
(1)中斷上文:硬件通過中斷觸發(fā)信號岂膳,導(dǎo)致內(nèi)核調(diào)用中斷處理程序誓竿,進入內(nèi)核空間。這個過程中谈截,硬件的一些變量和參數(shù)也要傳遞給內(nèi)核筷屡,內(nèi)核通過這些參數(shù)進行中斷處理。中斷上文可以看作就是硬件傳遞過來的這些參數(shù)和內(nèi)核需要保存的一些其他環(huán)境(主要是當前被中斷的進程環(huán)境簸喂。
(2)中斷下文:執(zhí)行在內(nèi)核空間的中斷服務(wù)程序毙死。
2.進程上下文:
(1)進程上文:其是指進程由用戶態(tài)切換到內(nèi)核態(tài)是需要保存用戶態(tài)時cpu寄存器中的值,進程狀態(tài)以及堆棧上的內(nèi)容喻鳄,即保存當前進程的執(zhí)行環(huán)境扼倘,以便再次執(zhí)行該進程時,能夠恢復(fù)切換時的狀態(tài)除呵,繼續(xù)執(zhí)行再菊。
(2)進程下文:其是指切換到內(nèi)核態(tài)后執(zhí)行的程序,即進程運行在內(nèi)核空間的部分颜曾。
3.中斷上下文與進程上下文區(qū)別:
1)所謂的“進程上下文”纠拔,可以看作是用戶進程傳遞給內(nèi)核的這些參數(shù)以及內(nèi)核要保存的那一整套的變量和寄存器值和當時的環(huán)境等;所謂的“ 中斷上下文”泛啸,其實也可以看作就是硬件傳遞過來的這些參數(shù)和內(nèi)核需要保存的一些其他環(huán)境(主要是當前被打斷執(zhí)行的進程環(huán)境)。
2)一個進程的上下文可以分為三個部分:用戶級上下文秃症、寄存器上下文以及系統(tǒng)級上下文候址。
(1)用戶級上下文: 正文、數(shù)據(jù)种柑、用戶堆棧以及共享存儲區(qū)岗仑;
(2)寄存器上下文: 通用寄存器、程序寄存器(IP)聚请、處理器狀態(tài)寄存器(EFLAGS)荠雕、棧指針(ESP)稳其;
(3)系統(tǒng)級上下文: 進程控制塊task_struct、內(nèi)存管理信息(mm_struct炸卑、vm_area_struct既鞠、pgd、pte)盖文、內(nèi)核棧等嘱蛋。
3)中斷上下文和特定進程無關(guān),通常都會始終占有CPU(當然中斷可以嵌套五续,但我們一般不這樣做)洒敏,不可以被打斷,所以運行在中斷上下文的代碼就要受一些限制:
1疙驾、睡眠或者放棄CPU凶伙。
? ? ? 這樣做的后果是災(zāi)難性的,因為內(nèi)核在進入中斷之前會關(guān)閉進程調(diào)度它碎,一旦睡眠或者放棄CPU函荣,這時內(nèi)核無法調(diào)度別的進程來執(zhí)行,系統(tǒng)就會死掉
2链韭、嘗試獲得信號量
? ? ? 如果獲得不到信號量偏竟,代碼就會睡眠,會產(chǎn)生和上面相同的情況
3敞峭、執(zhí)行耗時的任務(wù)
? ? ? 中斷處理應(yīng)該盡可能快踊谋,因為內(nèi)核要響應(yīng)大量服務(wù)和請求,中斷上下文占用CPU時間太長會嚴重影響系統(tǒng)功能旋讹。
4殖蚕、訪問用戶空間的虛擬地址
? ? ? 因為中斷上下文是和特定進程無關(guān)的,它是內(nèi)核代表硬件運行在內(nèi)核空間沉迹,所以在終端上下文無法訪問用戶空間的虛擬地址