あっきぃ日誌

鉄道ブログのような技術系ブログのようななにか

Raspberry Pi Compute Module 4でPCI Expressデバイスを動かす(NVMe SSD編)

Raspberry Pi Advent Calendar 2020の14日目です。

adventar.org

今回はCM4でNVMe SSDを動かす話。どうもNVMe SSDはドライバーコンパイルをしなくても動きそうなので、先日のrpi-updateした環境でテストをしてみます。

NVMe SSDの検証には、LenovoのM75q-2についているSSDを使おうと着弾前から企んでいたのですが、いざ到着して開けてみたらまさかの聞いたこともない謎SSDが実装されており、一抹の不安を感じます。写真はM75q-2の記事からの再掲。M75q-1のときは(128GBだからかもですけど)KIOXIAだったのに。Union Memory完全に知らん子ですわ……。

f:id:Akkiesoft:20201212224733j:plain

気を取り直してCM4に接続していきます。変換アダプターはこないだ自宅サーバーのSSD移行をするときに使ったものを使いました。上の空きスロットはM.2 SATA SSDSATAネクターに出すときに使うやつです。

f:id:Akkiesoft:20201213173458j:plain

起動したらlspciを実行し……応答がないと思ったらやべー感じのメッセージが出ました。もうダメそうです。

pi@raspberrypi:~ $ lspci

Message from syslogd@raspberrypi at Dec 13 16:54:19 ...
 kernel:[   50.923847] Internal error: : 1211 [#2] SMP ARM

Message from syslogd@raspberrypi at Dec 13 16:54:19 ...
 kernel:[   50.924746] Process lspci (pid: 551, stack limit = 0x85eeec38)

Message from syslogd@raspberrypi at Dec 13 16:54:19 ...
 kernel:[   50.924769] Stack: (0xc3149dd0 to 0xc314a000)

dmesgでもダメっぽそうな感じのtraceとかが出ていたので、ダメそうです。

[    1.134519] brcm-pcie fd500000.pcie: host bridge /scb/pcie@7d500000 ranges:
[    1.134569] brcm-pcie fd500000.pcie:   No bus range found for /scb/pcie@7d500000, using [bus 00-ff]
[    1.134672] brcm-pcie fd500000.pcie:      MEM 0x0600000000..0x063fffffff -> 0x00c0000000
[    1.134781] brcm-pcie fd500000.pcie:   IB MEM 0x0000000000..0x003fffffff -> 0x0400000000
[    1.195599] brcm-pcie fd500000.pcie: link up, 5.0 GT/s PCIe x1 (SSC)
[    1.195998] brcm-pcie fd500000.pcie: PCI host bridge to bus 0000:00
[    1.196035] pci_bus 0000:00: root bus resource [bus 00-ff]
[    1.196071] pci_bus 0000:00: root bus resource [mem 0x600000000-0x63fffffff] (bus address [0xc0000000-0xffffffff])
[    1.196179] pci 0000:00:00.0: [14e4:2711] type 01 class 0x060400
[    1.196438] pci 0000:00:00.0: PME# supported from D0 D3hot
[    1.199662] PCI: bus0: Fast back to back transfers disabled
[    1.199704] pci 0000:00:00.0: bridge configuration invalid ([bus ff-ff]), reconfiguring
[    1.200000] pci 0000:01:00.0: [1cc4:17ab] type 00 class 0x010802
[    1.200097] pci 0000:01:00.0: reg 0x10: [mem 0x00000000-0x00003fff 64bit]
[    1.200495] pci 0000:01:00.0: PME# supported from D0 D3hot
[    1.200609] pci 0000:01:00.0: 4.000 Gb/s available PCIe bandwidth, limited by 5.0 GT/s PCIe x1 link at 0000:00:00.0 (capable of 31.504 Gb/s with 8.0 GT/s PCIe x4 link)
[    1.203721] PCI: bus1: Fast back to back transfers disabled
[    1.203758] pci_bus 0000:01: busn_res: [bus 01-ff] end is updated to 01
[    1.203851] pci 0000:00:00.0: BAR 8: assigned [mem 0x600000000-0x6000fffff]
[    1.203892] pci 0000:01:00.0: BAR 0: assigned [mem 0x600000000-0x600003fff 64bit]
[    1.203959] pci 0000:00:00.0: PCI bridge to [bus 01]
[    1.203999] pci 0000:00:00.0:   bridge window [mem 0x600000000-0x6000fffff]
[    1.204423] pcieport 0000:00:00.0: enabling device (0140 -> 0142)
[    1.204652] pcieport 0000:00:00.0: PME: Signaling with IRQ 62

(中略)

[    4.279373] nvme nvme0: pci function 0000:01:00.0
[    4.279465] nvme 0000:01:00.0: enabling device (0000 -> 0002)
[    5.467617] 8<--- cut here ---
[    5.467651] Unhandled fault: asynchronous external abort (0x1211) at 0x00000000
[    5.467681] pgd = (ptrval)
[    5.467701] [00000000] *pgd=80000000004003, *pmd=00000000
[    5.467746] Internal error: : 1211 [#1] SMP ARM

10GbEといいUSB3.0カードといい、変換アダプターをつかうカードがことごとくダメなので、疑心暗鬼に陥りかけましたが、先人JeffがNVMe SSDについてもレポートしていました。

The Raspberry Pi Compute Module 4 Review | Jeff Geerling

曰く、「XPG SX6000(ADATA)だと動かなくて、複数アダプターを買って確かめても変なメッセージがでてダメだった。Samsung 970 EVO Plusに変えたら認識した。早いぜヒャッホー!!」とのこと。UnionMemoryのSSDもおそらくこのパターンでは……。

Samsung 970 EVO Plusは自宅サーバーで使用中ですがサーバーは止められないので、メインPCからSamsung 950 PROを取り外すことにしました。MiniITXの自作機だからマザーボードの裏にあって外すのが面倒なんだぞ……!しかも開けたらホコリまみれでついでに大掃除が発生しました。極力配線を外さないように無理やりNVMe SSDを取り外しました。

f:id:Akkiesoft:20201213174614j:plain

というわけでUnionMemoryにはご退場いただいて、Samsung 950 PROでやっていきます。

f:id:Akkiesoft:20201213174725j:plain

CM4に接続。

f:id:Akkiesoft:20201213174917j:plain

起動したらlspciで確認。おっ!ちゃんと結果が出る!

pi@raspberrypi:~ $ lspci
00:00.0 PCI bridge: Broadcom Limited Device 2711 (rev 20)
01:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd NVMe SSD Controller (rev 01)

Jeffのレポート曰く、NVMe のドライバーを読み込み直す必要があるみたいなことが書かれていましたが、パーティションが見えているので、読み込みの必要はなさそうでした。rpi-updateでバージョンが変わっているからかもしれません。

pi@raspberrypi:~ $ cat /proc/partitions 
major minor  #blocks  name
(中略)
 179        0   60751872 mmcblk0
 179        1     262144 mmcblk0p1
 179        2   60485632 mmcblk0p2
 259        0  250059096 nvme0n1
 259        1    5242880 nvme0n1p1
 259        2  169869312 nvme0n1p2
 259        3   66463744 nvme0n1p3
 259        4    8479744 nvme0n1p4

fdiskもちゃんと見えてますね。

pi@raspberrypi:~ $ sudo fdisk -l /dev/nvme0n1
Disk /dev/nvme0n1: 238.5 GiB, 256060514304 bytes, 500118192 sectors
Disk model: Samsung SSD 950 PRO 256GB               
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: (略)

Device             Start       End   Sectors  Size Type
/dev/nvme0n1p1      2048  10487807  10485760    5G EFI System
/dev/nvme0n1p2  10487808 350226431 339738624  162G Linux filesystem
/dev/nvme0n1p3 367185920 500113407 132927488 63.4G Microsoft basic data
/dev/nvme0n1p4 350226432 367185919  16959488  8.1G Linux swap

Partition table entries are not in disk order.

このSSDにはUbuntuが入っていてLinuxパーティションがあるのでマウントもしてみました。問題なさそうです!

pi@raspberrypi:~ $ sudo mount /dev/nvme0n1p2 /mnt
pi@raspberrypi:~ $ ls /mnt
bin   cdrom  etc   lib    lib64   media  opt   root  sbin  srv       sys  usr
boot  dev    home  lib32  libx32  mnt    proc  run   snap  swap.img  tmp  var

そしてhdparm。ちょっと不穏なメッセージが出ていますが、計測はできています。CM4のPCIe性能がボトルネックになるので、NVMeとはいえ270MB/s程度しか出せませんが、Raspberry Piで270MB/s出るので、これは早いですね!

pi@raspberrypi:~ $ sudo hdparm -t /dev/nvme0n1

/dev/nvme0n1:
 HDIO_DRIVE_CMD(identify) failed: Inappropriate ioctl for device
 Timing buffered disk reads: 812 MB in  3.00 seconds = 270.36 MB/sec

まとめ

Jeffの言う通り、SamsungのNVMe SSDならCM4で認識させて使うことができました。これでどのSSDも使えなかったら(ブログのネタ的に)どうしようかと思いました。検証用にNVMe SSDがあったほうがいいなと思ったので、メルカリで適当に中古をポチポチしちゃいました。昨日仕事ついでにアキバに寄っていてNVMe SSDを物色しながら買うのをやめていたので、買っておけばよかった……!

ただし、こちらもJeffが言う通り、NVMe SSDをPCIeから直接ブートできないので、ブートに使いたいときは(たぶんVL805の)USB3.0ポートを経由する必要があります。で、USB3.0を経由するなら帯域的にSATA SSDで事足りると思われるので、NVMeほど気合をいれなくてもOKという感じになりそうです。

さて、次は今度こそ10GbE NICの話を書きたいところですが、まだ動かせていないと言うか、コンパイルがうまくできていなくて、ぐぬぬとなっています……。明日のカレンダーはtakiponeさんという方にご参加いただけそうなので、その間にがんばります!