local_irq_disable和disable_irq的區別

来源:https://www.cnblogs.com/linhaostudy/archive/2019/03/15/10537054.html
-Advertisement-
Play Games

local_irq_disable: local_irq_disable的功能是屏蔽當前CPU上的所有中斷,通過操作arm核心中的寄存器來屏蔽到達CPU上的中斷,此時中斷控制器中所有送往該CPU上的中斷信號都將被忽略。 disable_irq: 在全局範圍內屏蔽某一個中斷號(irq num)。該ir ...


local_irq_disable:

local_irq_disable的功能是屏蔽當前CPU上的所有中斷,通過操作arm核心中的寄存器來屏蔽到達CPU上的中斷,此時中斷控制器中所有送往該CPU上的中斷信號都將被忽略。

Kernel/arch/arm/include/asm/irqflag.h

static inline void arch_local_irq_disable(void)
{
    asm volatile(
        "   cpsid i         @ arch_local_irq_disable"
        :
        :
        : "memory", "cc");
}

kernel/include/linux/irqflags.h

#define raw_local_irq_disable()     arch_local_irq_disable()

#define local_irq_disable() \
      do { raw_local_irq_disable(); trace_hardirqs_off(); } while (0)

disable_irq:

在全局範圍內屏蔽某一個中斷號(irq num)。該irq num對應的irq handler不會在任何一個CPU上執行。這個操作是通過設置中斷控制器中的寄存器來對指定中斷進行屏蔽,而其他未屏蔽的中斷依然可以正常送往CPU。

413 void disable_irq(unsigned int irq)
 414 {
 415     if (!__disable_irq_nosync(irq))
 416         synchronize_irq(irq);
 417 }

372 static int __disable_irq_nosync(unsigned int irq)
 373 {
 374     unsigned long flags;
 375     struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_     CHECK_GLOBAL);
 376 
 377     if (!desc)
 378         return -EINVAL;
 379     __disable_irq(desc, irq, false);
 380     irq_put_desc_busunlock(desc, flags);
 381     return 0;
 382 }
 383

360 void __disable_irq(struct irq_desc *desc, unsigned int irq, bool suspend)
 361 {
 362     if (suspend) {
 363         if (!desc->action || (desc->action->flags & IRQF_NO_SUSPEND))
 364             return;
 365         desc->istate |= IRQS_SUSPENDED;
 366     }
 367 
 368     if (!desc->depth++)
 369         irq_disable(desc);
 370 }

chip.c

216 void irq_disable(struct irq_desc *desc)
217 {
218     irq_state_set_disabled(desc);
219     if (desc->irq_data.chip->irq_disable) {
220         desc->irq_data.chip->irq_disable(&desc->irq_data);
221         irq_state_set_masked(desc);
222     }
223 }

160 static void irq_state_set_disabled(struct irq_desc *desc)
161 {
162     irqd_set(&desc->irq_data, IRQD_IRQ_DISABLED);
163 }

一個中斷處理的流程是這樣的:

關CPU中斷——–>mask and ack interrupt controller——–>設備驅動中註冊的irq_handler ——>unmask interrupt controller——–>開CPU中斷 

我們需要在irq_handler中做如下處理,其中包含了一個啟動下半部softirq的操作(可選)。

ack device irq——–>copy data to ram——>raise softirq

在代碼中,是這樣的調用流程:

High level irq handler 
–> mask_ack_irq 
–>chip->irq_mask 
–>chip->irq_ack 
–> handle_irq_event (就是調用irq_handler的處理) 
–>chip-> irq_unmask

具體可以參考蝸窩上的文章,對兩種場景有比較詳細的介紹。我們接下來討論電平觸發的場景,來看看如何在所有CPU上進行屏蔽中斷的。其他場景可以舉一反三。

void handle_level_irq(unsigned int irq, struct irq_desc *desc) 
{ 
    raw_spin_lock(&desc->lock); 
    mask_ack_irq(desc); 
    if (unlikely(irqd_irq_inprogress(&desc->irq_data))) 
        if (!irq_check_poll(desc)) 
            goto out_unlock; 
    desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);--和retrigger中斷以及自動探測IRQ相關 
    kstat_incr_irqs_this_cpu(irq, desc); 

    if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) { 
        desc->istate |= IRQS_PENDING; 
        goto out_unlock; 
    } 
    handle_irq_event(desc); 
    cond_unmask_irq(desc); 
out_unlock: 
    raw_spin_unlock(&desc->lock); 
} 

從代碼中可以看到,在函數中首先做的就是mask_ack_irq,在其中會調用chip中的回調來設置硬體。

static inline void mask_ack_irq(struct irq_desc *desc)
 {
     if (desc->irq_data.chip->irq_mask_ack)
         desc->irq_data.chip->irq_mask_ack(&desc->irq_data);
     else {
         desc->irq_data.chip->irq_mask(&desc->irq_data);
         if (desc->irq_data.chip->irq_ack)
             desc->irq_data.chip->irq_ack(&desc->irq_data);
     }
     irq_state_set_masked(desc);
 }

該函數中調用的就是chip中的irq_mask和irq_ack來操作chip中的寄存器.其中的irqd_irq_disabled就是用來判斷該中斷是否被其他CPU給disable了,這裡的disable就是調用disable_irq函數來做的,由此可見,使用disable_irq會在所有的CPU上把中斷號給屏蔽掉。

當在一個CPU上調用了disable_irq的時候,可能另一個CPU已經接收了中斷了,但是在handler的處理中可以看到,它會判斷是否被其它CPU disable了,如果disable了,它會把這個中斷標誌設置為IRQS_PENDING,但並不會去執行irq handler,而是直接退出,此時也沒有調用unmask函數,由此就屏蔽了該中斷,註意這裡的mask和ack只是對於中斷控制器到CPU上的信號進行了屏蔽,而外設到中斷控制器上的中斷信號並沒有消失。

而在使能中斷函數enable_irq中,我們可以看到它會調用unmask來取消該中斷的屏蔽。由於是電平觸發,所以當unmask後,中斷控制器立刻就會感知到外設上的中斷信號。由此進入中斷處理流程。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 集合命名空間: using system.collections. 非泛型集合 using system.collections.Generic. 泛型集合 為什麼要用集合: 1、數組一旦聲明長度就固定了。 2、集合有很多方法可以用 等 常用集合: 類似數組集合:ArrayList List<> 鍵 ...
  • 一.分部視圖 對於MVC 視圖和 Razor Pages 頁面,都有分部視圖功能。通常將 MVC 視圖和 Razor Pages 頁面統稱為“標記文件”,下麵會常提到該名詞。使用分部視圖的優勢包括:(1) 將大型標記文件分解為更小的組件。(2) 減少跨標記文件中,常見標記內容的重覆。 建議:(1)不 ...
  • 1.什麼是Hadoop 管理網路中跨多台電腦存儲的文件系統稱為分散式文件系統面臨的挑戰:使文件系統能容忍節點故障且不丟失任何數據不適合的特點:低時間延遲的數據訪問&大量的小文件&多用戶寫入,任意修改文件 2. HDFS的概念元數據hdfs的目錄結構及每一個文件的塊信息(塊的ID,塊的副本數量,塊的 ...
  • liunx搭建DHCP伺服器以及DHCP中繼伺服器 一、實驗拓撲 二、實驗條件 虛擬機取消VMnet1和VMnet8的dhcp動態獲取ip地址,以免影響實驗 DHCPserver 網關以及DHCP中繼以及linux客戶端清除防火牆策略或者關閉防火牆 iptables -F setenforce 0 ...
  • "Tmux Wiki" "Installation of CentOS7" "Introduction" "Key Bindings" "Configuring ~/.tmux.conf" "References" Tmux Wiki The follow contents is mainly re ...
  • 下載和安裝可以參考,這個鏈接: https://lanseyujie.com/post/matlab-download-and-activate.html 上面這鏈接,在創建桌面快捷鍵時,未能創建,centos要用 yum命令執行。 下載安裝完成後,還需要設置環境變數,才可以在終端中執行matlab ...
  • 前言 Linux上提供了兩款工具用於查找文件,一款是locate,另一款是find。 locate的特點是根據已生成的資料庫查找,速度較快,但是查找的是快照數據,不准確。 因此在日常使用中,為了準確性,使用find的情況比較常見。並且find可自定義查找條件,十分靈活。 locate Linux上有 ...
  • 配置虛擬主機: 從預設的模板文件中複製過來一份進行自己的配置: 將證書上傳到自己的伺服器上可以訪問到的位置, 然後再這個文件裡面填寫自己的證書路徑 編輯好規則以後檢查自己編輯的規則是否有誤: 檢查無誤以後啟用規則: 重啟apache: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...