blk_mq多隊列塊設備淺析


1. 為什么要使用多隊列

在主機中,多cpu運行多個線程,每個線程都能和文件系統交互,文件系統層也是用多線程和bio層交互,但是,塊設備層只有一個隊列:

在塊設備層,來自多個cpu的bio請求被放在同一個隊列中,造成阻塞:

因此,提出了多隊列的方法,在塊設備層也做成多線程:

但是,在塊設備層實現多個隊列並不能像文件系統一樣考慮,因為塊設備層需要與硬件交互,這需要硬件也支持多隊列,最理想的情況是,硬件支持的隊列足夠多,上層的每個隊列(基於軟件的隊列),都有硬件隊列和其關聯。但有些時候,硬件支持的隊列有限,就形成如上圖的關聯關系:上圖中有3個硬件隊列,但是,上層總共形成了6個隊列(cpu到文件系統到bio層,都是6個基於軟件的隊列),因此,到達塊設備層時,塊設備會將2個基於軟件的隊列和1個硬件隊列關聯起來。

以下是細節圖:

2. 更多信息

在編程中,一般用到的變量名和blk_mq 中各部分的對應關系:

圖源:https://img-blog.csdnimg.cn/20191110221335681.png

圖源:https://img-blog.csdnimg.cn/20191110221243484.png

圖源:https://img-blog.csdnimg.cn/2019111022505564.png

blk_mq 中的 io 流:

塊設備層的io流:

因為來自上層的多個隊列在塊設備層被放在不同的隊列中,一個需要解決的問題是:當塊設備的層提交給下層設備的bio請求完成后,如何從返回的請求(complete IO)中區分其來自塊設備中的哪一個隊列。一種方法是使用IPI(處理器間中斷處理),示意圖如下:

IPI(inter-processorinterrupt)是一種特別的中斷。在對稱多處理器 (SMP)環境下,它可以被任意一個處理器用來對另一個處理器產生中斷。IPIs典型地被用來實現高速緩存間的一致性同步(Cache Coherency Synchronization)

https://blog.csdn.net/xkjcf/article/details/7772849

另一個方法是使用一串數字來標記請求來自哪個隊列,即:硬件從請求中獲得 tag,請求完成后,在返回給 completion IO 池的的請求中也帶上該 tag,示意圖如下:

3. 使用blk_mq的效果

測試 IOPS 的結果:

可以看到,隨着線程的增加,使用 blk_mq 的效果明顯比沒使用blk_mq的單隊列好。

即使在只有一個硬件隊列的情況下,增加塊設備層的隊列也會提升性能:

因為,當塊設備層只有一個隊列的時候,大部分時間都花在獲取設備鎖上面。

相關資料:

Linux NVMe Driver學習筆記大合集: 從NVMe驅動代碼進行理解,有 blk_mq 的部分;

Multi-Queu on block layer in Linux Kernel: 從代碼理解 linux 內核中的 blk_mq 的實現。

參考資料:http://events.static.linuxfound.org/sites/events/files/slides/vault-2016.pdf


免責聲明!

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



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