Linux + arm 內存屏障

ARM 硬件層的屏障指令

  • DMB (Data Memory Barrier):保證在它之前的內存訪問(符合給定域/類型)在它之后的內存訪問之前對可見性排序。常用域:ish(Inner Shareable),sy(system-wide,最強)。

  • DSB (Data Synchronization Barrier):比 DMB 更強,等到之前的訪問“完成”才繼續執行下一條指令;常用于設備寄存器編程后需要確保“已生效”的情景。

  • ISB (Instruction Synchronization Barrier):刷新取指流水,常用于修改系統寄存器后,或自修改代碼等需要讓新指令可見的場景。

  • Acquire/Release 指令(ARMv8):LDAR(獲取/讀-獲取),STLR(釋放/寫-釋放),提供更精細的有序性而不必全棧 DMB

Linux 內核里的內存屏障原語(SMP 語義)

這些在 SMP 有效,在 UP 可能是 no-op(但保持可讀性與可移植性):

  • smp_mb():全柵欄(讀寫都排序)。

  • smp_rmb() / smp_wmb():僅讀-讀/寫-寫排序(以及與相對方向的最小保障,取決于架構實現)。

  • smp_store_release(p, v) / smp_load_acquire(p):推薦!映射到 ARM 的 STLR/LDAR,開銷更低,適合無鎖隊列/環形緩沖區。

  • READ_ONCE(x) / WRITE_ONCE(x, v):防止編譯器優化/拆分訪問,但提供跨 CPU 的排序;常與 acquire/release 或 smp_* 組合用。

  • 原子操作:大多自帶適當的屏障語義(比如 atomic_xxx_return 通常是 full barrier),但具體要看接口文檔;不要想當然。

鎖類原語自帶屏障:

  • spin_lock/unlock:進入/退出臨界區相當于 acquire/release 屏障。

  • mutex_lock/unlockrcu_read_lock/unlock 等也帶有已定義的順序保證。

設備/MMIO 與 I/O 屏障

  • 不要用 *(volatile u32 *)addr = v; 直接訪問 MMIO;統一使用內核提供的 readl/writel(或 ioread32/iowrite32)。

  • readl()/writel():大多數架構上帶必要的 I/O 可見性屏障(比如在 writel() 前插入 wmb() 或在 readl() 后插入 rmb() 等),確保 MMIO 與普通內存的順序。但它們的強度和位置是“架構相關”的。

  • readl_relaxed()/writel_relaxed()省略默認的 I/O 屏障,只做單次 MMIO 訪問。需要你顯式加 mb()/rmb()/wmb() 或專用 I/O 屏障來保證順序。

  • mmiowb():在某些架構/場景下用來約束向不同設備的寫入順序(通常在解鎖自旋鎖后確保批量 MMIO 寫順序對設備可見)。

  • 經驗法則:

    • 如果你對設備寫 doorbell/控制寄存器,且之前更新了普通內存中的描述符/數據:wmb()(或 dma_wmb()),再 writel() doorbell

    • 如果要讀取設備狀態后再讀普通內存里的緩沖區:readl() 取狀態,再 rmb(),再讀內存(或使用配套的 acquire 讀方案)。

DMA 與緩存一致性(非一致平臺尤需注意)

  • 可用 一致性 DMA(coherent)或 非一致性 DMA(streaming)。

  • 非一致性路徑:

    • CPU → 設備(CPU 填好 buffer/描述符):

      • dma_sync_single_for_device(dev, dma_addr, len, DMA_TO_DEVICE)(或在某些輕量場景用 dma_wmb() 之后寫 doorbell)

      • writel() doorbell/啟動寄存器

    • 設備 → CPU(設備寫回數據):

      • 中斷/輪詢得知完成

      • dma_sync_single_for_cpu(dev, dma_addr, len, DMA_FROM_DEVICE)

      • 再讀 buffer(必要時配合 dma_rmb()/rmb()

  • 一致性 DMA路徑(cache 一致):

    • 常用順序:更新內存dma_wmb()writel();讀回數據前 dma_rmb()

  • 簡化口訣:“寫前 wmb,讀后 rmb;doorbell 前 wmb;拿狀態后 rmb。”

常見并發模式示例

生產者(CPU0)/消費者(CPU1)單向通信(無鎖隊列一類)

/* 生產者:先寫數據,再發布索引 */
buf[idx] = data;
smp_store_release(&tail, idx + 1);/* 消費者:先拿到已發布的索引,再讀數據 */
int t = smp_load_acquire(&tail);
if (head < t) {item = buf[head];head++;
}
  • store_release 確保對 buf 的寫在發布 tail 之前對其他 CPU 可見;

  • load_acquire 確保拿到新的 tail 后,再讀 buf 一定能看到對應數據。

中斷上下文與線程上下文

線程設置“已就緒標志”,中斷處理里讀取:

/* 線程上下文 */
WRITE_ONCE(flag, 1);
smp_wmb();          /* 或者把下一條換成 store_release */
writel(START, dev->doorbell);/* 中斷上下文 */
status = readl(dev->status);
smp_rmb();          /* 或 load_acquire 來讀取 flag 等 */
if (READ_ONCE(flag))handle();

更新 MMIO 描述符 + Doorbell

/* 更新環形隊列的描述符(普通內存) */
desc->len = len;
desc->addr = dma_addr;
/* 確保描述符寫入先于設備可見 */
dma_wmb();
/* 通知設備 */
writel(DBELL_KICK, dev->db_reg);
  1. 內存類型與順序直覺

  • Normal(緩存able):ARM 默認弱內存模型,讀寫可能亂序,需要柵欄/acq-rel。

  • Device(nGnRnE / nGnRE / GRE):對同一設備 MMIO 訪問有先后規則,但CPU 對普通內存與 MMIO 的相對順序不一定天然符合你的期望;因此 Linux 以 readl/writel + 柵欄來提供統一模型。

  • 不要volatile 代替屏障;volatile 只約束編譯器,不約束 CPU 重排序。

  1. 該用誰?最簡決策表

目的用法
線程間發布數據smp_store_release / smp_load_acquire
強制完全排序smp_mb()
只約束讀序/寫序smp_rmb() / smp_wmb()
訪問 MMIO(設備寄存器)readl()/writel()(性能敏感才考慮 _relaxed + 顯式屏障)
Doorbell 前確保內存已可見dma_wmb() 或 wmb(),然后 writel()
設備寫回后 CPU 讀緩沖dma_sync_single_for_cpu() 或 dma_rmb()/rmb() 之后再讀
上鎖/解鎖的順序保證spin_lock=acquire,spin_unlock=release
  1. 常見坑

  • 只用 WRITE_ONCE/READ_ONCE沒有配對的 acquire/release 或 smp_mb()——在 ARM 上會出錯。

  • _relaxed 版本的 readl/writel 卻忘記加 mb()/wmb()/rmb()

  • 在非一致性 DMA 平臺忘了 dma_sync_single_for_*,導致讀到臟緩存或設備看不到最新內存。

  • dsb sy 當成“萬金油”濫用,性能大殺器;優先考慮 acquire/release 語義。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/919529.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/919529.shtml
英文地址,請注明出處:http://en.pswp.cn/news/919529.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

網絡安全中的遠程控制活動檢測與防御策略

本文還有配套的精品資源&#xff0c;點擊獲取 簡介&#xff1a;遠程控制技術在IT領域中用于網絡連接和設備操作&#xff0c;但同樣被黑客利用進行非法入侵。端口占用情況是識別遠程控制活動的關鍵因素&#xff0c;使用工具如"cports"可以監控這些端口。系統中未知…

UIGestureRecognizer 各個子類以及其作用

在 iOS 里&#xff0c;UIGestureRecognizer 是一個抽象基類&#xff0c;專門用來處理手勢事件。它本身不能直接用&#xff0c;必須用它的 子類。這些子類分別對應常見的手勢識別器。常見的 UIGestureRecognizer 子類及作用1. UITapGestureRecognizer作用&#xff1a;點擊手勢&a…

計算機網絡 HTTPS 全流程

HTTPS 通信的全流程&#xff08;特別是 TLS 握手階段&#xff09;中使用的三個隨機數是保障安全性的核心設計&#xff0c;不能隨意減少。每個隨機數都承擔著至關重要的安全職責。下面詳細解釋 HTTPS 全流程&#xff0c;并重點分析這三個隨機數的作用和必要性&#xff1a;&#…

DL00271-基于YOLOv11的激光雷達LiDAR船舶目標檢測含完整數據集

【CSDN推薦】基于YOLOv11的激光雷達&#xff08;LiDAR&#xff09;船舶目標檢測——含完整數據集&#xff01;&#x1f6a2; 科研人員必看&#xff01; 高校老師、學生和研究者們&#xff0c;前沿技術來了&#xff01;本論文利用YOLOv11模型&#xff0c;結合激光雷達&#xff0…

SQL-leetcode—3374. 首字母大寫 II

3374. 首字母大寫 II 表&#xff1a;user_content -------------------- | Column Name | Type | -------------------- | content_id | int | | content_text| varchar | -------------------- content_id 是這張表的唯一主鍵。 每一行包含一個不同的 ID 以及對應的文…

告別籠統的 200 OK:一份給 API 設計者的 HTTP 狀態碼終極指南

文章目錄寫在前面問題描述核心結論與建議簡要描述詳細闡述1xx - 信息性響應 (Informational)2xx - 成功 (Successful)3xx - 重定向 (Redirection)4xx - 客戶端錯誤 (Client Error)5xx - 服務器錯誤 (Server Error)HTTP 狀態碼速查表參考以及更多更詳細的狀態碼查詢寫在前面 你…

從防抖節流到鏈表樹:編程世界中的抽象優化藝術

從防抖節流到鏈表樹&#xff1a;編程世界中的抽象優化藝術 在編程的知識體系中&#xff0c;有些概念看似毫不相關&#xff0c;卻在底層邏輯上有著驚人的相似之處。防抖與節流、鏈表與樹&#xff0c;這兩組分屬不同領域的概念&#xff0c;正是這種思維共性的典型代表。它們不僅展…

第三階段數據-3:數據庫腳本生成,備份與還原,分離與附加

1_生成數據庫腳本&#xff08;1&#xff09;在數據庫上右鍵選擇任務&#xff08;2&#xff09;選擇生成腳本&#xff08;3&#xff09;選擇下一步&#xff0c;如果下次不想顯示此頁面&#xff0c;可勾選不再顯示此頁&#xff08;4&#xff09;如果導出全部數據&#xff0c;選擇…

React框架超詳細入門到實戰項目演練【前端】【React】

React框架 1.前端展示解釋 當客戶端訪問服務器時&#xff0c;會從服務器中下載很多靜態文件到本地&#xff0c;比如css、js等前端渲染文件 下載完成之后瀏覽器會將這些文件組合形成前端頁面渲染出來。 2.React概述 React是一個專注于構建用戶界面的JavaScript庫&#xff0c;…

本地部署的終極多面手:Qwen2.5-Omni-3B,視頻剪、音頻混、圖像生、文本寫全搞定

Qwen2.5-Omni-3B是什么&#xff1f; Qwen2.5-Omni-3B 是由阿里巴巴 Qwen 團隊推出的一款輕量級多模態大模型&#xff0c;作為 Qwen2.5-Omni-7B 的高效優化版本&#xff0c;專為消費級硬件環境量身打造。該模型具備處理文本、音頻、圖像和視頻等多種模態輸入的能力&#xff0c;…

連續空間強化學習:策略輸出的兩種形態 —— 概率分布與確定性動作

在強化學習的世界里&#xff0c;智能體與環境的交互核心是 “動作選擇”。當面對離散動作空間&#xff08;如圍棋的落子點、游戲的按鍵操作&#xff09;時&#xff0c;智能體可以直接枚舉或概率選擇有限的動作&#xff1b;但在連續動作空間中&#xff08;如機器人關節角度、無人…

IT運維背鍋權限泄露?集中式管控如何化解風險?

在企業數字化轉型的浪潮中&#xff0c;IT運維團隊常常被推到風口浪尖。員工離職后權限未及時回收、賬號共享導致數據泄露、跨系統權限配置不一致……這些問題一旦暴露&#xff0c;IT運維往往成為“背鍋俠”。權限泄露不僅威脅企業數據安全&#xff0c;還可能導致合規性風險&…

2025 世界機器人大會啟示錄:機構學 × AI × 視頻鏈路的融合之路

引言 2025 年 8 月 8 日&#xff0c;北京再一次成為全球矚目的科技焦點——世界機器人大會盛大開幕。來自全球的 200 余家頂尖企業齊聚一堂&#xff0c;帶來超過 1500 件展品&#xff0c;其中首發新品突破 100 款&#xff0c;涵蓋了從工業制造、醫療康復到服務陪伴、特種作業的…

從零開始部署經典開源項目管理系統最新版redmine6-Linux Debian12

安裝Debian 12 前面為了在windows上好開發&#xff0c;想要在windows上配置開發環境&#xff0c;以源碼方式在本地部署運行&#xff0c;但經過好幾天各種版本切換及配置組件庫等各種操作后&#xff0c;證明windows上搭建redmine6支持的運行環境沒有那么簡單&#xff0c;后續有…

超長視頻生成新突破!LongVie框架問世,創作不再受時長限制

超長視頻生成新突破&#xff01;LongVie框架問世&#xff0c;創作不再受時長限制 文章來源&#xff1a;Poixe AI 在AI技術飛速發展的當下&#xff0c;視頻生成領域取得了令人矚目的進步&#xff0c;尤其是在短視頻創作方面。然而&#xff0c;當視頻時長超過一分鐘時&#xff…

MongoDB 查詢方法與高級查詢表(Python版)

目錄 一、MongoDB3步快速安裝 1.1?下載安裝包 1.2運行安裝程序? 1.3?驗證安裝?打開CMD執行&#xff1a; 1.4 基本查詢操作 二、高級查詢操作符表 2.1 比較操作符 2.2 邏輯操作符 2.3 元素操作符 2.4 數組操作符 三、高級查詢案例 3.1 復雜條件組合 3.2 數組查…

選型指南:如何為企業挑選合適的邊緣計算網關

選型指南&#xff1a;如何為企業挑選合適的邊緣計算網關在企業邁向智能化轉型的道路上&#xff0c;選擇一款合適的物聯網邊緣計算網關至關重要。面對眾多型號和功能各異的網關產品&#xff0c;企業該如何做出正確抉擇呢&#xff1f;?首先要考慮的是網關的兼容性。藍蜂物聯網邊…

HT8693 音頻功率放大器:賦能優質音頻體驗的核心之選

在音頻設備快速迭代的當下&#xff0c;用戶對音質表現、設備穩定性和場景適應性的需求日益提升&#xff0c;一款性能卓越的音頻功率放大器成為連接音源與聽覺享受的關鍵橋梁。HT8693 憑借雙模式切換、強勁輸出、智能保護等核心優勢&#xff0c;為各類音頻設備提供了可靠的性能支…

python+flask后端開發~項目實戰 | 博客問答項目--模塊化文件架構的基礎搭建

項目功能概述&#xff1a; 首頁(公開博客顯示)博客發布與查詢用戶登錄與注冊底層MySQL數據庫的動態響應與支持 簡介&#xff1a;Flask作為Python的一個輕量級Web框架&#xff0c;以其靈活性和可擴展性&#xff0c;贏得了眾多開發者的青睞。從本文開始&#xff0c;你將從0開始…

精品方案 | GCKontrol與OMNeT++聯合仿真在機載網絡性能分析中的應用

概述本文基于GCKontrol搭建了飛行仿真模型&#xff0c;并基于OMNeT搭建了機內網絡系統&#xff0c;實現了不同專業、不同平臺的模型集成與調試。通過這種聯合仿真架構&#xff0c;能夠模擬飛機在不同飛行狀態下的網絡性能&#xff0c;極大提高了性能評估的精度和可靠性。這不僅…