web-dev-qa-db-ja.com

Qemu TRIMと物理SSDデバイスでの破棄

Qemu/KVMでWindows 7を実行していますが、パススルーGPUを使用して、仕事に関連するものに使用しています。私は最近、機械式ドライブで実行されるために前例のない速度が遅いことにうんざりしているので、Windows-KVMに「与える」ためにSSDをボックスに追加しました。 「パススルー」ディスクに次のqemuコマンドラインオプションを使用しています:-drive file=/dev/disk/by-id/wwn-0x5002538d4002d61f,if=none,id=drive-scsi0-0-0-0,format=raw,discard=on" \ -device virtio-scsi-pci,id=scsi0" \ -device scsi-hd,bus=scsi0.0,drive=drive-scsi0-0-0-0"

ゲストOSのTRIMコマンドが実際にはホスト上の物理ドライブにパススルーされることを期待していましたが、そうではないようです。

「discard = on」は、イメージファイルによってバックアップされたドライブにのみ影響し、実際の物理SSDでは影響しませんか?もしそうなら、ホスト上の物理デバイスに渡されるゲストOS上のデバイスへのTRIMコマンドをどのように実行できますか?ホストでイメージファイルを使用することが唯一の解決策ですか?そのディスク上にファイルシステムがあるとオーバーヘッドが発生するだけで、他には何も必要ないので、私はもっと良いものを望んでいます。

2
nohupper

研究

Qemuは_discard=unmap_と_discard=on_を同じように扱います:

block.c(773行目):} else if (!strcmp(mode, "on") || !strcmp(mode, "unmap")) {

また、ブロックレベルでゼロを書き込んだり破棄したりするために、 here で説明されているように、複数のLinux ioctlをサポートしているようです。

block/file-posix.c(行581):if (ioctl(s->fd, BLKDISCARDZEROES, &arg) == 0 && arg) {

block/file-posix.c(行1374):if (ioctl(aiocb->aio_fildes, BLKZEROOUT, range) == 0) {

block/file-posix.c(1509行目):if (ioctl(aiocb->aio_fildes, BLKDISCARD, range) == 0) {

したがって、これに基づいて、古いQemuマシンタイプまたはバグのあるQemuバージョンを使用しているのでない限り、オプション_discard=unmap,detect-zeroes=unmap_を使用してSCSIエミュレーションでパススルーをブロックすると、どちらも機能するはずです。

優れたプレゼンテーションが見つかりました こちら

プレゼンテーションから学んだ教訓:

  1. Linuxで破棄が無視されないようにするには、Qemu/KVMをrootまたはCAP_SYS_RAWIO権限を持つユーザーとして実行する必要があります。
  2. パススルーデバイスが本当にSCSIディスクである場合、実際のSCSI UNMAPコマンドとWRITE SAMEコマンドに注意を払う必要があり、パススルーにscsi-blockを使用できます。
  3. そうでない場合は、SCSIディスクをscsi-hdでエミュレートする必要があります。これにより、Qemuを介してLinuxブロックレイヤーに破棄コマンドが送信されます。

私にとって、パススルーにscsi-blockを使用すると、実際のデバイスの統計とSMART情報へのアクセスが許可され、通常のIOは正常に機能しましたが、破棄コマンドはサポートされませんでした。

私のバッキングデバイスは実際にはSATAなので、SCSI LUNではなくIDEであるため、この方法で破棄をサポートしないのはそのためだと思います。

Scsi-blockからscsi-hdに切り替えると、統計情報とSMART情報が失われますが、破棄は行われます。したがって、トレードオフになります。

個人的には、「真のパススルー」から「エミュレートされたパススルー」へのパフォーマンスの低下は、私のニーズではまったく見られませんでした。

以下は、エミュレートされたSCSIとバッキングブロックデバイスを備えたVirtio SCSIの例です。

_    -device virtio-scsi-pci,id=scsi \
    -blockdev driver=raw,node-name=disk.0,cache.direct=on,discard=unmap,file.driver=Host_device,file.aio=native,file.filename=/dev/disk/by-id/ata-Samsung_SSD_840_PRO_Series_S12PNEAD233247L \
    -device scsi-hd,drive=disk.0,bus=scsi.0
_

Qemuのドキュメントで見つからない部分は_file.driver=Host_device_セクションです。scsi-blockが機能するために必要であり、実際のブロックデバイスではなくscsi-hdに悪影響を与えていないようですHostファイルシステム上のファイル。

テスト

Linuxブロックレベルの関数呼び出しをテストするために使用したblktraceツールについては、 here で説明しています。

Blktraceプログラムとblkparseプログラムを一緒に実行して、破棄呼び出しをインターセプトできます。

_blktrace -a discard -d /dev/disk/by-id/ata-Samsung_SSD_840_PRO_Series_S12PNEAD233247L -o - | blkparse -i -_

これで、VMで_defrag /L c:_または_fstrim -v /_を実行すると、Host ..の出力からのスニペットの例のように、多くの破棄が印刷されます。

_    8,0    1      493     0.641661863  3118  Q  DS 45458024 + 728 [qemu-system-x86]
    8,0    1      494     0.641664662  3118  G  DS 45458024 + 728 [qemu-system-x86]
    8,0    1      495     0.641665920  3118  I  DS 45458024 + 728 [qemu-system-x86]
    8,0    1      496     0.641669312  3118  D  DS 45458024 + 728 [qemu-system-x86]
_

つまり、破棄が機能していることは、これで十分です。

6
Marshall Porter