目錄
1.中斷概念
2. Linux中斷處理
" >#上下半部機制
下半部實作機制之軟中斷" >下半部實作機制之軟中斷
下半部實作機制之tasklet" >下半部實作機制之tasklet
可以並行在多個CPU上。 " >)多個不同類型的tasklet可以並行在多個CPU上。
首頁 運維 linux運維 linux軟中斷和工作佇列的作用是什麼

linux軟中斷和工作佇列的作用是什麼

Apr 14, 2022 pm 04:41 PM
linux

linux中軟中斷和工作佇列的作用是實作中斷處理。軟中斷和工作隊列是中斷上下部機制中的下半部實現機制。軟中斷不能睡眠、不能阻塞、不能進程間切換,只能被硬體中斷打斷;而工作隊列可以睡眠,也能被阻塞,能夠在不同的進程間切換,以完成不同的工作。

linux軟中斷和工作佇列的作用是什麼

本教學操作環境:linux5.9.8系統、Dell G3電腦。

linux中軟中斷和工作佇列的作用是實作中斷處理。

1.中斷概念

中斷是指在CPU正常運作期間,由於內部外部事件或由程序預先安排的事件引起的CPU暫時停止正在運行的程序,轉而為該內部或外部事件或預先安排的事件服務的程序中去,服務完畢後再返回去繼續運行被暫時中斷的程序。 Linux中通常分為外部中斷(又稱為硬體中斷)和內部中斷(又叫異常)。

在實位址模式中,CPU把記憶體中從0開始的1KB空間當作一個中斷向量表。表中的每一項佔4個位元組。但在保護模式中,有這4個位元組的表項構成的中斷向量表不滿足實際需求,於是根據反映模式切換的資訊和偏移量的足夠使得中斷向量表的表項由8個位元組組成,而中斷向量表也叫做了中斷描述符表(IDT)。在CPU中增加了一個用來描述中斷描述符表暫存器(ID​​TR),用來保存中斷描述符表的起始位址。

2. Linux中斷處理

2.1 系統中斷號碼

  由上述中斷定義可知,系統中斷向量表中共可保存256個中斷向量入口,即IDT中包含的256個中斷描述子(對應256個中斷向量)。

  而0-31號中斷向量被intel公司保留用來處理例外事件,不能另作它用。對這0-31號中斷向量,作業系統只需提供異常的處理程序,當產生一個異常時,處理機就會自動把控制轉移到相應的處理程序的入口,運行相應的處理程序;而事實上,對於這32個處理異常的中斷向量,2.6版本的Linux只提供了0-17號中斷向量的處理程序,其對應處理程序請參考下表、中斷向量和例外事件對應表;也就是說,17-31號中斷向量是空著未用的。

 

###4溢位Overflow5 邊界監控中斷Bounds6無效操作碼Invalid_op7裝置不可用Device_not_available8#雙故障#9#Segment_not_present#12堆疊異常一般保護例外狀況頁異常
中斷向量號 #Linux的處理程序
0 除法錯誤 pide_error
1 #偵錯例外 Debug
2 NMI中斷 #Nmi
##3 單字節,int 3 #Int3
Double_fault ##協處理器段溢出
Coprocessor_segment_overrun 10 無效TSS
Incalid_tss #11 缺失片段
#Stack_segment 13
General_protection 14
#####Page_fault# #################15############# (intel保留)############Spurious_interrupt_bug### ###############16############協處理器出錯############Coprocessor_error########################################################################## #############17############對齊檢查中斷############Alignment_check######## #######

 

  0-31號中斷向量已被保留,那麼剩下32-255共224個中斷向量可用。這224個中斷向量又是怎麼分配的呢? 2.6版本的Linux中,除了0x80 (SYSCALL_VECTOR)用作系統呼叫總入口之外,其他都用在外部硬體中斷來源上,其中包括可程式中斷控制器8259A的15個irq;事實上,當沒有定義CONFIG_X86_IO_APIC時,其他223(除0x80外)個中斷向量,只利用了從32號開始的15個,其它208個空著未用。

 2.2 中斷請求

  2.2.1 中斷請求概述

  外部裝置當需要作業系統做相關的事情的時候,會產生對應的中斷。

  設備透過對應的中斷線向中斷控制器發送高電平以產生中斷訊號,而作業系統則會從中斷控制器的狀態位元取得那根中斷線上產生的中斷。而且只有在設備在對某一條中斷線擁有控制權,才可以向這條中斷線上發送訊號。也由於現在的周邊越來越多,中斷線又是很寶貴的資源不可能被一一對應。因此在使用中斷線前,就得對對應的中斷線進行申請。無論採用共享中斷方式或獨佔一個中斷,申請過程都是先講所有的中斷線進行掃描,得出哪些沒有別佔用,從其中選擇一個作為該設備的IRQ。其次,透過中斷申請函數申請對應的IRQ。最後,根據申請結果查看中斷是否能夠被執行。

  2.2.2 中斷相關結構

##  中斷中核心處理數據結構為irq_desc,它完整的描述了一條中斷線,Linux 2.6。22.6中原始碼如下。

  irq_desc#定義在include/linux/irq.h中

/**
 * struct irq_desc - interrupt descriptor
 *
 * @handle_irq:        highlevel irq-events handler [if NULL, __do_IRQ()]
 * @chip:        low level interrupt hardware access
 * @msi_desc:        MSI descriptor
 * @handler_data:    per-IRQ data for the irq_chip methods
 * @chip_data:        platform-specific per-chip private data for the chip
 *            methods, to allow shared chip implementations
 * @action:        the irq action chain
 * @status:        status information
 * @depth:        disable-depth, for nested irq_disable() calls
 * @wake_depth:        enable depth, for multiple set_irq_wake() callers
 * @irq_count:        stats field to detect stalled irqs
 * @irqs_unhandled:    stats field for spurious unhandled interrupts
 * @lock:        locking for SMP
 * @affinity:        IRQ affinity on SMP
 * @cpu:        cpu index useful for balancing
 * @pending_mask:    pending rebalanced interrupts
 * @dir:        /proc/irq/ procfs entry
 * @affinity_entry:    /proc/irq/smp_affinity procfs entry on SMP
 * @name:        flow handler name for /proc/interrupts output */struct irq_desc {
    irq_flow_handler_t    handle_irq;    struct irq_chip        *chip;    struct msi_desc        *msi_desc;    void            *handler_data;    void            *chip_data;    struct irqaction    *action;    /* IRQ action list */
    unsigned int        status;        /* IRQ status */

    unsigned int        depth;        /* nested irq disables */
    unsigned int        wake_depth;    /* nested wake enables */
    unsigned int        irq_count;    /* For detecting broken IRQs */
    unsigned int        irqs_unhandled;
    spinlock_t        lock;
#ifdef CONFIG_SMP
    cpumask_t        affinity;
    unsigned int        cpu;#endif#if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE)
    cpumask_t        pending_mask;#endif#ifdef CONFIG_PROC_FS    struct proc_dir_entry    *dir;#endif
    const char        *name;
} ____cacheline_internodealigned_in_smp;
登入後複製

irq_desc

   其相關聯的幾個結構體如下:

  

定義在include/linux/ interrupt.h中的中斷行動結構體:struct irqaction

struct irqaction {
    irq_handler_t handler;
    unsigned long flags;
    cpumask_t mask;    const char *name;    void *dev_id;    struct irqaction *next;    int irq;    struct proc_dir_entry *dir;
};
登入後複製
  定義在include/linux 中的:irq_chip 晶片相關的處理函數集合

/**
 * struct irq_chip - hardware interrupt chip descriptor
 *
 * @name:        name for /proc/interrupts
 * @startup:        start up the interrupt (defaults to ->enable if NULL)
 * @shutdown:        shut down the interrupt (defaults to ->disable if NULL)
 * @enable:        enable the interrupt (defaults to chip->unmask if NULL)
 * @disable:        disable the interrupt (defaults to chip->mask if NULL)
 * @ack:        start of a new interrupt
 * @mask:        mask an interrupt source
 * @mask_ack:        ack and mask an interrupt source
 * @unmask:        unmask an interrupt source
 * @eoi:        end of interrupt - chip level
 * @end:        end of interrupt - flow level
 * @set_affinity:    set the CPU affinity on SMP machines
 * @retrigger:        resend an IRQ to the CPU
 * @set_type:        set the flow type (IRQ_TYPE_LEVEL/etc.) of an IRQ
 * @set_wake:        enable/disable power-management wake-on of an IRQ
 *
 * @release:        release function solely used by UML
 * @typename:        obsoleted by name, kept as migration helper */struct irq_chip {    const char    *name;
    unsigned int    (*startup)(unsigned int irq);  //中断开始    void        (*shutdown)(unsigned int irq);    //中断关闭    void        (*enable)(unsigned int irq);      //中断使能    void        (*disable)(unsigned int irq);    //中断禁用    void        (*ack)(unsigned int irq);    void        (*mask)(unsigned int irq);    void        (*mask_ack)(unsigned int irq);    void        (*unmask)(unsigned int irq);    void        (*eoi)(unsigned int irq);    void        (*end)(unsigned int irq);    void        (*set_affinity)(unsigned int irq, cpumask_t dest);    int        (*retrigger)(unsigned int irq);    int        (*set_type)(unsigned int irq, unsigned int flow_type);    int        (*set_wake)(unsigned int irq, unsigned int on);    /* Currently used only by UML, might disappear one day.*/#ifdef CONFIG_IRQ_RELEASE_METHOD    void        (*release)(unsigned int irq, void *dev_id);#endif
    /*
     * For compatibility, ->typename is copied into ->name.
     * Will disappear.     */
    const char    *typename;
};
登入後複製

2.2.3 中斷請求實作

#上下半部機制

  我們期望讓中斷處理程序運作得快,並想讓它完成的工作量多,這兩個目標相互制約,如何解決——上下半部機制

  我們把中斷處理切成兩半。中斷處理程序是上半部-接受中斷,他就立刻開始執行,但只有做嚴格時限的工作。能夠被允許稍後完成的工作會推遲到下半部去,此後,在適當的時機,下半部會被開啟終端執行。上半部簡單快速,執行時禁止一些或全部中斷

  下半部稍後執行,而且執行期間可以回應所有的中斷。這種設計可以使系統處於中斷屏蔽狀態的時間盡可能的短,以此來提高系統的反應能力。上半部只有中斷處理程序機制,而下半部的實作有軟中斷實現,tasklet實作和工作佇列實作。

  我們用網路卡來解釋這兩半。當網卡接受到資料包時,通知內核,觸發中斷,所謂的上半部就是,及時讀取資料包到內存,防止因為延遲導致遺失,這是很急迫的工作。讀到記憶體後,這些資料的處理不再緊迫,此時核心可以去執行中斷前執行的程序,而對網路封包的處理則交給下半部處理。

上下半部分割原則

  1) 如果一個任務對時間非常敏感,將其放在中斷處理程序中執行;

  2) 如果一個任務和硬體有關,將其放在中斷處理程序中執行;

  3) 如果一個任務要確保不被其他中斷打斷,將其放在中斷處理程序中執行;

#  4)其他所有任務,考慮放置在下半部執行。

下半部實作機制之軟中斷

  軟中斷作為下半部機制的代表,是隨著SMPshare memory processor)的出現應運而生的,它也是tasklet實作的基礎(tasklet其實只是在軟中斷的基礎上添加了一定的機制)。軟中斷一般是可延遲函數的總稱,有時候也包括了tasklet(請讀者在遇到的時候根據上下文推斷是否包含tasklet)。它的出現就是因為要滿足上面所提出的上半部和下半部的區別,使得對時間不敏感的任務延後執行,軟中斷執行中斷處理程序留給它去完成的剩餘任務,而且可以在多個CPU上並行執行,使得總的系統效率可以更高。它的特性包括:

  a)產生後並不是馬上可以執行,必須要等待核心的調度才能執行。軟中斷不能被自己打斷,只能被硬體中斷打斷(上半部)。

  b)可以並發運行在多個CPU上(即使是相同類型的也可以)。所以軟中斷必須設計為可重入的函數(允許多個CPU同時操作),因此也需要使用自旋鎖來保護其資料結構。

下半部實作機制之tasklet

  tasklet是透過軟中斷實現的,所以它本身也是軟中斷。

  軟中斷用輪詢的方式處理。假如正好是最後一種中斷,則必須循環完所有的中斷類型,才能最終執行對應的處理函數。顯然當年開發人員為了保證輪詢的效率,於是限制中斷個數為32個。

  為了提高中斷處理數量,順道改進處理效率,於是產生了tasklet機制。

  Tasklet採用無差別的佇列機制,有中斷時才執行,免去了循環查表之苦。 Tasklet作為一種新機制,顯然可以承擔更多的優點。正好這時候SMP越來越火紅了,因此又在tasklet中加入了SMP機制,保證同種中斷只能在一個cpu 上執行。在軟中斷時代,顯然沒有這種考慮。因此同一種軟中斷可以在兩個cpu上同時執行,很可能會造成衝突。

  總結下tasklet的優點:

#  (1)無類型數量限制;

##  (

2)效率高,無須循環查表;  (3)支援SMP機制;

#  它的特性如下:  1)一種特定類型的tasklet#只能運行在一個

CPU

上,不能並行,只能串行執行。

  2

)多個不同類型的tasklet可以並行在多個CPU上。

  3

)軟中斷是靜態分配的,在內核編譯好之後,就無法改變。但tasklet就靈活許多,可以在執行時改變(例如新增模組時)。

#####################下半部實作機制之工作佇列(work queue)############## #  上面我們介紹的可延遲函數運行在中斷上下文中(軟中斷的一個檢查點就是###do_IRQ###退出的時候),於是導致了一些問題:軟中斷不能睡眠、不能阻塞。由於中斷上下文出於內核態,沒有進程切換,所以如果軟中斷一旦睡眠或阻塞,將無法退出這種狀態,導致核心會整個僵死。但可阻塞函數不能用在中斷上下文中實現,必須運行在進程上下文中,例如存取磁碟資料塊的函數。因此,可阻塞函數不能用軟中斷來實現。但是它們往往又具有可延遲的特性。 ##################  上面我們介紹的可延遲函數運行在中斷上下文中,於是導致了一些問題,說明它們不可掛起,也就是說軟中斷不能睡眠、不能阻塞,原因是由於中斷上下文出於內核態,沒有進程切換,所以如果軟中斷一旦睡眠或阻塞,將無法退出這種狀態,導致核心會整個僵死。因此,可阻塞函數不能用軟中斷來實現。但是它們往往又具有可延遲的特性。而且由於是串行執行,因此只要有一個處理時間較長,就會導致其他中斷響應的延遲。為了完成這些不可能的任務,於是出現了工作佇列,它能夠在不同的進程間切換,以完成不同的工作。 ######

  如果推後執行的任務需要睡眠,那麼就選擇工作隊列,如果不需要睡眠,那麼就選擇軟中斷或tasklet。工作佇列能運行在行程上下文,它將工作託付給一個核心執行緒。工作隊列說白了就是一組核心線程,當作中斷守護線程來使用。多個中斷可以放在一個執行緒中,也可以每個中斷分配一個執行緒。我們用結構體workqueue_struct表示工作者線程,工作者線程是用內核線程實現的。而工作者執行緒是如何執行被推後的工作——有這樣一個鍊錶,它由結構體work_struct組成,而這個work_struct則描述了一個工作,一旦這個工作被執行完,對應的work_struct物件就從鍊錶上移去,當鍊錶上不再有物件時,工作者執行緒就會繼續休眠。因為工作隊列是線程,所以我們可以使用所有可以在線程中使用的方法。

Linux軟體中斷和工作佇列的作用是什麼

linux 中的軟中斷和工作佇列的作用是實作中斷處理;它們是中斷上下部機制中的下半部實現機制。

  1.軟體中斷一般是可延遲函數的總稱,它不能睡眠,不能阻塞,它處於中斷上下文,不能進程間切換,軟中斷不能被自己打斷,只能被硬體中斷打斷(上半部),可以並發的運行在多個CPU上。所以軟中斷必須設計成可重入的函數,因此也需要自旋鎖來保護其資料結構。

#  2.

工作佇列中的函數處在進程上下文中,它可以睡眠,也能被阻塞,能夠在不同的進程間切換,以完成不同的工作。

可延遲函數和工作佇列都無法存取使用者的進程空間,可延時函數在執行時不可能有任何正在執行的進程,工作佇列的函數有核心行程執行,他不能存取使用者空間位址。

相關推薦:《###Linux影片教學###》###

以上是linux軟中斷和工作佇列的作用是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

vscode需要什麼電腦配置 vscode需要什麼電腦配置 Apr 15, 2025 pm 09:48 PM

VS Code 系統要求:操作系統:Windows 10 及以上、macOS 10.12 及以上、Linux 發行版處理器:最低 1.6 GHz,推薦 2.0 GHz 及以上內存:最低 512 MB,推薦 4 GB 及以上存儲空間:最低 250 MB,推薦 1 GB 及以上其他要求:穩定網絡連接,Xorg/Wayland(Linux)

Linux體系結構:揭示5個基本組件 Linux體系結構:揭示5個基本組件 Apr 20, 2025 am 12:04 AM

Linux系統的五個基本組件是:1.內核,2.系統庫,3.系統實用程序,4.圖形用戶界面,5.應用程序。內核管理硬件資源,系統庫提供預編譯函數,系統實用程序用於系統管理,GUI提供可視化交互,應用程序利用這些組件實現功能。

vscode終端使用教程 vscode終端使用教程 Apr 15, 2025 pm 10:09 PM

vscode 內置終端是一個開發工具,允許在編輯器內運行命令和腳本,以簡化開發流程。如何使用 vscode 終端:通過快捷鍵 (Ctrl/Cmd ) 打開終端。輸入命令或運行腳本。使用熱鍵 (如 Ctrl L 清除終端)。更改工作目錄 (如 cd 命令)。高級功能包括調試模式、代碼片段自動補全和交互式命令歷史。

git怎麼查看倉庫地址 git怎麼查看倉庫地址 Apr 17, 2025 pm 01:54 PM

要查看 Git 倉庫地址,請執行以下步驟:1. 打開命令行並導航到倉庫目錄;2. 運行 "git remote -v" 命令;3. 查看輸出中的倉庫名稱及其相應的地址。

vscode在哪寫代碼 vscode在哪寫代碼 Apr 15, 2025 pm 09:54 PM

在 Visual Studio Code(VSCode)中編寫代碼簡單易行,只需安裝 VSCode、創建項目、選擇語言、創建文件、編寫代碼、保存並運行即可。 VSCode 的優點包括跨平台、免費開源、強大功能、擴展豐富,以及輕量快速。

notepad怎麼運行java代碼 notepad怎麼運行java代碼 Apr 16, 2025 pm 07:39 PM

雖然 Notepad 無法直接運行 Java 代碼,但可以通過借助其他工具實現:使用命令行編譯器 (javac) 編譯代碼,生成字節碼文件 (filename.class)。使用 Java 解釋器 (java) 解釋字節碼,執行代碼並輸出結果。

Linux的主要目的是什麼? Linux的主要目的是什麼? Apr 16, 2025 am 12:19 AM

Linux的主要用途包括:1.服務器操作系統,2.嵌入式系統,3.桌面操作系統,4.開發和測試環境。 Linux在這些領域表現出色,提供了穩定性、安全性和高效的開發工具。

sublime寫好代碼後如何運行 sublime寫好代碼後如何運行 Apr 16, 2025 am 08:51 AM

在 Sublime 中運行代碼的方法有六種:通過熱鍵、菜單、構建系統、命令行、設置默認構建系統和自定義構建命令,並可通過右鍵單擊項目/文件運行單個文件/項目,構建系統可用性取決於 Sublime Text 的安裝情況。

See all articles