CentOS7上でSPDKをビルドして、NVMe-oF(NVMe over Fabric) targetを構築しました。
1.環境
1-1.筐体1 NVMe over Fabric Target
筐体 : ProLiant DL360p Gen8 System ROM : P71 01/22/2018 NIC : Mellanox ConnectX-3pro MCX311A-XCCT SSD : Samsung SSD 250GB 970 EVO M.2 Type2280 PCIe3.0×4 NVMe1.3 Adapter : GLOTRENDS M.2 PCIe NVMe or PCIe AHCI SSD to PCIe 3.0 x4 Adapter Card OS : CentOS7.5(1804) Kernel : 4.18.4-1.el7.elrepo.x86_64 Installed Environment Groups : Minimal Install SPDK : v18.10-pre DPDK : v18.05.0
1-2.筐体2 NVMe over Fabric Initiator
筐体 : ProLiant DL360p Gen8 System ROM : P71 01/22/2018 NIC : Mellanox ConnectX-3pro MCX311A-XCCT OS : CentOS7.5(1804) Kernel : 4.18.4-1.el7.elrepo.x86_64 Installed Environment Groups : Minimal Install
1-3.全体の構成
RoCEv2のフレームをPcapしたかったためTargetとInitiatorの間にスイッチを挟んでいますが、DAS(直結)構成でも大丈夫です。
1-4.全体の流れ
Kernelのアップグレード
事前準備
SPDKのビルド
SPDKのnvmf.conf設定
NVMe-oF Initiatorからのアクセス
2.Kernelのアップグレード
今回の構成ではRoCEv2を使用します。
RoCEv2を使用する場合、Kernel4.5以上でないとサポートされないため、ELRepoから最新のKernelにアップグレードします。
この作業はTargetおよびInitiatorの両方で行ってください。
2-1.リポジトリの登録
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
GPG-KeyとELRepoの登録を実施。
# yum list installed | grep kernel kernel.x86_64 3.10.0-862.el7 @anaconda kernel-tools.x86_64 3.10.0-862.el7 @anaconda kernel-tools-libs.x86_64 3.10.0-862.el7 @anaconda
現在インストールされているKernelのバージョンを確認
2-2.Kernelのアップグレード
yum --enablerepo=elrepo-kernel install kernel-ml
最新Kernelのインストール*1
# awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg 0 : CentOS Linux (4.18.4-1.el7.elrepo.x86_64) 7 (Core) 1 : CentOS Linux (3.10.0-862.el7.x86_64) 7 (Core) 2 : CentOS Linux (0-rescue-626b869879714a9cbe128e5b6f85dd89) 7 (Core) # grub2-set-default 0 # grub2-mkconfig -o /boot/grub2/grub.cfg Generating grub configuration file ... Found linux image: /boot/vmlinuz-4.18.4-1.el7.elrepo.x86_64 Found initrd image: /boot/initramfs-4.18.4-1.el7.elrepo.x86_64.img Found linux image: /boot/vmlinuz-3.10.0-862.el7.x86_64 Found initrd image: /boot/initramfs-3.10.0-862.el7.x86_64.img Found linux image: /boot/vmlinuz-0-rescue-626b869879714a9cbe128e5b6f85dd89 Found initrd image: /boot/initramfs-0-rescue-626b869879714a9cbe128e5b6f85dd89.img done # reboot
menuentryを確認
初期起動Kernelに4.18.4-1.el7.elrepo.x86_64を選択
grub.cfgへの反映
再起動
なお、Initiatorはここまでで完了です。
Targetはspdkのビルドを行うため、この後のkernel-ml-develやkernel-ml-headersのインストールも行ってください。
2-3.既存Kernel削除とその他のアップグレード
uname -r yum remove kernel yum list installed | grep kernel yum -y update kernel-tools-libs kernel-tools yum list installed | grep kernel
起動Kernelのバージョン確認
既存Kernelの削除
現在インストールされているKernel関連のパッケージの確認
tools類のアップデート*2
現在インストールされているKernel関連のパッケージの再確認
2-4.elrepo-kernelの常時有効化
vi /etc/yum.repos.d/elrepo.repo [elrepo-kernel] name=ELRepo.org Community Enterprise Linux Kernel Repository - el7 baseurl=http://elrepo.org/linux/kernel/el7/$basearch/ http://mirrors.coreix.net/elrepo/kernel/el7/$basearch/ http://mirror.rackspace.com/elrepo/kernel/el7/$basearch/ http://repos.lax-noc.com/elrepo/kernel/el7/$basearch/ http://mirror.ventraip.net.au/elrepo/kernel/el7/$basearch/ mirrorlist=http://mirrors.elrepo.org/mirrors-elrepo-kernel.el7 enabled=1 #0→1に修正 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-elrepo.org protect=0
2-5.tools類のアップグレードとdevel&headersのインストール
yum swap kernel-tools-libs kernel-tools -- kernel-ml-tools-libs kernel-ml-tools yum -y install kernel-ml-devel kernel-ml-headers yum list installed | grep kernel
kernel-*とkernel-ml-*のswap
kernel-ml-develとkernel-ml-headersのインストール
現在インストールされているKernel関連のパッケージの確認
# yum list installed | grep kernel kernel-ml.x86_64 4.18.4-1.el7.elrepo @elrepo-kernel kernel-ml-devel.x86_64 4.18.4-1.el7.elrepo @elrepo-kernel kernel-ml-headers.x86_64 4.18.4-1.el7.elrepo @elrepo-kernel kernel-ml-tools.x86_64 4.18.4-1.el7.elrepo @elrepo-kernel kernel-ml-tools-libs.x86_64 4.18.4-1.el7.elrepo @elrepo-kernel
上記のような出力になっていれば完了です。
3.事前準備
3-1.セキュリティ設定の無効化
firewalldとSELinuxを無効化します。
systemctl disable firewalld vi /etc/selinux/config で開いて SELINUX=disabled にして保存。
3-2.grubの設定
grubにHugePageの設定追加
vi /etc/default/grub GRUB_CMDLINE_LINUX=の行末に追加 default_hugepagesz=1G hugepagesz=1G hugepages=8 保存後、grubに反映 grub2-mkconfig -o /etc/grub2.cfg
3-3.NICのIPアドレス設定
nmcli devなどでMellanox製NICのデバイス名を確認の上、IPアドレスを設定してください。今回構築するNVMe-oF targetはRoCEv2で動作するため、NICにはIPアドレスが必要となります。
nmcli connection add type ethernet autoconnect yes con-name ens1 ifname ens1 nmcli connection modify ens1 ipv4.method manual ipv4.addresses 192.168.20.200/24 nmcli connection up ens1
4.SPDKのビルド
4-1.gitインストールからspdkのビルドまで
以下を流し込んでください。
yum -y install git && \ cd /usr/src && \ git clone https://github.com/spdk/spdk && \ cd spdk && \ git submodule update --init && \ scripts/pkgdep.sh && \ ./configure --with-rdma --enable-debug && \ make
gitインストール
/usr/srcにcd
spdkのソースをgitから取得
/usr/src/spdkにcd*3
アップデート
必要なパッケージのインストール
makeファイル生成
ビルド
iSCSI Targetと異なる点
--with-rdmaは必須となります。
また、nvmf_tgtを起動した際に「-L」オプションでDebugログが見れるようになるため、--enable-debugを追加しています。正常起動しているのか?固まっているのか?を見極めるためにも、あった方がいいかなと思います。
4-2.unittest.shの実行
ビルドが完了したら、最後に各モジュールのテストを実施してみてください。
./test/unit/unittest.sh 出力結果省略 ===================== All unit tests passed ===================== WARN: lcov not installed or SPDK built without coverage! WARN: neither valgrind nor ASAN is enabled!
多数の出力結果が表示されますが、最後に「All unit tests passed」と表示されればOKです。
Warringが2件表示されてますが、気にせず先に進んでください。
5.spdkのnvmf.confファイル設定
5-1.設定ファイルの作成
# cd /usr/src/spdk/app/nvmf_tgt # vi nvmf.conf [Global] ReactorMask 0x0F [Nvmf] MaxQueuesPerSession 4 MaxQueueDepth 1024 AcceptorPollRate 10000 [Nvme] TransportId "trtype:PCIe traddr:0000:04:00.0" Nvme0 RetryCount 4 TimeoutUsec 1 ActionOnTimeout None AdminPollRate 100000 HotplugEnable No [Subsystem1] NQN nqn.2016-06.io.spdk:cnode1 Listen RDMA 192.168.20.200:4791 AllowAnyHost Yes Host nqn.2016-06.io.spdk:init SN SPDK00000000000001 Namespace Nvme0n1 1
ReactorMaskの掛け方は最後に詳細を記載したいと思います。
わからなければ、コメントアウトしても問題ありません。
TransportIdの確認方法
私の場合、Samsung SSD 250GB 970を使用したため、lspciで以下のようにgrepしました。
# lspci |grep Samsung 04:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd Device a808
SSDのbsf(bus slot function)番号が判明したら、頭にDomain番号「0000:」を付けてください。
サンプルconfがspdk/etc/spdk/nvmf.conf.inにあるので、これをコピーしてnvmf.confを作成してもよいと思います。
5-2.setup.shの起動
カーネル上での制御からSPDK(正確にはDPDK)上での制御に移行します。
ますはステータス確認から。
# cd /usr/src/spdk # scripts/setup.sh status Hugepages node hugesize free / total node0 1048576kB 8 / 8 node1 1048576kB 8 / 8 NVMe devices BDF Numa Node Driver name Device name 0000:03:00.0 0 nvme nvme0 I/OAT DMA BDF Numa Node Driver Name 0000:00:04.0 0 ioatdma 0000:20:04.0 1 ioatdma 0000:00:04.1 0 ioatdma 0000:20:04.1 1 ioatdma 0000:00:04.2 0 ioatdma 0000:20:04.2 1 ioatdma 0000:00:04.3 0 ioatdma 0000:20:04.3 1 ioatdma 0000:00:04.4 0 ioatdma 0000:20:04.4 1 ioatdma 0000:00:04.5 0 ioatdma 0000:20:04.5 1 ioatdma 0000:00:04.6 0 ioatdma 0000:20:04.6 1 ioatdma 0000:00:04.7 0 ioatdma 0000:20:04.7 1 ioatdma virtio BDF Numa Node Driver Name Device Name
現在はカーネル上のnvmeやioatdmaドライバで制御していることがわかります。
オプション無しでsetup.shを実行すると、uio_pci_genericに移行します。*4
# scripts/setup.sh 0000:03:00.0 (144d a808): nvme -> uio_pci_generic 0000:00:04.0 (8086 3c20): ioatdma -> uio_pci_generic 0000:20:04.0 (8086 3c20): ioatdma -> uio_pci_generic 0000:00:04.1 (8086 3c21): ioatdma -> uio_pci_generic 0000:20:04.1 (8086 3c21): ioatdma -> uio_pci_generic 0000:00:04.2 (8086 3c22): ioatdma -> uio_pci_generic 0000:20:04.2 (8086 3c22): ioatdma -> uio_pci_generic 0000:00:04.3 (8086 3c23): ioatdma -> uio_pci_generic 0000:20:04.3 (8086 3c23): ioatdma -> uio_pci_generic 0000:00:04.4 (8086 3c24): ioatdma -> uio_pci_generic 0000:20:04.4 (8086 3c24): ioatdma -> uio_pci_generic 0000:00:04.5 (8086 3c25): ioatdma -> uio_pci_generic 0000:20:04.5 (8086 3c25): ioatdma -> uio_pci_generic 0000:00:04.6 (8086 3c26): ioatdma -> uio_pci_generic 0000:20:04.6 (8086 3c26): ioatdma -> uio_pci_generic 0000:00:04.7 (8086 3c27): ioatdma -> uio_pci_generic 0000:20:04.7 (8086 3c27): ioatdma -> uio_pci_generic
以下のようになっていれば、OKです。
# scripts/setup.sh status Hugepages node hugesize free / total node0 1048576kB 0 / 1 node1 1048576kB 0 / 1 NVMe devices BDF Numa Node Driver name Device name 0000:03:00.0 0 uio_pci_generic - I/OAT DMA BDF Numa Node Driver Name 0000:00:04.0 0 uio_pci_generic 0000:20:04.0 1 uio_pci_generic 0000:00:04.1 0 uio_pci_generic 0000:20:04.1 1 uio_pci_generic 0000:00:04.2 0 uio_pci_generic 0000:20:04.2 1 uio_pci_generic 0000:00:04.3 0 uio_pci_generic 0000:20:04.3 1 uio_pci_generic 0000:00:04.4 0 uio_pci_generic 0000:20:04.4 1 uio_pci_generic 0000:00:04.5 0 uio_pci_generic 0000:20:04.5 1 uio_pci_generic 0000:00:04.6 0 uio_pci_generic 0000:20:04.6 1 uio_pci_generic 0000:00:04.7 0 uio_pci_generic 0000:20:04.7 1 uio_pci_generic virtio BDF Numa Node Driver Name Device Name
5-3.Targetプログラムの実行
/usr/src/spdkのパス上で以下を実行。
app/nvmf_tgt/nvmf_tgt -c app/nvmf_tgt/nvmf.conf 以下、出力結果。 # app/nvmf_tgt/nvmf_tgt -c app/nvmf_tgt/nvmf.conf Starting SPDK v18.07-pre / DPDK 18.02.0 initialization... [ DPDK EAL parameters: nvmf -c 0x0F --file-prefix=spdk_pid23820 ] EAL: Detected 8 lcore(s) EAL: Multi-process socket /var/run/.spdk_pid23820_unix EAL: Probing VFIO support... app.c: 530:spdk_app_start: *NOTICE*: Total cores available: 4 reactor.c: 718:spdk_reactors_init: *NOTICE*: Occupied cpu socket mask is 0x1 reactor.c: 492:_spdk_reactor_run: *NOTICE*: Reactor started on core 1 on socket 0 reactor.c: 492:_spdk_reactor_run: *NOTICE*: Reactor started on core 2 on socket 0 reactor.c: 492:_spdk_reactor_run: *NOTICE*: Reactor started on core 3 on socket 0 reactor.c: 492:_spdk_reactor_run: *NOTICE*: Reactor started on core 0 on socket 0 EAL: PCI device 0000:03:00.0 on NUMA socket 0 EAL: probe driver: 144d:a808 spdk_nvme rdma.c:1454:spdk_nvmf_rdma_create: *ERROR*: rdma_create_event_channel() failed, No such device Segmentation fault (core dumped)
初回起動時に赤文字のエラーを吐く場合は、一度サーバを再起動してみてください。
nvmf_tgtはフォアグラウンドで稼働してしまうため、上記出力(赤文字以外の出力)でプロンプトが停止したように見えますが、nvmf targetは正常に起動できています。
iscsi targetとは異なり、-b(バックグラウンド)オプションはないようです。
また、Debugオプションを使用したい場合、まずは-Lに指定可能な引数を確認するため、-hオプションでnvmf_tgtを起動してあげてください。
# app/nvmf_tgt/nvmf_tgt -h app/nvmf_tgt/nvmf_tgt [options] options: -c config config file (default /usr/local/etc/nvmf/nvmf.conf) -d disable coredump file enabling -e mask tracepoint group mask for spdk trace buffers (default 0x0) -g force creating just one hugetlbfs file -h show this usage -i shared memory ID (optional) -m mask core mask for DPDK -n channel number of memory channels used for DPDK -p core master (primary) core for DPDK -q disable notice level logging to stderr -r RPC listen address (default /var/tmp/spdk.sock) -s size memory size in MB for DPDK (default: all hugepage memory) -u disable PCI access. -w wait for RPCs to initialize subsystems -B addr pci addr to blacklist -R unlink huge files after initialization -W addr pci addr to whitelist (-B and -W cannot be used at the same time) -L flag enable debug log flag (all, aio, bdev, bdev_malloc, bdev_null, bdev_nvme, blob, blob_rw, copy_ioat, gpt_parse, ioat, log, lvol, lvolrpc, nbd, nvme, nvmf, rdma, reactor, rpc, vbdev_gpt, vbdev_lvol, vbdev_passthru, vbdev_split, virtio, virtio_blk, virtio_dev, virtio_pci, virtio_user)
実際にDebugオプションを付けて起動した場合は、こんな感じです。
このように起動した後、Initiatorからアクセスすると、Targetの動きがわかります。
# app/nvmf_tgt/nvmf_tgt -L nvme -L nvmf -L rdma -c app/nvmf_tgt/nvmf.conf
6.NVMe-oF Initiatorからのアクセス
6-1.Initiator側の事前準備
Initiatorのインストール
yum -y install nvme-cli
modprobe実施
modprobe ib_core modprobe ib_umad modprobe ib_uverbs modprobe iw_cm modprobe rdma_cm modprobe rdma_ucm modprobe mlx4_core modprobe mlx4_ib modprobe nvme_rdma
上記のmodprobeが正常終了していれば、以下のように/dev/nvme-fabricsが追加されているハズです。
# ls /dev/ autofs fuse net rtc tty13 tty30 tty48 tty8 vcs6 block hpet network_latency rtc0 tty14 tty31 tty49 tty9 vcsa bsg hpilo network_throughput sda tty15 tty32 tty5 ttyS0 vcsa1 btrfs-control hugepages null sda1 tty16 tty33 tty50 ttyS1 vcsa2 bus hwrng nvme-fabrics sda2 tty17 tty34 tty51 ttyS2 vcsa3 centos infiniband nvram sg0 tty18 tty35 tty52 ttyS3 vcsa4 char initctl port sg1 tty19 tty36 tty53 uhid vcsa5 console input ppp shm tty2 tty37 tty54 uinput vcsa6 core ipmi0 ptmx snapshot tty20 tty38 tty55 urandom vfio cpu kmsg ptp0 snd tty21 tty39 tty56 usbmon0 vga_arbiter cpu_dma_latency kvm ptp1 stderr tty22 tty4 tty57 usbmon1 vhci cuse lightnvm ptp2 stdin tty23 tty40 tty58 usbmon2 vhost-net disk log ptp3 stdout tty24 tty41 tty59 usbmon3 vhost-vsock dm-0 loop-control ptp4 tty tty25 tty42 tty6 vcs watchdog dm-1 mapper ptp5 tty0 tty26 tty43 tty60 vcs1 watchdog0 dri mcelog ptp6 tty1 tty27 tty44 tty61 vcs2 zero fb0 mem pts tty10 tty28 tty45 tty62 vcs3 fd memory_bandwidth random tty11 tty29 tty46 tty63 vcs4 full mqueue raw tty12 tty3 tty47 tty7 vcs5
Discover実施Initiator側
# nvme discover -t rdma -a 192.168.20.200 -s 4791 Discovery Log Number of Records 1, Generation counter 4 =====Discovery Log Entry 0====== trtype: rdma adrfam: ipv4 subtype: nvme subsystem treq: not specified portid: 0 trsvcid: 4791 subnqn: nqn.2016-06.io.spdk:cnode1 traddr: 192.168.20.200 rdma_prtype: not specified rdma_qptype: connected rdma_cms: rdma-cm rdma_pkey: 0x0000
Discover実施Target側
# app/nvmf_tgt/nvmf_tgt -L nvmf -c app/nvmf_tgt/nvmf.conf request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x01 cid 1 request.c: 136:nvmf_trace_command: *INFO*: SGL: Keyed (Inv): addr 0xbeee9c800 key 0x10110 len 0x400 ctrlr.c: 321:spdk_nvmf_ctrlr_connect: *INFO*: recfmt 0x0 qid 0 sqsize 31 ctrlr.c: 323:spdk_nvmf_ctrlr_connect: *INFO*: Connect data: ctrlr.c: 324:spdk_nvmf_ctrlr_connect: *INFO*: cntlid: 0xffff ctrlr.c: 332:spdk_nvmf_ctrlr_connect: *INFO*: hostid: 0259e14b-3479-4850-be97-f6006ffa084c *** ctrlr.c: 349:spdk_nvmf_ctrlr_connect: *INFO*: subnqn: "nqn.2014-08.org.nvmexpress.discovery" ctrlr.c: 366:spdk_nvmf_ctrlr_connect: *INFO*: hostnqn: "nqn.2014-08.org.nvmexpress:uuid:eb63ddbc-c01f-4435-8e0b-bbbaf22639f2" ctrlr.c: 389:spdk_nvmf_ctrlr_connect: *INFO*: Connect Admin Queue for controller ID 0xffff ctrlr.c: 207:spdk_nvmf_ctrlr_create: *INFO*: cap 0x20010103ff ctrlr.c: 208:spdk_nvmf_ctrlr_create: *INFO*: vs 0x10300 ctrlr.c: 209:spdk_nvmf_ctrlr_create: *INFO*: cc 0x0 ctrlr.c: 210:spdk_nvmf_ctrlr_create: *INFO*: csts 0x0 ctrlr.c: 104:ctrlr_add_qpair_and_update_rsp: *INFO*: connect capsule response: cntlid = 0x0001 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=1 cdw0=0x00000001 rsvd1=0 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x04 cid 26 ctrlr.c: 557:spdk_nvmf_property_get: *INFO*: size 1, offset 0x0 ctrlr.c: 573:spdk_nvmf_property_get: *INFO*: name: cap ctrlr.c: 583:spdk_nvmf_property_get: *INFO*: response value: 0x20010103ff request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x010103ff rsvd1=32 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x00 cid 26 ctrlr.c: 598:spdk_nvmf_property_set: *INFO*: size 0, offset 0x14, value 0x460001 ctrlr.c: 608:spdk_nvmf_property_set: *INFO*: name: cc ctrlr.c: 438:nvmf_prop_set_cc: *INFO*: cur CC: 0x00000000 ctrlr.c: 439:nvmf_prop_set_cc: *INFO*: new CC: 0x00460001 ctrlr.c: 449:nvmf_prop_set_cc: *INFO*: Property Set CC Enable! ctrlr.c: 480:nvmf_prop_set_cc: *INFO*: Prop Set IOSQES = 6 (64 bytes) ctrlr.c: 487:nvmf_prop_set_cc: *INFO*: Prop Set IOCQES = 4 (16 bytes) request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x00000000 rsvd1=0 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x04 cid 26 ctrlr.c: 557:spdk_nvmf_property_get: *INFO*: size 0, offset 0x1c ctrlr.c: 573:spdk_nvmf_property_get: *INFO*: name: csts ctrlr.c: 583:spdk_nvmf_property_get: *INFO*: response value: 0x1 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x00000001 rsvd1=0 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x04 cid 26 ctrlr.c: 557:spdk_nvmf_property_get: *INFO*: size 0, offset 0x8 ctrlr.c: 573:spdk_nvmf_property_get: *INFO*: name: vs ctrlr.c: 583:spdk_nvmf_property_get: *INFO*: response value: 0x10300 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x00010300 rsvd1=0 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x04 cid 26 ctrlr.c: 557:spdk_nvmf_property_get: *INFO*: size 1, offset 0x0 ctrlr.c: 573:spdk_nvmf_property_get: *INFO*: name: cap ctrlr.c: 583:spdk_nvmf_property_get: *INFO*: response value: 0x20010103ff request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x010103ff rsvd1=32 status=0x0000 request.c: 121:nvmf_trace_command: *INFO*: Admin cmd: opc 0x06 fuse 0 cid 26 nsid 0 cdw10 0x00000001 request.c: 136:nvmf_trace_command: *INFO*: SGL: Keyed (Inv): addr 0xc026a1000 key 0x10111 len 0x1000 ctrlr.c:1172:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ctrlr data: maxcmd 0x400 ctrlr.c:1173:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: sgls data: 0x100005 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x00000000 rsvd1=0 status=0x0000 request.c: 121:nvmf_trace_command: *INFO*: Admin cmd: opc 0x02 fuse 0 cid 26 nsid 0 cdw10 0x00030070 request.c: 136:nvmf_trace_command: *INFO*: SGL: Keyed (Inv): addr 0xc09c46000 key 0x10112 len 0x10 ctrlr.c:1082:spdk_nvmf_ctrlr_get_log_page: *INFO*: Get log page: LID=0x70 offset=0x0 len=0x10 ctrlr_discovery.c: 63:nvmf_update_discovery_log: *INFO*: Generating log page for genctr 4 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x00000000 rsvd1=0 status=0x0000 request.c: 121:nvmf_trace_command: *INFO*: Admin cmd: opc 0x02 fuse 0 cid 26 nsid 0 cdw10 0x01ff0070 request.c: 136:nvmf_trace_command: *INFO*: SGL: Keyed (Inv): addr 0xbdc640000 key 0x10113 len 0x800 ctrlr.c:1082:spdk_nvmf_ctrlr_get_log_page: *INFO*: Get log page: LID=0x70 offset=0x0 len=0x800 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x00000000 rsvd1=0 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x00 cid 8 ctrlr.c: 598:spdk_nvmf_property_set: *INFO*: size 0, offset 0x14, value 0x464001 ctrlr.c: 608:spdk_nvmf_property_set: *INFO*: name: cc ctrlr.c: 438:nvmf_prop_set_cc: *INFO*: cur CC: 0x00460001 ctrlr.c: 439:nvmf_prop_set_cc: *INFO*: new CC: 0x00464001 ctrlr.c: 463:nvmf_prop_set_cc: *INFO*: Property Set CC Shutdown 01b! request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=8 cdw0=0x00000000 rsvd1=0 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x04 cid 8 ctrlr.c: 557:spdk_nvmf_property_get: *INFO*: size 0, offset 0x1c ctrlr.c: 573:spdk_nvmf_property_get: *INFO*: name: csts ctrlr.c: 583:spdk_nvmf_property_get: *INFO*: response value: 0x8 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=8 cdw0=0x00000008 rsvd1=0 status=0x0000
Connect実施Initiator側
iSCSIのときとは違い、Successなどは出力されません。
# nvme connect -t rdma -n nqn.2016-06.io.spdk:cnode1 -a 192.168.20.200 -s 4791
Connect実施Target側
Connectが完了すると、定期的にKeepaliveメッセージが流れます。
# nvme connect -t rdma -n nqn.2016-06.io.spdk:cnode1 -a 192.168.20.200 -s 4791 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x01 cid 0 request.c: 136:nvmf_trace_command: *INFO*: SGL: Keyed (Inv): addr 0xbeee99000 key 0x10111 len 0x400 ctrlr.c: 321:spdk_nvmf_ctrlr_connect: *INFO*: recfmt 0x0 qid 0 sqsize 31 ctrlr.c: 323:spdk_nvmf_ctrlr_connect: *INFO*: Connect data: ctrlr.c: 324:spdk_nvmf_ctrlr_connect: *INFO*: cntlid: 0xffff ctrlr.c: 332:spdk_nvmf_ctrlr_connect: *INFO*: hostid: 07ca1c45-8f62-493f-a732-7fd3c721f6f9 *** ctrlr.c: 349:spdk_nvmf_ctrlr_connect: *INFO*: subnqn: "nqn.2016-06.io.spdk:cnode1" ctrlr.c: 366:spdk_nvmf_ctrlr_connect: *INFO*: hostnqn: "nqn.2014-08.org.nvmexpress:uuid:eb63ddbc-c01f-4435-8e0b-bbbaf22639f2" ctrlr.c: 389:spdk_nvmf_ctrlr_connect: *INFO*: Connect Admin Queue for controller ID 0xffff ctrlr.c: 207:spdk_nvmf_ctrlr_create: *INFO*: cap 0x20010103ff ctrlr.c: 208:spdk_nvmf_ctrlr_create: *INFO*: vs 0x10300 ctrlr.c: 209:spdk_nvmf_ctrlr_create: *INFO*: cc 0x0 ctrlr.c: 210:spdk_nvmf_ctrlr_create: *INFO*: csts 0x0 ctrlr.c: 104:ctrlr_add_qpair_and_update_rsp: *INFO*: connect capsule response: cntlid = 0x0001 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=0 cdw0=0x00000001 rsvd1=0 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x04 cid 26 ctrlr.c: 557:spdk_nvmf_property_get: *INFO*: size 1, offset 0x0 ctrlr.c: 573:spdk_nvmf_property_get: *INFO*: name: cap ctrlr.c: 583:spdk_nvmf_property_get: *INFO*: response value: 0x20010103ff request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x010103ff rsvd1=32 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x00 cid 26 ctrlr.c: 598:spdk_nvmf_property_set: *INFO*: size 0, offset 0x14, value 0x460001 ctrlr.c: 608:spdk_nvmf_property_set: *INFO*: name: cc ctrlr.c: 438:nvmf_prop_set_cc: *INFO*: cur CC: 0x00000000 ctrlr.c: 439:nvmf_prop_set_cc: *INFO*: new CC: 0x00460001 ctrlr.c: 449:nvmf_prop_set_cc: *INFO*: Property Set CC Enable! ctrlr.c: 480:nvmf_prop_set_cc: *INFO*: Prop Set IOSQES = 6 (64 bytes) ctrlr.c: 487:nvmf_prop_set_cc: *INFO*: Prop Set IOCQES = 4 (16 bytes) request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x00000000 rsvd1=0 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x04 cid 26 ctrlr.c: 557:spdk_nvmf_property_get: *INFO*: size 0, offset 0x1c ctrlr.c: 573:spdk_nvmf_property_get: *INFO*: name: csts ctrlr.c: 583:spdk_nvmf_property_get: *INFO*: response value: 0x1 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x00000001 rsvd1=0 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x04 cid 26 ctrlr.c: 557:spdk_nvmf_property_get: *INFO*: size 0, offset 0x8 ctrlr.c: 573:spdk_nvmf_property_get: *INFO*: name: vs ctrlr.c: 583:spdk_nvmf_property_get: *INFO*: response value: 0x10300 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x00010300 rsvd1=0 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x04 cid 26 ctrlr.c: 557:spdk_nvmf_property_get: *INFO*: size 1, offset 0x0 ctrlr.c: 573:spdk_nvmf_property_get: *INFO*: name: cap ctrlr.c: 583:spdk_nvmf_property_get: *INFO*: response value: 0x20010103ff request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x010103ff rsvd1=32 status=0x0000 request.c: 121:nvmf_trace_command: *INFO*: Admin cmd: opc 0x06 fuse 0 cid 26 nsid 0 cdw10 0x00000001 request.c: 136:nvmf_trace_command: *INFO*: SGL: Keyed (Inv): addr 0xc026a2000 key 0x10112 len 0x1000 ctrlr.c:1172:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ctrlr data: maxcmd 0x400 ctrlr.c:1173:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: sgls data: 0x100005 ctrlr_bdev.c: 73:spdk_nvmf_subsystem_bdev_io_type_supported: *INFO*: All devices in Subsystem nqn.2016-06.io.spdk:cnode1 support io_type 3 ctrlr_bdev.c: 73:spdk_nvmf_subsystem_bdev_io_type_supported: *INFO*: All devices in Subsystem nqn.2016-06.io.spdk:cnode1 support io_type 9 ctrlr.c:1215:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ext ctrlr data: ioccsz 0x104 ctrlr.c:1217:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ext ctrlr data: iorcsz 0x1 ctrlr.c:1219:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ext ctrlr data: icdoff 0x0 ctrlr.c:1221:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ext ctrlr data: ctrattr 0x0 ctrlr.c:1223:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ext ctrlr data: msdbd 0x1 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x00000000 rsvd1=0 status=0x0000 request.c: 121:nvmf_trace_command: *INFO*: Admin cmd: opc 0x02 fuse 0 cid 26 nsid 4294967295 cdw10 0x03ff0005 request.c: 136:nvmf_trace_command: *INFO*: SGL: Keyed (Inv): addr 0xc026a3000 key 0x10113 len 0x1000 ctrlr.c:1082:spdk_nvmf_ctrlr_get_log_page: *INFO*: Get log page: LID=0x05 offset=0x0 len=0x1000 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x00000000 rsvd1=0 status=0x0000 ~・~一部省略~・~ ctrlr.c:1548:spdk_nvmf_ctrlr_keep_alive: *INFO*: Keep Alive request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=0 cdw0=0x00000000 rsvd1=0 status=0x0000 request.c: 121:nvmf_trace_command: *INFO*: Admin cmd: opc 0x18 fuse 0 cid 0 nsid 0 cdw10 0x00000000 ctrlr.c:1548:spdk_nvmf_ctrlr_keep_alive: *INFO*: Keep Alive request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=0 cdw0=0x00000000 rsvd1=0 status=0x0000 request.c: 121:nvmf_trace_command: *INFO*: Admin cmd: o
List確認Initiator側
# nvme list
Node SN Model Namespace Usage Format FW Rev
---------------- -------------------- ---------------------------------------- --------- -------------------------- ---------------- --------
/dev/nvme0n1 SPDK00000000000001 SPDK bdev Controller 1 250.06 GB / 250.06 GB 512 B + 0 B 18.10
List確認Target側
request.c: 121:nvmf_trace_command: *INFO*: Admin cmd: opc 0x06 fuse 0 cid 18 nsid 0 cdw10 0x00000001 request.c: 136:nvmf_trace_command: *INFO*: SGL: Keyed (Inv): addr 0xbe37f8000 key 0x10120 len 0x1000 ctrlr.c:1172:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ctrlr data: maxcmd 0x400 ctrlr.c:1173:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: sgls data: 0x100005 ctrlr_bdev.c: 73:spdk_nvmf_subsystem_bdev_io_type_supported: *INFO*: All devices in Subsystem nqn.2016-06.io.spdk:cnode1 support io_type 3 ctrlr_bdev.c: 73:spdk_nvmf_subsystem_bdev_io_type_supported: *INFO*: All devices in Subsystem nqn.2016-06.io.spdk:cnode1 support io_type 9 ctrlr.c:1215:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ext ctrlr data: ioccsz 0x104 ctrlr.c:1217:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ext ctrlr data: iorcsz 0x1 ctrlr.c:1219:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ext ctrlr data: icdoff 0x0 ctrlr.c:1221:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ext ctrlr data: ctrattr 0x0 ctrlr.c:1223:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ext ctrlr data: msdbd 0x1 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=18 cdw0=0x00000000 rsvd1=0 status=0x0000 request.c: 121:nvmf_trace_command: *INFO*: Admin cmd: opc 0x06 fuse 0 cid 18 nsid 1 cdw10 0x00000000 request.c: 136:nvmf_trace_command: *INFO*: SGL: Keyed (Inv): addr 0xbe37f8000 key 0x10121 len 0x1000 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=18 cdw0=0x00000000 rsvd1=0 status=0x0000
bdevとして認識されていることを確認*5
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 136.8G 0 disk
tqsda1 8:1 0 1G 0 part /boot
mqsda2 8:2 0 135.7G 0 part
tqcentos-root 253:0 0 131.7G 0 lvm /
mqcentos-swap 253:1 0 4G 0 lvm [SWAP]
sr0 11:0 1 1024M 0 rom
nvme0n1 259:0 0 232.9G 0 disk
Disconnect実施Initiator側
# nvme disconnect -n "nqn.2016-06.io.spdk:cnode1" NQN:nqn.2016-06.io.spdk:cnode1 disconnected 1 controller(s)
Disconnect実施Target側
request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x00 cid 18 ctrlr.c: 598:spdk_nvmf_property_set: *INFO*: size 0, offset 0x14, value 0x464001 ctrlr.c: 608:spdk_nvmf_property_set: *INFO*: name: cc ctrlr.c: 438:nvmf_prop_set_cc: *INFO*: cur CC: 0x00460001 ctrlr.c: 439:nvmf_prop_set_cc: *INFO*: new CC: 0x00464001 ctrlr.c: 463:nvmf_prop_set_cc: *INFO*: Property Set CC Shutdown 01b! request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=18 cdw0=0x00000000 rsvd1=0 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x04 cid 18 ctrlr.c: 557:spdk_nvmf_property_get: *INFO*: size 0, offset 0x1c ctrlr.c: 573:spdk_nvmf_property_get: *INFO*: name: csts ctrlr.c: 583:spdk_nvmf_property_get: *INFO*: response value: 0x8 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=18 cdw0=0x00000008 rsvd1=0 status=0x0000
上記InitiatorとTargetのやり取りをPcapしたファイルを以下にアップしておきます。
roce02.pcapng
あとは、iSCSI Targetと同様に動作しますので、Initiator側でmkfsするなり、fioで速度測定するなりご自由にどうぞ。
以上です。
7.補足その1:ReactorMaskについて
ReactorMaskとは、PMD(Poll Mode Driver)で専有させるCPUコアを明示的に指定するためのものです。NVMe-oF targetの場合、SSDが管理されているNUMA socket*6と同じNUMA socket上のCPUコアを明示的に指定することでパフォーマンスが向上します。このため、ReactorMaskでPMDが専有するCPUコアを明示的に指定することが重要となってきます。
それでは、CPUコアを明示的に指定する方法を具体例を交えて解説します。
lscpuの結果
# lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 8 On-line CPU(s) list: 0-7 Thread(s) per core: 1 Core(s) per socket: 4 Socket(s): 2 NUMA node(s): 2 Vendor ID: GenuineIntel CPU family: 6 Model: 45 Model name: Intel(R) Xeon(R) CPU E5-2407 0 @ 2.20GHz Stepping: 7 CPU MHz: 1200.000 CPU max MHz: 2200.0000 CPU min MHz: 1200.0000 BogoMIPS: 4389.14 Virtualization: VT-x L1d cache: 32K L1i cache: 32K L2 cache: 256K L3 cache: 10240K NUMA node0 CPU(s): 0-3 NUMA node1 CPU(s): 4-7 Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx lahf_lm epb tpr_shadow vnmi flexpriority ept vpid xsaveopt ibpb ibrs stibp dtherm arat pln pts spec_ctrl intel_stibp
今回使用したサーバ(DL360e)の場合、2ソケット、Hyperスレッド無し、4コアなので、トータル8コアあります。
さらに、NUMA socketの割り当ては以下のようになっています。
NUMA socket(node)0:0-3コア
NUMA socket(node)1:4-7コア
また、nvmf_tgtの実行結果から、SSDがNUMA socket(node)0で動作していることがわかります。
# app/nvmf_tgt/nvmf_tgt -c app/nvmf_tgt/nvmf.conf Starting SPDK v18.07-pre / DPDK 18.02.0 initialization... [ DPDK EAL parameters: nvmf -c 0x0E --file-prefix=spdk_pid17014 ] EAL: Detected 8 lcore(s) EAL: Multi-process socket /var/run/.spdk_pid17014_unix EAL: Probing VFIO support... app.c: 530:spdk_app_start: *NOTICE*: Total cores available: 3 reactor.c: 718:spdk_reactors_init: *NOTICE*: Occupied cpu socket mask is 0x1 reactor.c: 492:_spdk_reactor_run: *NOTICE*: Reactor started on core 2 on socket 0 reactor.c: 492:_spdk_reactor_run: *NOTICE*: Reactor started on core 3 on socket 0 reactor.c: 492:_spdk_reactor_run: *NOTICE*: Reactor started on core 1 on socket 0 EAL: PCI device 0000:03:00.0 on NUMA socket 0 EAL: probe driver: 144d:a808 spdk_nvme
上記結果より、PMDに専有させたいコアは「NUMA socket(node)0:0-3」となります。
このときのReactorMaskの指定方法は、
[Global] ReactorMask 0x0F
となります。
CPUコアの並び順は以下のようになっています。
7654 3210
lscpuの結果より、
7654がNUMA socket(node)1
3210がNUMA socket(node)0
となります。
ReactorMaskのうち、0x0Fを2進数に変換すると、以下のようになります。
16進数 0x0F 2進数 0000 1111
CPUコアの並びと2進数に変換したReactorMaskを合わせると
7654 3210 0000 1111
となり、ReactorMaskのうち「1」が立っているCPUがPMDに専有されます。
考え方としては、SubnetMaskと同様ですね。
今回の場合、あまり意味はないですが、例えば、奇数番号のコアだけを使用したい場合は、
CPUコア 7654 3210 2進数 1010 1010 16進数 0xAA
となります。
8.補足その2:fioの実施結果
fioを実施してみました。
結果、10Gbpsをフルに使用したパフォーマンスを出してくれました。
但し、Samsung SSD 250GB 970 EVOのシーケンシャルリードの公称値が3400MBps(27.2Gbps)なので、Mellanox製NICがボトルネックとなっています。
これについては、40GNIC or 100GNICで試せたらいいなと考えています。
fio設定ファイル
# cat seqread4.fio [global] filename=/dev/nvme0n1 group_reporting=1 direct=1 ioengine=libaio [seqread4] readwrite=read blocksize=32m size=10g numjobs=2 loops=2
fio実行結果
# fio seqread4.fio seqread4: (g=0): rw=read, bs=(R) 32.0MiB-32.0MiB, (W) 32.0MiB-32.0MiB, (T) 32.0MiB-32.0MiB, ioengine=libaio, iodepth=1 ... fio-3.1 Starting 2 processes Jobs: 2 (f=2): [R(2)][100.0%][r=1185MiB/s,w=0KiB/s][r=37,w=0 IOPS][eta 00m:00s] seqread4: (groupid=0, jobs=2): err= 0: pid=13105: Thu Aug 23 15:26:47 2018 read: IOPS=36, BW=1167MiB/s (1224MB/s)(40.0GiB/35097msec) slat (usec): min=26489, max=30909, avg=28159.67, stdev=289.25 clat (usec): min=13362, max=27098, avg=26659.48, stdev=449.47 lat (usec): min=40354, max=56431, avg=54820.49, stdev=422.94 clat percentiles (usec): | 1.00th=[25560], 5.00th=[26346], 10.00th=[26346], 20.00th=[26608], | 30.00th=[26608], 40.00th=[26608], 50.00th=[26608], 60.00th=[26608], | 70.00th=[26870], 80.00th=[26870], 90.00th=[26870], 95.00th=[26870], | 99.00th=[26870], 99.50th=[26870], 99.90th=[27132], 99.95th=[27132], | 99.99th=[27132] bw ( KiB/s): min=588646, max=656673, per=49.95%, avg=596887.99, stdev=20330.41, samples=140 iops : min= 17, max= 20, avg=18.20, stdev= 0.61, samples=140 lat (msec) : 20=0.08%, 50=99.92% cpu : usr=0.02%, sys=3.94%, ctx=21806, majf=0, minf=1107 IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued rwt: total=1280,0,0, short=0,0,0, dropped=0,0,0 latency : target=0, window=0, percentile=100.00%, depth=1 Run status group 0 (all jobs): READ: bw=1167MiB/s (1224MB/s), 1167MiB/s-1167MiB/s (1224MB/s-1224MB/s), io=40.0GiB (42.9GB), run=35097-35097msec Disk stats (read/write): nvme0n1: ios=325850/0, merge=0/0, ticks=6298513/0, in_queue=6471868, util=99.76%
1224MBps=9792Mbps
9.最後に
以下のサイトを参考にさせて頂きました。
SPDK: NVMe over Fabrics Target
Intel SPDK NVMe-oF Target Performance Tuning. Part 2: Preparing testing environment | StarWind Blog
CentOS7でelrepoリポジトリを有効化してkernel-mlを入れる - Qiita
kernelのBugにヒットした際、仕方なく4.17系でリビルドして何とかPcapに成功したのですが、リビルドの手順も合せてこのBlogに記載するのは本編からブレるため、4.18.4がリリースされるまで待ちました。ただ予想以上に早くリリースして頂いたので、コミッターの方にはとても感謝しています。
この記事によるとNVMe市場は2020年までに570億ドル(日本円で6兆円超)規模の市場になるらしいです。
blog.calsoftinc.com
なので、早めにキャッチアップ&修得しておいて損はない技術かなと思っています。
また、以前FCoEの勉強をしていたため、RoCEは前々から気になっていました。
metonymical.hatenablog.com
FCoEはあっという間に消えてしまいましたが、RoCEはNVMe-oFのうちover Fabricの部分で残りそうな予感がしています。
oEやoCEの部分では既に規格があります*7が、RoCEv2がいいかも?と思った点は、それに加えて、IP&UDPを乗せたところだと思っています。
EthernetやIPの世界では既に400Gbpsのスイッチも市場に出始めていますし、100G×32ポート程度のスイッチであれば100万円ちょい&100GBase-SR4のQSFP28でも1万円ちょいで購入できます。
このような状況を踏まえれば、EthernetやIPをFabricとして使用したとしても、高性能なNVMe対応ストレージに対して、充分な性能を担保できるのでは?と考えています。また、導入コストやスケーラビリティの点を含めて考えても、IBやFCと対等に渡り合えるのではないかと考えています。
なので、例えば、IP CLOSネットワーク上でRoCEv2を動作させて、障害時の切替検証や複数InitiatorからTargetへのアクセス時における負荷分散など、といったシチュエーションにおける最適なネットワーク設計を検討していきたいと考えています。
*1:あえて、-yオプションを付けていません。万が一、4.18系Kernelで、4.18.4-1以前のバージョンだった場合、リポジトリからミラーサイトのURLを全て削除してください。4.18.1-1や4.18.3-1などの場合、uio_pci_genericのBugを踏むことになりTargetを起動できません。
*2:この後、yum swapしますので、最新までアップデートしてください。
*3:ここのパスが基点となります。
*4:GRUB_CMDLINE_LINUX=の行末に、intel_iommu=on iommu=pt pci=realloc も追記すると、uioの代わりにvfio-pciで稼働するようになりますが、HPのアドバイザリにヒットしたため、今回はuio_pci_genericで行っています。また、Kernel4.18系のうち、4.18.3-1以前のバージョンの場合、uio_pci_genericに移行できず、空欄となるBugを踏むことになります。
*5:setup.shの実行直後にlsblkを実行すると、nvmeはカーネルの制御から解放されているためlsblkでは見えなくなります。その後、Initiator側からConnectして、lsblkを実行すると、nvme0n1が見えるようになります。
*6:NUMA socketとかNUMA nodeと言ったりします。厳密には異なりますが、今回は同じ用語だと考えてください。
*7:DCBXとして、802.1Qau(Congestion Notification)、802.1Qaz(Enhanced Transmission Selection)、802.1Qbb(Priority-based Flow Control)に加えて、SPB、TRILLなどがあります。