🦘

シングルボードコンピュータにM.2 M-keyのSSDを増設してみた

2023/04/03に公開

試してみたSSDはこちら。M.2 M-key のコネクタがあるシングルボードコンピュータに増設することができます。

A-DATA エーデータ
ALEG-700-512GCS [LEGEND 700 M.2 SSD 512GB M.2 2280 NVMe(PCIe Gen3×4) Read:2000MB/s / Write:1600MB/s ヒートシンク付属]
私が購入したときは¥5,080(税込)でした。
https://www.yodobashi.com/product-detail/100000001007545482/

Jetson AGX Orin

試したときのカーネルバージョン

$ cat /proc/version 
Linux version 5.10.104-tegra (buildbrain@mobile-u64-5273-d7000) (aarch64-buildroot-linux-gnu-gcc.br_real (Buildroot 2020.08) 9.3.0, GNU ld (GNU Binutils) 2.33.1) #1 SMP PREEMPT Wed Aug 10 20:17:07 PDT 2022

USBの外付けタイプのSSDを使っています。それをhdparmコマンドで測定してみました。

$ sudo hdparm -tTv /dev/sda1 

/dev/sda1:
 multcount     =  1 (on)
 readonly      =  0 (off)
 readahead     = 256 (on)
 geometry      = 60801/255/63, sectors = 976771087, start = 2048
 Timing cached reads:   6580 MB in  2.00 seconds = 3292.16 MB/sec
 Timing buffered disk reads: 632 MB in  3.00 seconds = 210.38 MB/sec

同じことを新しく増設したSSDでやってみます。

$ sudo hdparm -tTv /dev/nvme0n1p1 

/dev/nvme0n1p1:
 HDIO_DRIVE_CMD(identify) failed: Inappropriate ioctl for device
 readonly      =  0 (off)
 readahead     = 256 (on)
 HDIO_DRIVE_CMD(identify) failed: Inappropriate ioctl for device
 geometry      = 488385/64/32, sectors = 1000213168, start = 2048
 Timing cached reads:   6820 MB in  2.00 seconds = 3412.32 MB/sec
 HDIO_DRIVE_CMD(identify) failed: Inappropriate ioctl for device
 Timing buffered disk reads:  66 MB in  3.01 seconds =  21.90 MB/sec

あれ? HDIO_DRIVE_CMD(identify) failed: Inappropriate ioctl for device という気になるメッセージが。
しかも、buffered disk readの速度がさきほどのものに比べて1/10しか出ていません。

ついでに、ボードに内蔵されているeMMCも測ってみました。

$ sudo hdparm -tTv /dev/mmcblk0p1

/dev/mmcblk0p1:
 HDIO_DRIVE_CMD(identify) failed: Invalid argument
 readonly      =  0 (off)
 readahead     = 4096 (on)
 HDIO_DRIVE_CMD(identify) failed: Invalid argument
 geometry      = 1898944/4/16, sectors = 121532416, start = 2787904
 Timing cached reads:   6760 MB in  2.00 seconds = 3381.94 MB/sec
 HDIO_DRIVE_CMD(identify) failed: Invalid argument
 Timing buffered disk reads: 584 MB in  3.01 seconds = 194.26 MB/sec

気になるHDIO_DRIVE_CMD(identify) failed: Invalid argument は出ていますが、速度的にはそこそこのものです。

hdparmは読み込みの性能しか測れないので、ddで書き込んでみました。
これはUSB外付けのSSD

$ sudo dd if=/dev/zero of=/autofs/usbssd1/temp oflag=direct bs=128k count=32k
32768+0 records in
32768+0 records out
4294967296 bytes (4.3 GB, 4.0 GiB) copied, 70.6557 s, 60.8 MB/s

今回増設したSSD

$ sudo dd if=/dev/zero of=/mnt/temp oflag=direct bs=128k count=32k
32768+0 records in
32768+0 records out
4294967296 bytes (4.3 GB, 4.0 GiB) copied, 221.922 s, 19.4 MB/s

はっきりと遅いですね。

違うボードで試してみることにしました。

VisonFive 2

測定したときのカーネルのバージョン。

$ cat /proc/version 
Linux version 5.15.0-starfive (sw_buildbot@mdcsw02) (riscv64-unknown-linux-gnu-gcc (GCC) 10.2.0, GNU ld (GNU Binutils) 2.35) #1 SMP Mon Feb 27 14:03:14 EST 2023

rootfsが載っているマイクロSDカード

$ sudo hdparm -tTv /dev/mmcblk1p1 

/dev/mmcblk1p1:
 readonly      =  0 (off)
 readahead     = 256 (on)
 geometry      = 34048/4/16, sectors = 4096, start = 4096
 Timing cached reads:   1284 MB in  2.00 seconds = 642.06 MB/sec
 Timing buffered disk reads:   2 MB in  0.19 seconds =  10.39 MB/sec

マイクロSDカードはこんなものですね。

今回増設したSSD

$ sudo hdparm -tTv /dev/nvme0n1p1 

/dev/nvme0n1p1:
 readonly      =  0 (off)
 readahead     = 256 (on)
 geometry      = 488385/64/32, sectors = 1000213168, start = 2048
 Timing cached reads:   1368 MB in  2.00 seconds = 684.06 MB/sec
 Timing buffered disk reads: 502 MB in  3.00 seconds = 167.18 MB/sec

このボードではそこそこの速度が出ています。このSSDはこちらのボードで使うようにします。
本当はランダムアクセスの性能を測りたいのですが、とりあえず今回はこれで。

以下、余談

Jetson AGX OrinはSSDを固定するネジがついていたのですが、VisonFive 2にはネジがありませんでした。しかもネジの大きさが違う。
一時的に養生テープで止めていたのですが、これを購入して固定しました。
購入価格¥260(税込)でしたが、これ単体で買っても送料無しで送ってくれました。ありがたい。

https://www.yodobashi.com/product-detail/100000001003744717/

SSD増設時のコマンドの操作

備忘録として書いておきます。

$ lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
mtdblock0    31:0    0   128K  0 disk 
mtdblock1    31:1    0     3M  0 disk 
mtdblock2    31:2    0     1M  0 disk 
mmcblk1     179:0    0    29G  0 disk 
|-mmcblk1p1 179:1    0     2M  0 part 
|-mmcblk1p2 179:2    0     4M  0 part 
|-mmcblk1p3 179:3    0   100M  0 part 
`-mmcblk1p4 179:4    0  28.9G  0 part /
nvme0n1     259:0    0 476.9G  0 disk 
$ sudo fdisk /dev/nvme0n1

nコマンドでパーティションを一つ作成する。開始、終了位置などはデフォルトでよい。

$ sudo mkfs -t ext4 /dev/nmve0n1p1

一時的なマウント。

$ sudo mount /dev/nmve0n1p1 /mnt

サイズの確認。

$ ls /mnt
lost+found
$ df /mnt
Filesystem     1K-blocks  Used Available Use% Mounted on
/dev/nvme0n1p1 491134192    28 466112452   1% /mnt

メモ。hdparmコマンド実行時のstrace結果など

Jetson AGX Orin

hdparmコマンドのバージョン

hdparm - get/set hard disk parameters - version v9.58, by Mark Lord.

straceの結果からioctlだけ抜き出す

$ sudo strace -f -o st.log hdparm -t /dev/mmcblk0p1

/dev/mmcblk0p1:
 HDIO_DRIVE_CMD(identify) failed: Invalid argument
 Timing buffered disk reads: 682 MB in  3.00 seconds = 227.33 MB/sec
$ grep ioctl st.log 
7322  ioctl(3, SG_IO, {interface_id='S', dxfer_direction=SG_DXFER_FROM_DEV, cmd_len=16, cmdp="\x85\x08\x0e\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x40\xec\x00", mx_sb_len=32, iovec_count=0, dxfer_len=512, timeout=15000, flags=0, dxferp="\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"..., status=0, masked_status=0, msg_status=0, sb_len_wr=0, sbp="", host_status=0, driver_status=0, resid=0, duration=0, info=0}) = -1 EINVAL (Invalid argument)
7322  ioctl(3, HDIO_DRIVE_CMD, 0xaaaae3e8f878) = -1 EINVAL (Invalid argument)
7322  ioctl(3, SG_IO, {interface_id='S', dxfer_direction=SG_DXFER_FROM_DEV, cmd_len=16, cmdp="\x85\x08\x0e\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x40\xa1\x00", mx_sb_len=32, iovec_count=0, dxfer_len=512, timeout=15000, flags=0, dxferp="\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"..., status=0, masked_status=0, msg_status=0, sb_len_wr=0, sbp="", host_status=0, driver_status=0, resid=0, duration=0, info=0}) = -1 EINVAL (Invalid argument)
7322  ioctl(3, HDIO_DRIVE_CMD, 0xaaaae3e8f878) = -1 EINVAL (Invalid argument)
7322  ioctl(3, BLKFLSBUF)               = 0
7322  ioctl(3, HDIO_DRIVE_CMD, 0)       = -1 EINVAL (Invalid argument)

VisionFive2

hdparmコマンドのバージョン

hdparm - get/set hard disk parameters - version v9.65, by Mark Lord.

straceの結果からioctlだけ抜き出す

$ sudo strace -f -o st.log hdparm -t /dev/nvme0n1p1 

/dev/nvme0n1p1:
 Timing buffered disk reads: 484 MB in  3.00 seconds = 161.26 MB/sec
$ grep ioctl st.log
1791  ioctl(3, SG_IO, {interface_id='S', dxfer_direction=SG_DXFER_FROM_DEV, cmd_len=16, cmdp="\x85\x08\x0e\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x40\xec\x00", mx_sb_len=32, iovec_count=0, dxfer_len=512, timeout=15000, flags=0, dxferp="\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"..., status=0, masked_status=0, msg_status=0, sb_len_wr=0, sbp="", host_status=0, driver_status=0, resid=0, duration=0, info=0}) = -1 ENOTTY (Inappropriate ioctl for device)
1791  ioctl(3, SG_IO, {interface_id='S', dxfer_direction=SG_DXFER_FROM_DEV, cmd_len=16, cmdp="\x85\x08\x0e\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x40\xa1\x00", mx_sb_len=32, iovec_count=0, dxfer_len=512, timeout=15000, flags=0, dxferp="\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"..., status=0, masked_status=0, msg_status=0, sb_len_wr=0, sbp="", host_status=0, driver_status=0, resid=0, duration=0, info=0}) = -1 ENOTTY (Inappropriate ioctl for device)
1791  ioctl(3, BLKFLSBUF)               = 0
1791  ioctl(3, HDIO_DRIVE_CMD, NULL)    = -1 ENOTTY (Inappropriate ioctl for device)

ioctl(3, HDIO_DRIVE_CMD, 0xaaaae3e8f878) を呼んでいないですね。

VisionFive2のカーネルバージョンが5.15であるのに対して、Jetson AGX Orinは5.10です。
Jetson AGX Orin でこのSSDのread/writeの速度が遅いのはカーネルのバージョンが古いために、適切なネゴシエーションができずに互換性はあるけど速度が遅い方法にフォールバックしているためのような気がします。

関連

https://zenn.dev/tetsu_koba/articles/9486a827e286ee
https://zenn.dev/tetsu_koba/articles/5cf919a31c217c

Discussion