”吐槽“qemu的塊設備驅動


  花點時間來總結一下前陣子的工作。

  qemu的底層塊設備無疑是我所見過的最復雜的模塊了,說得好像我很精通很多模塊一樣(大霧)。

  它的raw鏡像格式文件的驅動的核心代碼主要都是在raw-posix.c文件下面了看看那里的各種API吧哈哈哈。名字也起的特別的顯眼,很容易就讓人清楚那個API究竟是干啥用的。

  目前閱讀代碼所能認知到那群維護者所用到的技術有 異步IO(AIO),多線程,協程(couroutine)。

  對於異步IO的內容,不想在這里說太多,讀者有空可以看看《UNP》卷一,那里有一章節對於各種各樣的IO總結的很棒。

    qemu對於異步IO有兩種的選擇方式,你可以在guest的啟動腳本里對其進行設置,實際上就是aio的選項,aio=native的話,那么你就要為你的linux安裝好libaio庫,這樣子你的linux機器才能跑得動異步io的程序,這樣子qemu才能在塊設備驅動的讀寫當中用到異步IO的接口。如果aio=threads的話,那么qemu就會使用自己創建的線程池來模擬這么一個異步IO。。。哈哈哈真是太吊了。。。這部分的代碼真是神才能寫的出來。。。。那些神究竟要對這些玩意兒腦子里多清楚才能寫得出來啊。。這兩個選擇我們可以在這里看到

  

  CONFIG_LINUX_AIO就是針對於linux本地的aio庫的一個宏,如果沒有定義(host上沒有libaio庫),這段紅色的代碼就會被忽略過去而跑去執行paio_submit,也就是用線程池模擬的異步IO

 

  咱們現在來跳到handle_aiocb_rw這里,這個接口主要就是針對快設備數據((RawPosixAIOData )的讀寫的一個接口,沒錯,qemu就是這么的叼炸天,讀和寫都放在同一個接口里面處理!

  總體來說,qemu貌似很喜歡使用io向量來處理數據(或許效率更高)?媽蛋,那要我們怎么攔截讀寫請求的數據嘛,沒關系,qemu的作者很細心,似乎考慮到總有想我們這一群qemu hacker,也或許是防止qemu的io向量的處理機制出問題了

 /*
   * We have more than one iovec, and all are properly aligned.
   *
   * Try preadv/pwritev first and fall back to linearizing the
   * buffer if it's not supported.
   */

如果處理io向量出問題了,

那么后面就會有相應的處理機制,將所有的io向量對其到一個linear buffer里面

利用這一純天然沒有任何防腐添加劑的方法,我們可以通過這個步驟來講所有的數據轉換成linear buffer形式的,那我們就可以將這些數據進行攔截並扔到緩存里面咯~

很簡單,只要將preadv_present從true改寫成false,那么他就無法正確讀取io向量的數據咯~攔截下來扔到緩存里面就ok了。

  緩存的實現目前還不適合公開,因為性能還遠未達到我們的要求,還在處於不斷地優化調試當中,不過已經可以正常地跑起來了,並且我相信最終會有性能提高的,因為我們現在將線程池里面線程的數目設置為1,原先的是64個線程,主要遇到了多個io線程同步的問題不得不先將線程的數目設置為1。不過這幾個月總算沒有白費,收獲還是不少滴~


免責聲明!

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



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