尋夢新聞LINE@每日推播熱門推薦文章,趣聞不漏接❤️
LightNVM 是Linux 內核中操作Open-Channel SSD的子系統的名稱,並作為實際操作Open-Channel SSD的driver。既然Open-Channel SSD的願景是希望Host是基於實際工作負載的特點,來調配操作盤上NAND資源。那就意味著,開發者需要基於業務需求,靈活做到定制化的FTL。這些定制化的軟件則更有可能會被做到在用戶態,而非內核態。
由此,用戶態定制化FTL需要一套能夠提供操作Open-Channel SSD的API。從名稱可知liblightnvm就是這樣一套在用戶態操作Open-Channel SSD的函數庫。
Liblightnvm 的組成
libIightnvm 提供了Open-Channel SSD與用戶空間交互的方法,和獲取信息的手段。它的組成部分由圖1所示
Figure 1 liblightnvm的組成部分
1. liblightnvm.a與相關頭文件
它的核心是函數庫 liblightnvm.a與相關頭文件 , 其中定義了Open-Channel SSD所需的各種結構,向上提供出封裝好的nvm_dev_XXX和nvm_cmd_XXX系列函數。
- nvm_dev_XXX用於打開、關閉Open-Channel SSD,獲取盤上資源信息,設置相關配置。
- nvm_cmd_XXX用於執行相關的admin命令和IO命令。
為了簡便用戶態應用 操作Open-Channel SSD,函數庫 liblightnvm.a與相關頭文件也包含了基本的輔助功能, nvm_addr_XXX,nvm_buf_XXX,以及nvm_vblk_XXX系列函數。
- nvm_buf_XXX封裝了內存申請、釋放填充等操作。由於liblightnvm的後端對內存類型有不同的需求,使用nvm_buf系列API可以屏蔽掉不同類型內存操作的差異。
- nvm_addr_XXX 包括了很多非常方便的地址轉換結構的方法。Open-Channel 涉及到的地址表示方法主要有4類:NAND成員結構地址(Generic address, gen), 設備物理頁地址 (device physical page address, dev), Chunk信息偏移地址(Chunk information log page offset, lpo), 以及塊設備偏移地址(Linux Block Device offset, off)。
- nvm_vblk_XXX包括了對Virtual Block的定義和操作。
2. liblightnvm的後端nvm_be
Liblightnvm 將具體的執行過程隱藏在不同的後端nvm_be中。當前liblightnvm的nvm_be有多個,nvm_be_ioctl、nvm_be_lbd 和nvm_be_spdk.
- nvm_be_ioctl是使用ioctl系統調用來與kernel內的lightnvm (Open-Channel SSD的內核驅動)交互,操作Open-Channel SSD.
- nvm_be_lbd的admin 命令與nvm_be_ioctl 相同,通過ioctl系統調用做到。但是read/write/earse這些IO命令則是通過操作linux 塊設備做到。
- nvm_be_spdk是通過直接調用SPDK中的nvme driver,完全在用戶態執行的後端。
nvm_be 可以在運行時指定liblightnvm分別為每個nvm_be指定一個Identifier, 在打開nvm_dev時,傳入對應nvm_be的Identifier, 對該nvm_dev的操作就通過該Identifier對應的nvm_be執行。如果是使用幾個liblightnvm 附帶的命令行工具,可以通過環境變量NVM_CLI_BE_ID的值來指定nvm_be.
例如
NVM_CLI_BE_ID=0x2 nvm_dev info /dev/nvme0n1
就會通過nvm_be_lbd後端來執行geometry命令獲取設備信息。
dev_attr:
verid: 0x02
be_id: 0x10
name: ”
path: ”
fd: 0
ssw: 12
mccap: 11111111111111111111111111111110
pmode: ‘SNGL’
erase_naddrs_max: 64
read_naddrs_max: 64
write_naddrs_max: 64
meta_mode: 0
bbts_cached: 0
bbts_cached: 00000000
quirks: 00000000
dev_geo:
verid: 0x02
npugrp: 8
npunit: 8
nchunk: 501
nsectr: 18432
nbytes: 4096
nbytes_oob: 0
tbytes: 2420750942208
tmbytes: 2308608
dev_ppaf: ~
dev_ppaf_mask: ~
dev_lbaf:
pugrp: 3
punit: 3
chunk: 9
sectr: 15
dev_lbaz:
pugrp: 27
punit: 24
chunk: 15
sectr: 0
dev_lbam:
pugrp: ‘0000000000000000000000000000000000111000000000000000000000000000’
punit: ‘0000000000000000000000000000000000000111000000000000000000000000’
chunk: ‘0000000000000000000000000000000000000000111111111000000000000000’
sectr: ‘0000000000000000000000000000000000000000000000000111111111111111’
3.命令行工具
為了方便用戶評估和調試Open-Channel SSD,liblightnvm的源代碼中還附帶了幾個命令行工具。這些工具也同時作為示例,展示了liblightnvm API的使用方法。
- nvm_dev 命令可以獲得當前系統上所有的Open-Channel SSD, 也可以獲取某個SSD的Geometry信息。
- num_addr命令可以靈活的計算Open-Channel SSD涉及的各種不同的地址格式。
- nvm_cmd 命令可以直接在某個Open-Channel SSD上執行admin 或者IO 命令。
- nvm_vblk 命令可以以Virtual Block 為基本單位做read/write/erase等IO 操作。作為對nvm_cmd命令的補充,它在操作Virtual Block時省去了nvm_cmd繁瑣的步驟。
- nvm_bbt命令只能用在支持Open-Channel Spec 1.2的設備。bbt, 即 bad block table,在Spec 1.2中起到了類似 Spec 2.0中chunk information的作用。
4.異步調用
為了提高liblightnvm對用戶態應用的可用性,目前liblightnvm中加入幾個簡單的異步調API. 它們的名稱和作用分別是:
struct nvm_async_ctx
異步調用上下文
nvm_async_init
建立異步調用環境
nvm_async_term
清除異步調用環境
nvm_async_poke
查看是否有異步請求完成,並立即返回
nvm_async_wait
阻塞直至所有異步請求完成
nvm_async_get_depth
獲取異步調用上下文IO隊列深度
nvm_async_get_outstanding
獲取當前未完成的異步請求數量
nvm_cmd_<IO operation> with NVM_CMD_ASYNC flag
提交異步調用
Liblightnvm中需要區別的概念
1.多樣的地址表示
- NAND成員結構地址(gen addr)是一個結構體,結構體表示了SSD的NAND物理結構。比如,Open-Chanel Spec 1.2 和Spec 2.0的地址結構分別是:
- 設備物理頁地址(dev addr)是一個64位的無符號整數。 這個地址類型與PPA(Physical Page Address)對應。上面在介紹NAND成員地址中,每個成員的長度,由liblightnvm默認定義, 但是在Open-Channel SSD上,實際的長度格式由固件上定義,並通過Geometry 命令來獲取。所以該地址類型的具體值由gen地址和固件長度格式共同決定。比如, 對一個Spec 2.0的gen地址:
gen addr: { pugrp: 04, punit: 02, chunk: 0142, sectr: 0000 }
它直接對應的16進制整數值為 :
0x0402008e00000000
若某個SSD的固件長度格式是:
dev_lbaf: {pugrp: 3, punit: 3, chunk: 9, sectr: 15}
則,上述gen addr 對應的dev addr的二進制為:
100 010 010001110 000000000000000B,
即0010 0010 0100 0111 0000 0000 0000 0000B
十六進制值為:
0x22470000.
Dev addr 即對應了設備的PPA,Open-Channel SSD 的所有IO命令都需要使用它。
- 塊設備偏移地址(off addr),即為以字節為單位偏移的地址。其值為dev addr 左移到頁大小。比如如果SSD的頁大小為4KB(212B),則off addr 為 dev addr 左移12位。
- Chunk信息偏移地址(lpo addr),主要用在Spec 2.0中,當要獲取chunk信息時,需要指定對應的lpo。由於Chunk 信息按照Chunk位置順序排列,中間沒有地址空洞,所以某個chunk信息的位置是無法通過dev addr或gen addr指定,必須通過gen addr 與SSD上各種NAND組織數量來確定。
Figure 2 Chunk Information的布局圖
2.何為Virtual Block
Block 是一個相當魔幻的詞。通常存儲里面講一個Block,是指一個邏輯塊,塊存儲的最小操作單位。但在NAND的相關術語中,Block通常指擦除單位,而讀寫的單位常是Page或Sector,一個NAND Block由大量的NAND Page組成。Open-Channel Spec 1.2里面,Block的含義遵從NAND術語,代表擦除單位NAND Block。到了Open-Channel Spec 2.0,為了避免Block混淆,用Chunk代替Block來表示擦除單位。Liblightnvm為了保持命名的連貫統一,函數,參數,及結構成員名稱依舊保持Block 或blk。
Figure 3 one Virtual Block in Open-Channel SSD
說回到Virtual Block, 它是一組NAND 擦除單位Block的集合。如圖3,為了獲得高讀寫IOPS或吞吐量,其中的每個Block都分布在不同的Channel和LUN中,使得一個讀寫請求可以有機會並行地在各個Block上同時執行。例如,寫一個Block的Throughput 是 200MB/s, 寫一個由8個Block組成的Virtual Block 的Throughput則是1600MB/s。為了簡化對組成Virtual Block中Block的記錄維護,常常默認每個Block在各自的LUN中有著同樣的offset。定制化的FTL,明智的選擇都是以Virtual Block整體來作IO操作。
References
[1] Open-Channel Solid State Drives Specification Revision 1.2
[2] Open-Channel Solid State Drives Specification Revision 2.0
[3] Lightnvm: The Linux Open-Channel SSD subsystem.
[4] https://github.com/OpenChannelSSD/liblightnvm/
[5] http://lightnvm.io
www.ssdfans.com