盡對合用!在用戶態把持Open-Channel SSD

尋夢新聞LINE@每日推播熱門推薦文章,趣聞不漏接❤️

加入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所示

盡對合用!在用戶態把持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的地址結構分別是:

盡對合用!在用戶態把持Open-Channel SSD 科技 第2張

盡對合用!在用戶態把持Open-Channel SSD 科技 第3張

  • 設備物理頁地址(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組織數量來確定。

盡對合用!在用戶態把持Open-Channel SSD 科技 第4張

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。

盡對合用!在用戶態把持Open-Channel SSD 科技 第5張

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

About 尋夢園
尋夢園是台灣最大的聊天室及交友社群網站。 致力於發展能夠讓會員們彼此互動、盡情分享自我的平台。 擁有數百間不同的聊天室 ,讓您隨時隨地都能找到志同道合的好友!