nvme req的dma映射與提交流程註釋

nvme_queue_rq函數用於提交一個req到nvme submission queue中。

1,nvme_setup_cmd用於構造nvme cmd:

 nvme_setup_rw函數用於設置nvme讀寫命令的基礎字段:

  2,nvme_map_data函數爲req的bio中所有vector建立dma散列表映射

老的磁盤控制器僅僅支持“簡單”的DMA方式:磁盤必須與RAM中連續的內存單元傳送數據。但是新的磁盤控制器支持分散聚集(scatter-gather)DMA方式,磁盤可以與一些非連續的內存區域相互傳送數據。爲了支持分散聚集DMA方式,塊設備驅動程序必須能夠處理稱爲段的數據存儲單元,一次分散聚集DMA可以傳送幾個段(nr_phys_segments),一個段就是一個內存頁或者內存頁的一部分,它們包含磁盤上物理相鄰的數據塊。如果不同的段在RAM中相應的頁框正好是連續的並且在磁盤上相應的數據也是相鄰的,那麼通用塊層就可以進行合併,這種合併方式產生的更大的內存區域就稱爲物理段。當然nvme設置是支持這種DMA傳送方式的。

https://lwn.net/Articles/256368/ 中關於散列表的描述:

Scatter/gather I/O allows the system to perform DMA I/O operations on buffers which are scattered throughout physical memory. Consider, for example, the case of a large (multi-page) buffer created in user space. The application sees a continuous range of virtual addresses, but the physical pages behind those addresses will almost certainly not be adjacent to each other. If that buffer is to be written to a device in a single I/O operation, one of two things must be done: (1) the data must be copied into a physically-contiguous buffer, or (2) the device must be able to work with a list of physical addresses and lengths, grabbing the right amount of data from each segment. Scatter/gather I/O, by eliminating the need to copy data into contiguous buffers, can greatly increase the efficiency of I/O operations while simultaneously getting around the problem that the creation of large, physically-contiguous buffers can be problematic in the first place.

塊設備的request請求中所能攜帶的最大的段數,由下面的函數設置:

blk_rq_map_sq函數是核心的dma映射函數:

散列表sg的結構:

__blk_bvec_map_sq函數用於映射單個bio sector: 

__blk_bios_map_sq函數爲req中每個bio所有的vector創建dma映射:

3,nvme_pci_setup_prps函數設置nvme cmd中prp字段

在設置prp之前,會判斷是用sgl還是prp:

設置prp字段:

 

 4,提交nvme cmd

 寫sq tail doorbell寄存器

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章